diff --git a/docs/src/guides/developer.md b/docs/src/guides/developer.md index e4d8e8d9..adfa6760 100644 --- a/docs/src/guides/developer.md +++ b/docs/src/guides/developer.md @@ -42,12 +42,14 @@ And lastly, there are many other optional functions for each specific geometry. ### Conversion It is useful if others can convert any custom geometry into your geometry type, if their custom geometry supports GeoInterface as well. -This requires the following three methods, and the last one requires more code to generate `T` with `ngeom`, `getgeom` or just `coordinates` calls. +This requires the following methods, where the implementation should be defined in terms +of GeoInterface methods like `ngeom`, `getgeom`, or just `coordinates` calls. ```julia -Base.convert(::Type{T}, geom) where T<:AbstractPackageType = Base.convert(T, geomtrait(geom), geom) -Base.convert(::Type{T}, ::LineStringTrait, geom::T) = geom # fast fallthrough without conversion -Base.convert(::Type{T}, ::LineStringTrait, geom) = ... # slow custom conversion based on ngeom and getgeom +# This method will get called on GeoInterface.convert(::Type{T}, geom) +# if geomtrait(geom) == LineStringTrait() +GeoInterface.convert(::Type{CustomLineString}, ::LineStringTrait, geom) = ... +GeoInterface.convert(::Type{CustomPolygon}, ::PolygonTrait, geom) = ... ``` ## Required for Feature(Collection)s diff --git a/src/fallbacks.jl b/src/fallbacks.jl index b3c3e9ec..c90de2ed 100644 --- a/src/fallbacks.jl +++ b/src/fallbacks.jl @@ -103,14 +103,12 @@ getfeature(t::AbstractFeatureCollectionTrait, fc) = (getfeature(t, fc, i) for i # Backwards compatibility coordinates(t::AbstractPointTrait, geom) = collect(getcoord(t, geom)) coordinates(t::AbstractGeometryTrait, geom) = collect(coordinates.(getgeom(t, geom))) -function coordinates(t::AbstractFeatureTrait, feature) +function coordinates(t::AbstractFeatureTrait, feature) geom = geometry(feature) isnothing(geom) ? [] : coordinates(geom) end coordinates(t::AbstractFeatureCollectionTrait, fc) = [coordinates(f) for f in getfeature(fc)] -Base.convert(T::Type, ::AbstractGeometryTrait, geom) = error("Conversion is enabled for type $T, but not implemented. Please report this issue to the package maintainer.") - # Subtraits """ diff --git a/src/interface.jl b/src/interface.jl index bfa678c0..99242350 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -606,10 +606,10 @@ coordinates(obj) = coordinates(trait(obj), obj) """ convert(type::CustomGeom, geom) -Convert `geom` into the `CustomGeom` type if both geom as the CustomGeom package -have implemented GeoInterface. +Create a `CustomGeom` from any `geom` that implements the GeoInterface. """ convert(T, geom) = convert(T, geomtrait(geom), geom) +convert(::Type{T}, x::T) where {T} = x # no-op """ astext(geom) -> WKT diff --git a/test/test_primitives.jl b/test/test_primitives.jl index 410ee7e6..39d36779 100644 --- a/test/test_primitives.jl +++ b/test/test_primitives.jl @@ -35,8 +35,6 @@ using Test GeoInterface.geomtrait(::MyCurve) = LineStringTrait() GeoInterface.ngeom(::LineStringTrait, geom::MyCurve) = 2 GeoInterface.getgeom(::LineStringTrait, geom::MyCurve, i) = MyPoint() - Base.convert(T::Type{MyCurve}, geom::X) where {X} = Base.convert(T, geomtrait(geom), geom) - Base.convert(::Type{MyCurve}, ::LineStringTrait, geom::MyCurve) = geom GeoInterface.isgeometry(::MyPolygon) = true GeoInterface.geomtrait(::MyPolygon) = PolygonTrait() @@ -235,15 +233,9 @@ end struct XCurve end struct XPolygon end - Base.convert(T::Type{XCurve}, geom::X) where {X} = Base.convert(T, geomtrait(geom), geom) - Base.convert(::Type{XCurve}, ::LineStringTrait, geom::XCurve) = geom # fast fallthrough - Base.convert(::Type{XCurve}, ::LineStringTrait, geom) = geom - geom = MyCurve() - @test !isnothing(convert(MyCurve, geom)) - - Base.convert(T::Type{XPolygon}, geom::X) where {X} = Base.convert(T, geomtrait(geom), geom) - @test_throws Exception convert(MyPolygon, geom) + @test GeoInterface.convert(MyCurve, geom) === geom + @test_throws Exception GeoInterface.convert(MyPolygon, geom) end @testset "Operations" begin