From f4b14d6b170e1c87dcb35c5f2500069640c45432 Mon Sep 17 00:00:00 2001 From: Anshul Singhvi Date: Fri, 25 Oct 2024 11:06:44 -0700 Subject: [PATCH 1/5] Create SortTileRecursiveTreeAbstractTreesExt.jl --- ext/SortTileRecursiveTreeAbstractTreesExt.jl | 42 ++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 ext/SortTileRecursiveTreeAbstractTreesExt.jl diff --git a/ext/SortTileRecursiveTreeAbstractTreesExt.jl b/ext/SortTileRecursiveTreeAbstractTreesExt.jl new file mode 100644 index 0000000..28ed1cc --- /dev/null +++ b/ext/SortTileRecursiveTreeAbstractTreesExt.jl @@ -0,0 +1,42 @@ +module SortTileRecurrsiveTreeAbstractTreesExt + +using AbstractTrees +using SortTileRecursiveTree +using SortTileRecursiveTree.Extents +using SortTileRecursiveTree.GI + +import SortTileRecursiveTree: STRtree, STRNode, STRLeafNode + +AbstractTrees.children(tree::STRtree) = AbstractTrees.children(tree.rootnode) +AbstractTrees.parent(tree::STRtree) = nothing + +AbstractTrees.nodevalue(tree::STRtree) = AbstractTrees.nodevalue(tree.rootnode) + +# Implement the interface for general STRNodes + +AbstractTrees.children(node::STRNode) = node.children +AbstractTrees.nodevalue(node::STRNode) = node.extent + +# Implement the interface for STRLeafNodes +AbstractTrees.children(node::STRLeafNode) = STRLeafNode[] +AbstractTrees.nodevalue(node::STRLeafNode) = reduce(Extents.union, node.extents) + + +# Define the traits from AbstractTrees +AbstractTrees.ParentLinks(::Type{<: STRtree}) = AbstractTrees.ImplicitParents() +AbstractTrees.ParentLinks(::Type{<: STRNode}) = AbstractTrees.ImplicitParents() +AbstractTrees.ParentLinks(::Type{<: STRLeafNode}) = AbstractTrees.ImplicitParents() + +AbstractTrees.SiblingLinks(::Type{<: STRtree}) = AbstractTrees.ImplicitSiblings() +AbstractTrees.SiblingLinks(::Type{<: STRNode}) = AbstractTrees.ImplicitSiblings() +AbstractTrees.SiblingLinks(::Type{<: STRLeafNode}) = AbstractTrees.ImplicitSiblings() + +AbstractTrees.ChildIndexing(::Type{<: STRtree}) = AbstractTrees.IndexedChildren() +AbstractTrees.ChildIndexing(::Type{<: STRNode}) = AbstractTrees.IndexedChildren() +# We don't define this trait for STRLeafNodes, because they have no children. + +# Type stability fixes + +AbstractTrees.NodeType(::Type{<:Union{STRNode, STRLeafNode, STRtree}}) = NodeTypeUnknown() + +end From 67b36b2ca1c57c3b71fe62e83685a70d07b18d9f Mon Sep 17 00:00:00 2001 From: Anshul Singhvi Date: Mon, 4 Nov 2024 14:31:23 -0800 Subject: [PATCH 2/5] Move the AbstractTrees implementation to Please ask your administrator. --- Project.toml | 4 +++- src/SortTileRecursiveTree.jl | 4 ++++ .../abstracttrees.jl | 13 +------------ 3 files changed, 8 insertions(+), 13 deletions(-) rename ext/SortTileRecursiveTreeAbstractTreesExt.jl => src/abstracttrees.jl (84%) diff --git a/Project.toml b/Project.toml index 477a770..28d9553 100644 --- a/Project.toml +++ b/Project.toml @@ -4,13 +4,15 @@ authors = ["Max Freudenberg and contr version = "0.1.1" [deps] +AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" Extents = "411431e0-e8b7-467b-b5e0-f676ba4f2910" GeoInterface = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" [compat] -julia = "1.10" +AbstractTrees = "0.4.5" Extents = "0.1.0" GeoInterface = "1" +julia = "1.6" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/src/SortTileRecursiveTree.jl b/src/SortTileRecursiveTree.jl index 8c8ede9..8112f75 100644 --- a/src/SortTileRecursiveTree.jl +++ b/src/SortTileRecursiveTree.jl @@ -2,6 +2,7 @@ module SortTileRecursiveTree using Extents import GeoInterface as GI +import AbstractTrees """ @@ -156,6 +157,9 @@ function query!(query_result::Vector{Int}, node::STRLeafNode, extent::Extent) end + +include("abstracttrees.jl") + export STRtree, query end diff --git a/ext/SortTileRecursiveTreeAbstractTreesExt.jl b/src/abstracttrees.jl similarity index 84% rename from ext/SortTileRecursiveTreeAbstractTreesExt.jl rename to src/abstracttrees.jl index 28ed1cc..b8a7a63 100644 --- a/ext/SortTileRecursiveTreeAbstractTreesExt.jl +++ b/src/abstracttrees.jl @@ -1,12 +1,3 @@ -module SortTileRecurrsiveTreeAbstractTreesExt - -using AbstractTrees -using SortTileRecursiveTree -using SortTileRecursiveTree.Extents -using SortTileRecursiveTree.GI - -import SortTileRecursiveTree: STRtree, STRNode, STRLeafNode - AbstractTrees.children(tree::STRtree) = AbstractTrees.children(tree.rootnode) AbstractTrees.parent(tree::STRtree) = nothing @@ -37,6 +28,4 @@ AbstractTrees.ChildIndexing(::Type{<: STRNode}) = AbstractTrees.IndexedChildren( # Type stability fixes -AbstractTrees.NodeType(::Type{<:Union{STRNode, STRLeafNode, STRtree}}) = NodeTypeUnknown() - -end +AbstractTrees.NodeType(::Type{<:Union{STRNode, STRLeafNode, STRtree}}) = AbstractTrees.NodeTypeUnknown() From 459e54d7fc268ec7f3f050ed90d813acef1c9e8c Mon Sep 17 00:00:00 2001 From: Anshul Singhvi Date: Tue, 18 Feb 2025 13:14:19 -0500 Subject: [PATCH 3/5] Fixes for Extents API Co-authored-by: Rafael Schouten --- src/abstracttrees.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/abstracttrees.jl b/src/abstracttrees.jl index b8a7a63..f32c622 100644 --- a/src/abstracttrees.jl +++ b/src/abstracttrees.jl @@ -6,11 +6,11 @@ AbstractTrees.nodevalue(tree::STRtree) = AbstractTrees.nodevalue(tree.rootnode) # Implement the interface for general STRNodes AbstractTrees.children(node::STRNode) = node.children -AbstractTrees.nodevalue(node::STRNode) = node.extent +AbstractTrees.nodevalue(node::STRNode) = Extents.extent(node) # Implement the interface for STRLeafNodes AbstractTrees.children(node::STRLeafNode) = STRLeafNode[] -AbstractTrees.nodevalue(node::STRLeafNode) = reduce(Extents.union, node.extents) +AbstractTrees.nodevalue(node::STRLeafNode) = Extents.extent(node) # Define the traits from AbstractTrees From 92bc57fd2506a027fc7be3f4385e6cd9d7fb0358 Mon Sep 17 00:00:00 2001 From: Anshul Singhvi Date: Tue, 18 Feb 2025 13:47:54 -0500 Subject: [PATCH 4/5] Add tests for AbstractTrees interface --- src/abstracttrees.jl | 2 +- test/Project.toml | 1 + test/abstracttrees.jl | 69 +++++++++++++++++++++++++++++++++++++++++++ test/runtests.jl | 1 + 4 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 test/abstracttrees.jl diff --git a/src/abstracttrees.jl b/src/abstracttrees.jl index f32c622..68fa8f4 100644 --- a/src/abstracttrees.jl +++ b/src/abstracttrees.jl @@ -9,7 +9,7 @@ AbstractTrees.children(node::STRNode) = node.children AbstractTrees.nodevalue(node::STRNode) = Extents.extent(node) # Implement the interface for STRLeafNodes -AbstractTrees.children(node::STRLeafNode) = STRLeafNode[] +AbstractTrees.children(node::STRLeafNode) = STRLeafNode[] # no children for a leaf node AbstractTrees.nodevalue(node::STRLeafNode) = Extents.extent(node) diff --git a/test/Project.toml b/test/Project.toml index 062349f..8c80403 100644 --- a/test/Project.toml +++ b/test/Project.toml @@ -1,4 +1,5 @@ [deps] +AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" ArchGDAL = "c9ce4bd3-c3d5-55b8-8973-c0e20141b8c3" Extents = "411431e0-e8b7-467b-b5e0-f676ba4f2910" GeoInterface = "cf35fbd7-0cd7-5166-be24-54bfbe79505f" diff --git a/test/abstracttrees.jl b/test/abstracttrees.jl new file mode 100644 index 0000000..00545b6 --- /dev/null +++ b/test/abstracttrees.jl @@ -0,0 +1,69 @@ + +using Test +using AbstractTrees +using SortTileRecursiveTree +using SortTileRecursiveTree: STRtree, STRNode, STRLeafNode +using Extents +using AbstractTrees: GI + +@testset "AbstractTrees interface" begin + # Create a simple test tree structure + # Level 1: root with extent (0,0) -> (10,10) + # Level 2: two children with extents (0,0)->(5,5) and (5,5)->(10,10) + # Level 3: leaf nodes + + geom1 = GI.MultiPoint([GI.Point((0.0, 0.0)), GI.Point((2.5, 2.5))]) + geom2 = GI.MultiPoint([GI.Point((2.5, 2.5)), GI.Point((5.0, 5.0))]) + geom3 = GI.MultiPoint([GI.Point((5.0, 5.0)), GI.Point((7.5, 7.5))]) + geom4 = GI.MultiPoint([GI.Point((7.5, 7.5)), GI.Point((10.0, 10.0))]) + + tree = STRtree([geom1, geom1, geom2, geom2, geom3, geom3, geom4, geom4]; nodecapacity=2) + + @testset "Basic Tree Structure" begin + # Test children access + @test length(children(tree)) == 2 + @test length(children(first(children(tree)))) == 2 + @test length(children(last(children(tree)))) == 2 + @test all(x -> isa(x, STRLeafNode), children(first(children(tree)))) + @test all(x -> isa(x, STRLeafNode), children(last(children(tree)))) + end + + @testset "Node Values" begin + # Test that nodevalue returns proper extents + @test nodevalue(tree) isa Extent + @test nodevalue(first(children(tree))) isa Extent + @test nodevalue(first(children(last(children(tree))))) isa Extent + end + + @testset "Tree Traits" begin + # Test ParentLinks trait + @test ParentLinks(STRtree) == ImplicitParents() + @test ParentLinks(STRNode) == ImplicitParents() + @test ParentLinks(STRLeafNode) == ImplicitParents() + + # Test SiblingLinks trait + @test SiblingLinks(STRtree) == ImplicitSiblings() + @test SiblingLinks(STRNode) == ImplicitSiblings() + @test SiblingLinks(STRLeafNode) == ImplicitSiblings() + + # Test ChildIndexing trait + @test ChildIndexing(STRtree) == IndexedChildren() + @test ChildIndexing(STRNode) == IndexedChildren() + end + + @testset "Tree Traversal Iterators" begin + # Test that we can traverse the tree + nodes = collect(PreOrderDFS(tree)) + @test length(nodes) == 7 # 1 root + 2 internal nodes + 4 leaves + + leaves = collect(Leaves(tree)) + @test length(leaves) == 4 + @test all(x -> x isa STRLeafNode, leaves) + end + + @testset "Node Type Stability" begin + @test NodeType(STRtree) == NodeTypeUnknown() + @test NodeType(STRNode) == NodeTypeUnknown() + @test NodeType(STRLeafNode) == NodeTypeUnknown() + end +end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 9443def..cdad0bb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -34,4 +34,5 @@ import GeoInterface as GI @test points[query_result] == points[:,1] @test query(tree, Extent(X=(0, 0.5), Y=(0, 0.5))) == [] end + @testset "AbstractTrees interface" begin; include("abstracttrees.jl"); end end From 4a9edf8b8d6c24619144d68068e211362ea39706 Mon Sep 17 00:00:00 2001 From: Anshul Singhvi Date: Tue, 18 Feb 2025 13:50:01 -0500 Subject: [PATCH 5/5] use Geointerface directly since we have it --- test/abstracttrees.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/abstracttrees.jl b/test/abstracttrees.jl index 00545b6..e5bcedb 100644 --- a/test/abstracttrees.jl +++ b/test/abstracttrees.jl @@ -4,7 +4,7 @@ using AbstractTrees using SortTileRecursiveTree using SortTileRecursiveTree: STRtree, STRNode, STRLeafNode using Extents -using AbstractTrees: GI +import GeoInterface as GI @testset "AbstractTrees interface" begin # Create a simple test tree structure