Skip to content

Commit fb494e3

Browse files
committed
Addressed review comments. Properties can be null.
1 parent dbc0332 commit fb494e3

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
lines changed

src/geojson_types.jl

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ abstract type GeoJSONT{D,T} end
22
abstract type AbstractGeometry{D,T} <: GeoJSONT{D,T} end
33
abstract 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)
4243
end
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)
4445
Base.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
100101
Base.eltype(::Type{MultiPolygon{D,T}}) where {D,T} = Vector{Vector{NTuple{D,T}}}
101102
coordinates(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+
104111
Base.length(g::AbstractGeometry) = length(coordinates(g))
105112
Base.lastindex(g::AbstractGeometry) = length(coordinates(g))
106113
Base.size(g::AbstractGeometry) = size(coordinates(g))
107114
Base.axes(g::AbstractGeometry) = axes(coordinates(g))
108115
Base.getindex(g::AbstractGeometry, i::Int) = getindex(coordinates(g), i::Int)
109116
Base.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

113122
function 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)
163172
end
164173
Feature(; id=nothing, bbox=nothing, geometry::AbstractGeometry{D,T}, properties=NamedTuple()) where {D,T} = Feature{D,T}(id, bbox, geometry, properties)
165174

166175
id(f::Feature) = getfield(f, :id)
167176
geometry(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+
169182
coordinates(f::Feature) = coordinates(geometry(f))
170183
Base.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))")
171184
Base.:(==)(f1::Feature, f2::Feature) = id(f1) == id(f2) && bbox(f1) == bbox(f2) && geometry(f1) == geometry(f2) && properties(f1) == properties(f2)
@@ -195,7 +208,7 @@ end
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
199212
struct 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
264277
lazily parsed from the GeoJSON string. Indexing into the collection will parse the feature.
265278
This can be more efficient when interested in only a few features from a large collection,
266279
or parsing a very large collection iteratively without loading it all into memory.

test/geojson_samples.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,8 @@ h = """{
433433
"properties": {"title": "Dict 1", "bbox": [-180.0, -90.0, 180.0, 90.0]}
434434
}"""
435435

436+
null_prop_feat = """{"geometry": null, "id": 12, "properties": null, "type": "Feature"}"""
437+
436438
features = [a, b, c, d, e, f, h]
437439

438440

@@ -492,4 +494,6 @@ geometries_2d = [multi, bbox, bermuda_triangle, geom_collection, point_int]
492494
geometries_3d = [bbox_z]
493495
geometries = vcat(geometries_2d, geometries_3d)
494496

497+
include("regression.jl")
498+
495499
end # module

test/runtests.jl

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,17 @@ include("geojson_samples.jl")
304304
@test collect(coords) isa Vector{Float32}
305305
end
306306

307+
@testset "equality" begin
308+
p = GeoJSON.read(Samples.point_int)
309+
@test p == p
310+
@test GeoJSON.Point(coordinates=(1, 2)) != GeoJSON.Point(coordinates=(2, 3))
311+
@test GeoJSON.LineString(coordinates=[(1, 2)]) != GeoJSON.MultiPoint(coordinates=[(1, 2)])
312+
end
313+
314+
@testset "regression" begin
315+
GeoJSON.read(Samples.null_prop_feat)
316+
end
317+
307318
Aqua.test_all(GeoJSON)
308319

309320
end # testset "GeoJSON"

0 commit comments

Comments
 (0)