@@ -4,6 +4,9 @@ import GeoInterface as GI
44import Extents
55
66using .. SpatialTreeInterface
7+
8+ import .. GeometryOps as GO # TODO : only needed for NaturallyIndexedRing, remove when that is removed.
9+
710export NaturalTree, NaturallyIndexedRing, prepare_naturally
811
912"""
@@ -35,33 +38,37 @@ struct NaturalIndex{E <: Extents.Extent}
3538 levels:: Vector{NaturalLevel{E}}
3639end
3740
38- GI. extent (idx:: NaturalIndex ) = idx. extent
3941Extents. extent (idx:: NaturalIndex ) = idx. extent
4042
4143function Base. show (io:: IO , :: MIME"text/plain" , idx:: NaturalIndex )
4244 println (io, " NaturalIndex with $(length (idx. levels)) levels and $(idx. nodecapacity) children per node" )
4345 println (io, " extent: $(idx. extent) " )
4446end
45-
4647function Base. show (io:: IO , idx:: NaturalIndex )
4748 println (io, " NaturalIndex($(length (idx. levels)) levels, $(idx. extent) )" )
4849end
4950
5051function NaturalIndex (geoms; nodecapacity = 32 )
52+ # Get the extent type initially (coord order, coord type, etc.)
53+ # so that the construction is type stable.
5154 e1 = GI. extent (first (geoms))
5255 E = typeof (e1)
5356 return NaturalIndex {E} (geoms; nodecapacity = nodecapacity)
5457end
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!
5860 return NaturalIndex {E} (last_level_extents; nodecapacity = nodecapacity)
5961end
6062
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)
6269 return NaturalIndex {E} (last_level_extents; nodecapacity = nodecapacity)
6370end
64-
71+ # This is the main constructor that performs inflation.
6572function NaturalIndex {E} (last_level_extents:: Vector{E} ; nodecapacity = 32 ) where E <: Extents.Extent
6673 ngeoms = length (last_level_extents)
6774 last_level = NaturalLevel (last_level_extents)
@@ -70,11 +77,11 @@ function NaturalIndex{E}(last_level_extents::Vector{E}; nodecapacity = 32) where
7077
7178 levels = Vector {NaturalLevel{E}} (undef, nlevels)
7279 levels[end ] = last_level
73-
80+ # Iterate backwards, from bottom to top level,
81+ # and build up the level extent vectors.
7482 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
7684 nrects = _number_of_keys (nodecapacity, nlevels - (level_index), ngeoms)
77- # @show level_index nrects
7885 extents = [
7986 begin
8087 start = (rect_index - 1 ) * nodecapacity + 1
@@ -185,6 +192,15 @@ SpatialTreeInterface.getchild(node::NaturalIndex, i) = SpatialTreeInterface.getc
185192
186193SpatialTreeInterface. child_indices_extents (node:: NaturalIndex ) = (i_ext for i_ext in enumerate (node. levels[1 ]. extents))
187194
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+ """
188204struct NaturallyIndexedRing
189205 points:: Vector{Tuple{Float64, Float64}}
190206 index:: NaturalIndex {Extents. Extent{(:X , :Y ), NTuple{2 , NTuple{2 , Float64}}}}
@@ -194,7 +210,6 @@ function NaturallyIndexedRing(points::Vector{Tuple{Float64, Float64}}; nodecapac
194210 index = NaturalIndex (GO. edge_extents (GI. LinearRing (points)); nodecapacity)
195211 return NaturallyIndexedRing (points, index)
196212end
197-
198213NaturallyIndexedRing (ring:: NaturallyIndexedRing ) = ring
199214
200215function GI. convert (:: Type{NaturallyIndexedRing} , :: GI.LinearRingTrait , geom)
@@ -203,24 +218,19 @@ function GI.convert(::Type{NaturallyIndexedRing}, ::GI.LinearRingTrait, geom)
203218end
204219
205220Base. show (io:: IO , :: MIME"text/plain" , ring:: NaturallyIndexedRing ) = Base. show (io, ring)
206-
207221Base. show (io:: IO , ring:: NaturallyIndexedRing ) = print (io, " NaturallyIndexedRing($(length (ring. points)) points) with index $(sprint (show, ring. index)) " )
208222
209223GI. ncoord (:: GI.LinearRingTrait , ring:: NaturallyIndexedRing ) = 2
210224GI. is3d (:: GI.LinearRingTrait , ring:: NaturallyIndexedRing ) = false
211225GI. ismeasured (:: GI.LinearRingTrait , ring:: NaturallyIndexedRing ) = false
212226
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-
217227GI. ngeom (:: GI.LinearRingTrait , ring:: NaturallyIndexedRing ) = length (ring. points)
218228GI. getgeom (:: GI.LinearRingTrait , ring:: NaturallyIndexedRing ) = ring. points
219229GI. getgeom (:: GI.LinearRingTrait , ring:: NaturallyIndexedRing , i:: Int ) = ring. points[i]
220230
221231Extents. extent (ring:: NaturallyIndexedRing ) = ring. index. extent
222232
223- GI. isgeometry (:: NaturallyIndexedRing ) = true
233+ GI. isgeometry (:: Type{<: NaturallyIndexedRing} ) = true
224234GI. geomtrait (:: NaturallyIndexedRing ) = GI. LinearRingTrait ()
225235
226236function prepare_naturally (geom)
0 commit comments