@@ -2,6 +2,7 @@ abstract type GeoJSONT{D,T} end
22abstract type AbstractGeometry{D,T} <: GeoJSONT{D,T} end
33abstract type AbstractFeatureCollection{D,T} <: GeoJSONT{D,T} end
44
5+ const Dims = (2 , 3 , 4 )
56"""
67 CRS(type::String, properties::Dict{String,Any})
78
@@ -40,7 +41,7 @@ struct LineString{D,T} <: AbstractGeometry{D,T}
4041 LineString {D,T} (bbox, coordinates) where {D,T} = new {D,T} (bbox, coordinates)
4142 LineString {D,T} (; bbox= nothing , coordinates= nothing ) where {D,T} = LineString {D,T} (bbox, coordinates)
4243end
43- LineString (; bbox= nothing , coordinates:: Vector{NTuple{2,T}} ) where {T} = LineString {2,T} (D, T, bbox, coordinates)
44+ LineString (; bbox= nothing , coordinates:: Vector{NTuple{2,T}} ) where {T} = LineString {2,T} (bbox, coordinates)
4445Base. eltype (:: Type{LineString{D,T}} ) where {D,T} = NTuple{D,T}
4546
4647"""
@@ -100,15 +101,23 @@ MultiPolygon(; bbox=nothing, coordinates::Vector{Vector{Vector{NTuple{2,T}}}}) w
100101Base. eltype (:: Type{MultiPolygon{D,T}} ) where {D,T} = Vector{Vector{NTuple{D,T}}}
101102coordinates (g:: AbstractGeometry ) = getfield (g, :coordinates )
102103
103- Base. show (io:: IO , G:: AbstractGeometry{D,T} ) where {D,T} = print (io, " $(D) D $(typestring (typeof (G))) $(get (io, :compact , false ) ? " " : " with $(length (G. coordinates)) sub-geometries" ) " )
104+ function Base. show (io:: IO , G:: AbstractGeometry{D,T} ) where {D,T}
105+ print (io, D, " D " , typestring (typeof (G)))
106+ if ! get (io, :compact , false )
107+ print (io, " with " , length (G. coordinates), " sub-geometries" )
108+ end
109+ end
110+
104111Base. length (g:: AbstractGeometry ) = length (coordinates (g))
105112Base. lastindex (g:: AbstractGeometry ) = length (coordinates (g))
106113Base. size (g:: AbstractGeometry ) = size (coordinates (g))
107114Base. axes (g:: AbstractGeometry ) = axes (coordinates (g))
108115Base. getindex (g:: AbstractGeometry , i:: Int ) = getindex (coordinates (g), i:: Int )
109116Base. IndexStyle (:: Type{<:AbstractGeometry} ) = Base. IndexLinear ()
110117
111- Base.:(== )(g1:: AbstractGeometry , g2:: AbstractGeometry ) = coordinates (g1) == coordinates (g2)
118+ function Base.:(== )(g1:: AbstractGeometry , g2:: AbstractGeometry )
119+ (typeof (g1) === typeof (g2)) && (coordinates (g1) == coordinates (g2))
120+ end
112121
113122function Base. iterate (g:: AbstractGeometry , state= 1 )
114123 x = iterate (coordinates (g), state)
@@ -157,15 +166,19 @@ struct Feature{D,T} <: GeoJSONT{D,T}
157166 id:: Union{Nothing,String,Int}
158167 bbox:: Union{Nothing,Vector{T}}
159168 geometry:: Union{Nothing,AbstractGeometry{D,T}}
160- properties:: NamedTuple
169+ properties:: Union{Nothing, NamedTuple}
161170 Feature {D,T} (id, bbox, geometry, properties) where {D,T} = new {D,T} (id, bbox, geometry, properties)
162171 Feature {D,T} (; id= nothing , bbox= nothing , geometry= nothing , properties= NamedTuple ()) where {D,T} = Feature {D,T} (id, bbox, geometry, properties)
163172end
164173Feature (; id= nothing , bbox= nothing , geometry:: AbstractGeometry{D,T} , properties= NamedTuple ()) where {D,T} = Feature {D,T} (id, bbox, geometry, properties)
165174
166175id (f:: Feature ) = getfield (f, :id )
167176geometry (f:: Feature ) = getfield (f, :geometry )
168- properties (f:: Feature ) = getfield (f, :properties )
177+ function properties (f:: Feature )
178+ props = getfield (f, :properties )
179+ return isnothing (props) ? (;) : props
180+ end
181+
169182coordinates (f:: Feature ) = coordinates (geometry (f))
170183Base. show (io:: IO , x:: Feature{D,T} ) where {D,T} = print (io, " Feature with $(D) D $(typestring (typeof (geometry (x)))) geometry and $(length (properties (x))+ 1 ) properties: $(propertynames (x)) " )
171184Base.:(== )(f1:: Feature , f2:: Feature ) = id (f1) == id (f2) && bbox (f1) == bbox (f2) && geometry (f1) == geometry (f2) && properties (f1) == properties (f2)
195208
196209
197210# This is a non-public type used to lazily construct a Feature from a JSON3.RawValue
198- # It can be written again as String, which can also be used to parsed to a Feature
211+ # It can be written again as String, which can also be used to parse to a Feature
199212struct LazyFeature{D,T} <: GeoJSONT{D,T}
200213 bytes:: Any
201214 pos:: Int
@@ -260,7 +273,7 @@ bbox(x::GeoJSONT) = getfield(x, :bbox)
260273"""
261274 LazyFeatureCollection{D,T}(bbox::Union{Nothing,Vector{T}}, features::Vector{LazyFeature{D,T}}, crs::Union{Nothing,String})
262275
263- A FeatureCollection with `D` dimensional geometry in its features, but it's features are
276+ A FeatureCollection with `D` dimensional geometry in its features, but its features are
264277lazily parsed from the GeoJSON string. Indexing into the collection will parse the feature.
265278This can be more efficient when interested in only a few features from a large collection,
266279or parsing a very large collection iteratively without loading it all into memory.
0 commit comments