Skip to content

Commit

Permalink
Fix coord order and performance of write (#64)
Browse files Browse the repository at this point in the history
* write with NTuple not vector

* test named tuple order

* fix change to extent

* bugfix map write
  • Loading branch information
rafaqz authored Apr 22, 2023
1 parent 2f7fe9d commit 363a496
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 13 deletions.
43 changes: 30 additions & 13 deletions src/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,26 +61,43 @@ function _lower(obj)
)
return _add_bbox(GI.extent(obj), base)
elseif GI.isgeometry(obj)
_lower(GI.geomtrait(obj), obj)
if GI.is3d(obj)
_lower(GI.geomtrait(obj), Val{true}(), obj)
else
_lower(GI.geomtrait(obj), Val{false}(), obj)
end
else
# null geometry
nothing
end
end
_lower(::GI.AbstractPointTrait, obj) = (type="Point", coordinates=GI.coordinates(obj))
_lower(::GI.AbstractLineStringTrait, obj) =
(type="LineString", coordinates=GI.coordinates(obj))
_lower(::GI.AbstractPolygonTrait, obj) =
(type="Polygon", coordinates=GI.coordinates(obj))
_lower(::GI.AbstractMultiPointTrait, obj) =
(type="MultiPoint", coordinates=GI.coordinates(obj))
_lower(::GI.AbstractMultiLineStringTrait, obj) =
(type="Polygon", coordinates=GI.coordinates(obj))
_lower(::GI.AbstractMultiPolygonTrait, obj) =
(type="MultiPolygon", coordinates=collect(GI.coordinates(obj)))
_lower(::GI.AbstractGeometryCollectionTrait, obj) =
_lower(t::GI.AbstractPointTrait, d, obj) =
(type="Point", coordinates=_to_vector_ntuple(t, d, obj))
_lower(t::GI.AbstractLineStringTrait, d, obj) =
(type="LineString", coordinates=_to_vector_ntuple(t, d, obj))
_lower(t::GI.AbstractPolygonTrait, d, obj) =
(type="Polygon", coordinates=_to_vector_ntuple(t, d, obj))
_lower(t::GI.AbstractMultiPointTrait, d, obj) =
(type="MultiPoint", coordinates=_to_vector_ntuple(t, d, obj))
_lower(t::GI.AbstractMultiLineStringTrait, d, obj) =
(type="Polygon", coordinates=_to_vector_ntuple(t, d, obj))
_lower(t::GI.AbstractMultiPolygonTrait, d, obj) =
(type="MultiPolygon", coordinates=_to_vector_ntuple(t, d, obj))
_lower(t::GI.AbstractGeometryCollectionTrait, d, obj) =
(type="GeometryCollection", geometries=_lower.(GI.getgeom(obj)))

function _to_vector_ntuple(::GI.PointTrait, is3d::Val{false}, geom)
(GI.x(geom), GI.y(geom))
end
function _to_vector_ntuple(::GI.PointTrait, is3d::Val{true}, geom)
(GI.x(geom), GI.y(geom), GI.z(geom))
end
function _to_vector_ntuple(::GI.AbstractGeometryTrait, is3d, geom)
map(GI.getgeom(geom)) do child_geom
_to_vector_ntuple(GI.geomtrait(child_geom), is3d, child_geom)
end
end

_add_bbox(::Nothing, nt::NamedTuple) = nt
function _add_bbox(ext::Extents.Extent, nt::NamedTuple)
if haskey(ext, :Z)
Expand Down
17 changes: 17 additions & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,23 @@ include("geojson_samples.jl")
GeoJSON.read(Samples.null_prop_feat)
end

@testset "NamedTuple point order doesn't matter as long as it's known" begin
@test GeoJSON.write((X=1.0, Y=2.0)) ==
GeoJSON.write((Y=2.0, X=1.0)) ==
"{\"type\":\"Point\",\"coordinates\":[1.0,2.0]}"
@test GeoJSON.write((Z=3, X=1.0, Y=2.0)) ==
GeoJSON.write((Y=2.0, X=1.0, Z=3)) ==
GeoJSON.write((Y=2.0, Z=3, X=1.0)) ==
GeoJSON.write((X=1.0, Z=3, Y=2.0)) ==
"{\"type\":\"Point\",\"coordinates\":[1.0,2.0,3]}"
# M is not in the spec
@test GeoJSON.write((Z=3, X=1.0, Y=2.0, M=4)) ==
GeoJSON.write((Y=2.0, X=1.0, M=4, Z=3)) ==
GeoJSON.write((M=4, Y=2.0, Z=3, X=1.0)) ==
GeoJSON.write((X=1.0, Z=3, M=4, Y=2.0)) ==
"{\"type\":\"Point\",\"coordinates\":[1.0,2.0,3]}"
end

Aqua.test_all(GeoJSON)

end # testset "GeoJSON"

0 comments on commit 363a496

Please sign in to comment.