Skip to content

Commit bfd57aa

Browse files
committed
add a test for multilevel dual tree query
1 parent edc84d3 commit bfd57aa

File tree

2 files changed

+80
-12
lines changed

2 files changed

+80
-12
lines changed

Project.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
6767
LibGEOS = "a90b1aa1-3769-5649-ba7e-abc5a9d163eb"
6868
NaturalEarth = "436b0209-26ab-4e65-94a9-6526d86fea76"
6969
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
70+
Polylabel = "49a44318-e865-4b63-9842-695152d634c1"
7071
Proj = "c94c279d-25a6-4763-9509-64d165bea63e"
7172
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
7273
Rasters = "a3a2b9e3-a471-40c9-b274-f788e487c689"
@@ -76,4 +77,4 @@ TGGeometry = "d7e755d2-3c95-4bcf-9b3c-79ab1a78647b"
7677
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
7778

7879
[targets]
79-
test = ["ArchGDAL", "CoordinateTransformations", "DataFrames", "Distributions", "DimensionalData", "Downloads", "FlexiJoins", "GeoJSON", "Proj", "JLD2", "LibGEOS", "Random", "Rasters", "NaturalEarth", "OffsetArrays", "SafeTestsets", "Shapefile", "TGGeometry", "Test"]
80+
test = ["ArchGDAL", "CoordinateTransformations", "DataFrames", "Distributions", "DimensionalData", "Downloads", "FlexiJoins", "GeoJSON", "Proj", "JLD2", "LibGEOS", "Random", "Rasters", "NaturalEarth", "OffsetArrays", "Polylabel", "SafeTestsets", "Shapefile", "TGGeometry", "Test"]

test/utils/SpatialTreeInterface.jl

+78-11
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ using GeometryOps.SpatialTreeInterface: FlatNoTree
77
using Extents
88
using GeoInterface: GeoInterface as GI
99
using SortTileRecursiveTree: STRtree
10+
using NaturalEarth
11+
using Polylabel
1012

1113
# Generic test functions for spatial trees
1214
function test_basic_interface(TreeType)
@@ -67,7 +69,7 @@ function test_query_functionality(TreeType)
6769
end
6870

6971
function test_dual_query_functionality(TreeType)
70-
@testset "Dual query functionality" begin
72+
@testset "Dual query functionality - simple" begin
7173
# Create two trees with overlapping extents
7274
tree1 = TreeType([
7375
Extents.Extent(X=(0.0, 1.0), Y=(0.0, 1.0)),
@@ -90,6 +92,65 @@ function test_dual_query_functionality(TreeType)
9092
dual_depth_first_search((i, j) -> push!(results, (i, j)), intersects_pred, tree1, tree2)
9193
@test sort(results) == [(1,1), (2,1), (2,2)]
9294
end
95+
96+
@testset "Dual query functionality - every country's polylabel against every country" begin
97+
98+
# Note that this is a perfectly balanced tree query - we don't yet have a test for unbalanced
99+
# trees (but could easily add one, e.g. by getting polylabels of admin-1 or admin-2 regions)
100+
# from Natural Earth, or by using GADM across many countries.
101+
102+
all_countries = NaturalEarth.naturalearth("admin_0_countries", 10)
103+
all_adm0_a3 = all_countries.ADM0_A3
104+
all_geoms = all_countries.geometry
105+
# US minor outlying islands - bug in Polylabel.jl
106+
# A lot of small geoms have this issue, that there will be an error from the queue
107+
# because the cell exists in the queue already.
108+
# Not sure what to do about it, I don't want to check containment every time...
109+
deleteat!(all_adm0_a3, 205)
110+
deleteat!(all_geoms, 205)
111+
112+
geom_tree = TreeType(all_geoms)
113+
114+
polylabels = [Polylabel.polylabel(geom; rtol = 0.019) for geom in all_geoms]
115+
polylabel_tree = TreeType(polylabels)
116+
117+
found_countries = falses(length(polylabels))
118+
119+
dual_depth_first_search(Extents.intersects, geom_tree, polylabel_tree) do i, j
120+
if i == j
121+
found_countries[i] = true
122+
end
123+
end
124+
125+
@test all(found_countries)
126+
end
127+
end
128+
129+
function test_find_point_in_all_countries(TreeType)
130+
all_countries = NaturalEarth.naturalearth("admin_0_countries", 10)
131+
tree = TreeType(all_countries.geometry)
132+
133+
ber = (13.4050, 52.5200) # Berlin
134+
nyc = (-74.0060, 40.7128) # New York City
135+
sin = (103.8198, 1.3521) # Singapore
136+
137+
@testset "locate points using query" begin
138+
@testset let point = ber, name = "Berlin"
139+
# Test Berlin (should be in Germany)
140+
results = query(tree, point)
141+
@test any(i -> all_countries.ADM0_A3[i] == "DEU", results)
142+
end
143+
@testset let point = nyc, name = "New York City"
144+
# Test NYC (should be in USA)
145+
results = query(tree, point)
146+
@test any(i -> all_countries.ADM0_A3[i] == "USA", results)
147+
end
148+
@testset let point = sin, name = "Singapore"
149+
# Test Singapore
150+
results = query(tree, point)
151+
@test any(i -> all_countries.ADM0_A3[i] == "SGP", results)
152+
end
153+
end
93154
end
94155

95156
function test_geometry_support(TreeType)
@@ -119,20 +180,26 @@ end
119180

120181
# Test FlatNoTree implementation
121182
@testset "FlatNoTree" begin
122-
test_basic_interface(FlatNoTree)
123-
test_child_indices_extents(FlatNoTree)
124-
test_query_functionality(FlatNoTree)
125-
test_dual_query_functionality(FlatNoTree)
126-
test_geometry_support(FlatNoTree)
183+
@testset let TreeType = FlatNoTree
184+
test_basic_interface(TreeType)
185+
test_child_indices_extents(TreeType)
186+
test_query_functionality(TreeType)
187+
test_dual_query_functionality(TreeType)
188+
test_geometry_support(TreeType)
189+
test_find_point_in_all_countries(TreeType)
190+
end
127191
end
128192

129193
# Test STRtree implementation
130194
@testset "STRtree" begin
131-
test_basic_interface(STRtree)
132-
test_child_indices_extents(STRtree)
133-
test_query_functionality(STRtree)
134-
test_dual_query_functionality(STRtree)
135-
test_geometry_support(STRtree)
195+
@testset let TreeType = STRtree
196+
test_basic_interface(TreeType)
197+
test_child_indices_extents(TreeType)
198+
test_query_functionality(TreeType)
199+
test_dual_query_functionality(TreeType)
200+
test_geometry_support(TreeType)
201+
test_find_point_in_all_countries(TreeType)
202+
end
136203
end
137204

138205

0 commit comments

Comments
 (0)