From 5264a54aec903cef64a5a190c578e80de9a7a818 Mon Sep 17 00:00:00 2001 From: Rafael Schouten Date: Fri, 30 Dec 2022 19:30:59 +0100 Subject: [PATCH 1/2] add convert methods --- src/geointerface.jl | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/geointerface.jl b/src/geointerface.jl index dc61b45..c7539b9 100644 --- a/src/geointerface.jl +++ b/src/geointerface.jl @@ -13,8 +13,16 @@ GI.ncoord(::GI.AbstractTrait, ::AbstractGeometry{D,T}) where {D,T} = D GI.coordinates(::GI.AbstractGeometryTrait, g::AbstractGeometry) = coordinates(g) GI.coordinates(::GI.AbstractPointTrait, g::AbstractGeometry) = coordinates(g) # prevent ambiguity +GI.traittype(::Val{:GeoJSON}, ::GI.PointTrait) = Point +GI.traittype(::Val{:GeoJSON}, ::GI.LineStringTrait) = LineString +GI.traittype(::Val{:GeoJSON}, ::GI.PolygonTrait) = Polygon +GI.traittype(::Val{:GeoJSON}, ::GI.MultiLineStringTrait) = MultiLineString +GI.traittype(::Val{:GeoJSON}, ::GI.MultiPolygonTrait) = MultiPolygon +GI.traittype(::Val{:GeoJSON}, ::GI.GeometryCollectionTrait) = GeometryCollection + # we have to make use of the GI fallbacks that call geomtrait on the input GI.getcoord(::GI.PointTrait, g::Point, i::Int) = g[i] +GI.convert(::Type{<:Point}, ::GI.PointTrait, geom) = Point(; coordinates=collect(GI.getcoord(geom))) GI.ngeom(::GI.LineStringTrait, g::LineString) = length(g) GI.getgeom(::GI.LineStringTrait, g::LineString{D,T}, i::Integer) where {D,T} = Point{D,T}(nothing, g[i]) @@ -22,6 +30,8 @@ GI.getpoint(::GI.LineStringTrait, g::LineString{D,T}, i::Int) where {D,T} = Poin # TODO what to return for length 0 and 1? # TODO should this be an approximate equals for floating point? GI.isclosed(::GI.LineStringTrait, g::LineString) = first(g) == last(g) +GI.convert(::Type{<:LineString}, ::GI.LineStringTrait, geom) = + LineString(; coordinates=GI.coordinates(geom)) GI.ngeom(::GI.PolygonTrait, g::Polygon) = length(g) GI.getgeom(::GI.PolygonTrait, g::Polygon{D,T}, i::Integer) where {D,T} = LineString{D,T}(nothing, g[i]) @@ -29,32 +39,52 @@ GI.ncoord(::GI.PolygonTrait, g::Polygon) = length(first(first(g))) GI.getexterior(::GI.PolygonTrait, g::Polygon{D,T}) where {D,T} = LineString{D,T}(nothing, first(g)) GI.nhole(::GI.PolygonTrait, g::Polygon) = length(g) - 1 GI.gethole(::GI.PolygonTrait, g::Polygon{D,T}, i::Int) where {D,T} = LineString{D,T}(nothing, g[i+1]) +GI.convert(::Type{<:Polygon}, ::GI.PolygonTrait, geom) = + Polygon(; coordinates=GI.coordinates(geom)) GI.ngeom(::GI.MultiPointTrait, g::MultiPoint) = length(g) GI.getgeom(::GI.MultiPointTrait, g::MultiPoint{D,T}, i::Int) where {D,T} = Point{D,T}(nothing, g[i]) +GI.convert(::Type{<:MultiPoint}, ::GI.MultiPointTrait, geom) = + MultiPoint(; coordinates=GI.coordinates(geom)) GI.ngeom(::GI.MultiLineStringTrait, g::MultiLineString) = length(g) GI.getgeom(::GI.MultiLineStringTrait, g::MultiLineString{D,T}, i::Int) where {D,T} = LineString{D,T}(nothing, g[i]) +GI.convert(::Type{<:MultiLineString}, ::GI.MultiLineStringTrait, geom) = + MultiLineString(; coordinates=GI.coordinates(geom)) GI.ngeom(::GI.MultiPolygonTrait, g::MultiPolygon) = length(g) GI.getgeom(::GI.MultiPolygonTrait, g::MultiPolygon{D,T}, i::Int) where {D,T} = Polygon{D,T}(nothing, g[i]) +GI.convert(::Type{<:MultiPolygon}, ::GI.MultiPolygonTrait, geom) = + MultiLineString(; coordinates=GI.coordinates(geom)) GI.ngeom(::GI.GeometryCollectionTrait, g::GeometryCollection) = length(g) GI.getgeom(::GI.GeometryCollectionTrait, g::GeometryCollection, i::Int) = g[i] GI.coordinates(::GI.GeometryCollectionTrait, g::GeometryCollection) = coordinates.(geometry(g)) +function GI.convert(::Type{<:GeometryCollection}, ::GI.GeometryCollectionTrait, geom) + geometries = [GI.convert(Val{:GeoJSON}(), g) for g in GI.getgeoms(geom)] + GeometryCollection(; geometries) +end # Feature GI.isfeature(::Type{<:Feature}) = true GI.trait(::Feature) = GI.FeatureTrait() GI.geometry(f::Feature) = geometry(f) GI.properties(f::Feature) = properties(f) +function GI.convert(::Type{<:Feature}, ::GI.FeatureTrait, feature) + Feature(; + geometry=GI.convert(GeoJSON, GI.geometry(feature)), + properties=GI.properties(feature), + ) +end # FeatureCollection GI.isfeaturecollection(::Type{<:AbstractFeatureCollection}) = true GI.trait(::AbstractFeatureCollection) = GI.FeatureCollectionTrait() GI.getfeature(::GI.FeatureCollectionTrait, fc::AbstractFeatureCollection, i::Integer) = fc[i] GI.nfeature(::GI.FeatureCollectionTrait, fc::AbstractFeatureCollection) = length(fc) +GI.convert(::Type{<:FeatureCollection}, ::GI.FeatureCollectionTrait, fc) = + FeatureCollection(GI.convert(Feature, GI.features(fc))) # Any GeoJSON Object GI.extent(::GI.FeatureTrait, x::GeoJSONT{2}) = _extent2(x) From 053964ffbcb78e3a8fc5461af2a89d9640b9d970 Mon Sep 17 00:00:00 2001 From: rafaqz Date: Mon, 20 Mar 2023 12:36:09 +0000 Subject: [PATCH 2/2] use geointerface_geomtype --- src/geointerface.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/geointerface.jl b/src/geointerface.jl index c7539b9..774f24b 100644 --- a/src/geointerface.jl +++ b/src/geointerface.jl @@ -13,12 +13,12 @@ GI.ncoord(::GI.AbstractTrait, ::AbstractGeometry{D,T}) where {D,T} = D GI.coordinates(::GI.AbstractGeometryTrait, g::AbstractGeometry) = coordinates(g) GI.coordinates(::GI.AbstractPointTrait, g::AbstractGeometry) = coordinates(g) # prevent ambiguity -GI.traittype(::Val{:GeoJSON}, ::GI.PointTrait) = Point -GI.traittype(::Val{:GeoJSON}, ::GI.LineStringTrait) = LineString -GI.traittype(::Val{:GeoJSON}, ::GI.PolygonTrait) = Polygon -GI.traittype(::Val{:GeoJSON}, ::GI.MultiLineStringTrait) = MultiLineString -GI.traittype(::Val{:GeoJSON}, ::GI.MultiPolygonTrait) = MultiPolygon -GI.traittype(::Val{:GeoJSON}, ::GI.GeometryCollectionTrait) = GeometryCollection +geointerface_geomtype(::GI.PointTrait) = Point +geointerface_geomtype(::GI.LineStringTrait) = LineString +geointerface_geomtype(::GI.PolygonTrait) = Polygon +geointerface_geomtype(::GI.MultiLineStringTrait) = MultiLineString +geointerface_geomtype(::GI.MultiPolygonTrait) = MultiPolygon +geointerface_geomtype(::GI.GeometryCollectionTrait) = GeometryCollection # we have to make use of the GI fallbacks that call geomtrait on the input GI.getcoord(::GI.PointTrait, g::Point, i::Int) = g[i]