@@ -4,6 +4,9 @@ import GeoInterface as GI
4
4
import Extents
5
5
6
6
using .. SpatialTreeInterface
7
+
8
+ import .. GeometryOps as GO # TODO : only needed for NaturallyIndexedRing, remove when that is removed.
9
+
7
10
export NaturalTree, NaturallyIndexedRing, prepare_naturally
8
11
9
12
"""
@@ -35,33 +38,37 @@ struct NaturalIndex{E <: Extents.Extent}
35
38
levels:: Vector{NaturalLevel{E}}
36
39
end
37
40
38
- GI. extent (idx:: NaturalIndex ) = idx. extent
39
41
Extents. extent (idx:: NaturalIndex ) = idx. extent
40
42
41
43
function Base. show (io:: IO , :: MIME"text/plain" , idx:: NaturalIndex )
42
44
println (io, " NaturalIndex with $(length (idx. levels)) levels and $(idx. nodecapacity) children per node" )
43
45
println (io, " extent: $(idx. extent) " )
44
46
end
45
-
46
47
function Base. show (io:: IO , idx:: NaturalIndex )
47
48
println (io, " NaturalIndex($(length (idx. levels)) levels, $(idx. extent) )" )
48
49
end
49
50
50
51
function NaturalIndex (geoms; nodecapacity = 32 )
52
+ # Get the extent type initially (coord order, coord type, etc.)
53
+ # so that the construction is type stable.
51
54
e1 = GI. extent (first (geoms))
52
55
E = typeof (e1)
53
56
return NaturalIndex {E} (geoms; nodecapacity = nodecapacity)
54
57
end
55
-
56
- function NaturalIndex {E} (geoms; nodecapacity = 32 ) where E <: Extents.Extent
57
- last_level_extents = GI. extent .(geoms)
58
+ function NaturalIndex (last_level_extents:: Vector{E} ; nodecapacity = 32 ) where E <: Extents.Extent
59
+ # If we are passed a vector of extents - inflate immediately!
58
60
return NaturalIndex {E} (last_level_extents; nodecapacity = nodecapacity)
59
61
end
60
62
61
- function NaturalIndex (last_level_extents:: Vector{E} ; nodecapacity = 32 ) where E <: Extents.Extent
63
+ function NaturalIndex {E} (geoms; nodecapacity = 32 ) where E <: Extents.Extent
64
+ # If passed a vector of geometries, and we know the type of the extent,
65
+ # then simply retrieve the extents so they can serve as the "last-level"
66
+ # extents.
67
+ # Finally, call the lowest level method that performs inflation.
68
+ last_level_extents = GI. extent .(geoms)
62
69
return NaturalIndex {E} (last_level_extents; nodecapacity = nodecapacity)
63
70
end
64
-
71
+ # This is the main constructor that performs inflation.
65
72
function NaturalIndex {E} (last_level_extents:: Vector{E} ; nodecapacity = 32 ) where E <: Extents.Extent
66
73
ngeoms = length (last_level_extents)
67
74
last_level = NaturalLevel (last_level_extents)
@@ -70,11 +77,11 @@ function NaturalIndex{E}(last_level_extents::Vector{E}; nodecapacity = 32) where
70
77
71
78
levels = Vector {NaturalLevel{E}} (undef, nlevels)
72
79
levels[end ] = last_level
73
-
80
+ # Iterate backwards, from bottom to top level,
81
+ # and build up the level extent vectors.
74
82
for level_index in (nlevels- 1 ): (- 1 ): 1
75
- prev_level = levels[level_index+ 1 ] # this is always instantiated
83
+ prev_level = levels[level_index+ 1 ] # this is always instantiated, since we are iterating backwards
76
84
nrects = _number_of_keys (nodecapacity, nlevels - (level_index), ngeoms)
77
- # @show level_index nrects
78
85
extents = [
79
86
begin
80
87
start = (rect_index - 1 ) * nodecapacity + 1
@@ -185,6 +192,15 @@ SpatialTreeInterface.getchild(node::NaturalIndex, i) = SpatialTreeInterface.getc
185
192
186
193
SpatialTreeInterface. child_indices_extents (node:: NaturalIndex ) = (i_ext for i_ext in enumerate (node. levels[1 ]. extents))
187
194
195
+ """
196
+ NaturallyIndexedRing(points; nodecapacity = 32)
197
+
198
+ A linear ring that contains a natural index.
199
+
200
+ !!! warning
201
+ This will be removed in favour of prepared geometry - the idea here
202
+ is just to test what interface works best to store things in.
203
+ """
188
204
struct NaturallyIndexedRing
189
205
points:: Vector{Tuple{Float64, Float64}}
190
206
index:: NaturalIndex {Extents. Extent{(:X , :Y ), NTuple{2 , NTuple{2 , Float64}}}}
@@ -194,7 +210,6 @@ function NaturallyIndexedRing(points::Vector{Tuple{Float64, Float64}}; nodecapac
194
210
index = NaturalIndex (GO. edge_extents (GI. LinearRing (points)); nodecapacity)
195
211
return NaturallyIndexedRing (points, index)
196
212
end
197
-
198
213
NaturallyIndexedRing (ring:: NaturallyIndexedRing ) = ring
199
214
200
215
function GI. convert (:: Type{NaturallyIndexedRing} , :: GI.LinearRingTrait , geom)
@@ -203,24 +218,19 @@ function GI.convert(::Type{NaturallyIndexedRing}, ::GI.LinearRingTrait, geom)
203
218
end
204
219
205
220
Base. show (io:: IO , :: MIME"text/plain" , ring:: NaturallyIndexedRing ) = Base. show (io, ring)
206
-
207
221
Base. show (io:: IO , ring:: NaturallyIndexedRing ) = print (io, " NaturallyIndexedRing($(length (ring. points)) points) with index $(sprint (show, ring. index)) " )
208
222
209
223
GI. ncoord (:: GI.LinearRingTrait , ring:: NaturallyIndexedRing ) = 2
210
224
GI. is3d (:: GI.LinearRingTrait , ring:: NaturallyIndexedRing ) = false
211
225
GI. ismeasured (:: GI.LinearRingTrait , ring:: NaturallyIndexedRing ) = false
212
226
213
- GI. npoint (:: GI.LinearRingTrait , ring:: NaturallyIndexedRing ) = length (ring. points)
214
- GI. getpoint (:: GI.LinearRingTrait , ring:: NaturallyIndexedRing ) = ring. points[i]
215
- GI. getpoint (:: GI.LinearRingTrait , ring:: NaturallyIndexedRing , i:: Int ) = ring. points[i]
216
-
217
227
GI. ngeom (:: GI.LinearRingTrait , ring:: NaturallyIndexedRing ) = length (ring. points)
218
228
GI. getgeom (:: GI.LinearRingTrait , ring:: NaturallyIndexedRing ) = ring. points
219
229
GI. getgeom (:: GI.LinearRingTrait , ring:: NaturallyIndexedRing , i:: Int ) = ring. points[i]
220
230
221
231
Extents. extent (ring:: NaturallyIndexedRing ) = ring. index. extent
222
232
223
- GI. isgeometry (:: NaturallyIndexedRing ) = true
233
+ GI. isgeometry (:: Type{<: NaturallyIndexedRing} ) = true
224
234
GI. geomtrait (:: NaturallyIndexedRing ) = GI. LinearRingTrait ()
225
235
226
236
function prepare_naturally (geom)
0 commit comments