From 4630f13cb6df21bf6b45c27351a1e1ffacd6dee3 Mon Sep 17 00:00:00 2001 From: Martijn Visser Date: Sun, 15 May 2022 13:33:23 +0200 Subject: [PATCH 1/6] rename defaults.jl to fallbacks.jl This fits the header description better, and is the same filename as used for Tables.jl --- src/GeoInterface.jl | 2 +- src/{defaults.jl => fallbacks.jl} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/{defaults.jl => fallbacks.jl} (100%) diff --git a/src/GeoInterface.jl b/src/GeoInterface.jl index e01b0f30..20df9d1c 100644 --- a/src/GeoInterface.jl +++ b/src/GeoInterface.jl @@ -4,7 +4,7 @@ using Base.Iterators include("types.jl") include("interface.jl") -include("defaults.jl") +include("fallbacks.jl") include("utils.jl") export testgeometry diff --git a/src/defaults.jl b/src/fallbacks.jl similarity index 100% rename from src/defaults.jl rename to src/fallbacks.jl From 2c00af7fb772003f4f6b50e2e446fe3790ec492c Mon Sep 17 00:00:00 2001 From: Martijn Visser Date: Sun, 15 May 2022 13:34:35 +0200 Subject: [PATCH 2/6] editing --- .gitignore | 1 - README.md | 15 +++++---- find_integrations.jl | 4 +-- src/GeoInterface.jl | 13 ++------ src/fallbacks.jl | 6 ++-- src/interface.jl | 15 ++++----- src/types.jl | 72 ++++++++++++++++++++++---------------------- 7 files changed, 61 insertions(+), 65 deletions(-) diff --git a/.gitignore b/.gitignore index f459254d..e5a16dee 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,3 @@ /docs/build/ .DS_Store docs/src/reference/integrations.md - diff --git a/README.md b/README.md index 980bcab9..c51e7a95 100644 --- a/README.md +++ b/README.md @@ -3,13 +3,16 @@ [![Build Status](https://github.com/JuliaGeo/GeoInterface.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/JuliaGeo/GeoInterface.jl/actions/workflows/CI.yml?query=branch%3Amain) # GeoInterface -An interface for geospatial vector data in Julia +An interface for geospatial vector data in [Julia](https://julialang.org/). -This Package describe a set of traits based on the [Simple Features standard (SF)](https://www.opengeospatial.org/standards/sfa) -for geospatial vector data, including the SQL/MM extension with support for circular geometry. -Using these traits, it should be easy to parse, serialize and use different geometries in the Julia ecosystem, -without knowing the specifics of each individual package. In that regard it is similar to Tables.jl, but for geometries instead of tables. +This Package describe a set of traits based on the [Simple Features standard +(SF)](https://www.opengeospatial.org/standards/sfa) for geospatial vector data, including +the SQL/MM extension with support for circular geometry. Using these traits, it should be +easy to parse, serialize and use different geometries in the Julia ecosystem, without +knowing the specifics of each individual package. In that regard it is similar to +[Tables.jl](https://github.com/JuliaData/Tables.jl), but for geometries instead of tables. -Packages which support the GeoInterface.jl interface can be found in [INTEGRATIONS.md](INTEGRATIONS.md). +Packages which support the GeoInterface.jl interface can be found in +[INTEGRATIONS.md](INTEGRATIONS.md). We thank Julia Computing for supporting contributions to this package. diff --git a/find_integrations.jl b/find_integrations.jl index 14108a30..a4bdfb92 100644 --- a/find_integrations.jl +++ b/find_integrations.jl @@ -6,14 +6,14 @@ ### ### Usage ### -### 1. ensure a development version of Tables.jl (`pkg> add GeoInterface`) +### 1. ensure a development version of GeoInterface.jl (`pkg> add GeoInterface`) ### 2. make sure the General registry is up to date (`pkg> up`) ### 3. run this script, which uses the first depot from DEPOT_PATH DEPOT = first(DEPOT_PATH) REGISTRIES = joinpath(DEPOT, "registries") @info DEPOT -# find each package w/ a direct dependency on Tables.jl +# find each package w/ a direct dependency on GeoInterface.jl general = joinpath(DEPOT, "General") mkpath(general) # run(`tar -xzf General.tar.gz -C $general`) diff --git a/src/GeoInterface.jl b/src/GeoInterface.jl index 20df9d1c..6dda5923 100644 --- a/src/GeoInterface.jl +++ b/src/GeoInterface.jl @@ -1,19 +1,12 @@ module GeoInterface -using Base.Iterators +using Base.Iterators: flatten + +export testgeometry, isgeometry, geomtype, ncoord, getcoord, ngeom, getgeom include("types.jl") include("interface.jl") include("fallbacks.jl") include("utils.jl") -export testgeometry -export isgeometry - -export geomtype -export ncoord -export getcoord -export ngeom -export getgeom - end # module diff --git a/src/fallbacks.jl b/src/fallbacks.jl index 14be4ef8..25b7c3f6 100644 --- a/src/fallbacks.jl +++ b/src/fallbacks.jl @@ -1,5 +1,5 @@ # Defaults for many of the interface functions are defined here as fallback. -# Methods here should take a type as first argument and should already be defined +# Methods here should take a trait instance as first argument and should already be defined # in the `interface.jl` first as a generic f(geom) method. ## Coords @@ -107,8 +107,8 @@ end """ subtrait(t::AbstractGeometryTrait) -Gets the expected, possible abstract, (sub)trait for subgeometries (retrieved with [`getgeom`](@ref)) of trait `t`. -This follows the [Type hierarchy](@ref) of Simple Features. +Gets the expected, possible abstract, (sub)trait for subgeometries (retrieved with +[`getgeom`](@ref)) of trait `t`. This follows the [Type hierarchy](@ref) of Simple Features. # Examples ```jldoctest; setup = :(using GeoInterface) diff --git a/src/interface.jl b/src/interface.jl index 45df4dec..e1fe99bb 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -2,7 +2,7 @@ """ GeoInterface.isgeometry(x) => Bool -Check if an object `x` is a geometry and thus implicitely supports GeoInterface methods. +Check if an object `x` is a geometry and thus implicitly supports GeoInterface methods. It is recommended that for users implementing `MyType`, they define only `isgeometry(::Type{MyType})`. `isgeometry(::MyType)` will then automatically delegate to this method. @@ -13,12 +13,13 @@ isgeometry(::Type{T}) where {T} = false """ GeoInterface.isfeature(x) => Bool -Check if an object `x` is a feature and thus implicitely supports some GeoInterface methods. +Check if an object `x` is a feature and thus implicitly supports some GeoInterface methods. A feature is a combination of a geometry and properties, not unlike a row in a table. It is recommended that for users implementing `MyType`, they define only `isfeature(::Type{MyType})`. `isfeature(::MyType)` will then automatically delegate to this method. -Ensures backwards compatibility with the older GeoInterface. + +Ensures backwards compatibility with GeoInterface version 0. """ isfeature(x::T) where {T} = isfeature(T) isfeature(::Type{T}) where {T} = false @@ -27,7 +28,7 @@ isfeature(::Type{T}) where {T} = false GeoInterface.geometry(feat) => geom Retrieve the geometry of `feat`. It is expected that `isgeometry(geom) === true`. -Ensures backwards compatibility with the older GeoInterface. +Ensures backwards compatibility with GeoInterface version 0. """ geometry(feat) = nothing @@ -35,7 +36,7 @@ geometry(feat) = nothing GeoInterface.properties(feat) => properties Retrieve the properties of `feat`. This can be any Iterable that behaves like an AbstractRow. -Ensures backwards compatibility with the older GeoInterface. +Ensures backwards compatibility with GeoInterface version 0. """ properties(feat) = nothing @@ -375,7 +376,7 @@ extent(geom) = extent(geomtype(geom), geom) Alias for [`extent`](@ref), for compatibility with GeoJSON and the Python geointerface. -Ensures backwards compatibility with the older GeoInterface. +Ensures backwards compatibility with GeoInterface version 0. """ bbox(geom) = extent(geom) @@ -550,7 +551,7 @@ ismeasured(geom) = ismeasured(geomtype(geom), geom) coordinates(geom) -> Vector Return (an iterator of) point coordinates. -Ensures backwards compatibility with the older GeoInterface. +Ensures backwards compatibility with GeoInterface version 0. """ coordinates(geom) = coordinates(geomtype(geom), geom) diff --git a/src/types.jl b/src/types.jl index a5e44f75..eb79fee4 100644 --- a/src/types.jl +++ b/src/types.jl @@ -1,81 +1,81 @@ -"""An AbstractGeometryTrait type for all geometries.""" +"An AbstractGeometryTrait type for all geometries." abstract type AbstractGeometryTrait end -"""An AbstractGeometryCollectionTrait type for all geometrycollections.""" +"An AbstractGeometryCollectionTrait type for all geometrycollections." abstract type AbstractGeometryCollectionTrait <: AbstractGeometryTrait end -"""A GeometryCollection is a collection of `Geometry`s.""" +"A GeometryCollection is a collection of `Geometry`s." struct GeometryCollectionTrait <: AbstractGeometryCollectionTrait end -"""An AbstractPointTrait for all points.""" +"An AbstractPointTrait for all points." abstract type AbstractPointTrait <: AbstractGeometryTrait end -"""A single point.""" +"A single point." struct PointTrait <: AbstractPointTrait end -"""An AbstractCurveTrait type for all curves.""" +"An AbstractCurveTrait type for all curves." abstract type AbstractCurveTrait <: AbstractGeometryTrait end -"""An AbstractLineString type for all linestrings.""" +"An AbstractLineString type for all linestrings." abstract type AbstractLineStringTrait <: AbstractCurveTrait end -"""A LineStringTrait is a collection of straight lines between its `PointTrait`s.""" +"A LineStringTrait is a collection of straight lines between its `PointTrait`s." struct LineStringTrait <: AbstractLineStringTrait end -"""A LineTrait is [`LineStringTrait`](@ref) with just two points.""" +"A LineTrait is [`LineStringTrait`](@ref) with just two points." struct LineTrait <: AbstractLineStringTrait end -"""A LinearRingTrait is a [`LineStringTrait`](@ref) with the same begin and endpoint.""" +"A LinearRingTrait is a [`LineStringTrait`](@ref) with the same begin and endpoint." struct LinearRingTrait <: AbstractLineStringTrait end -"""A CircularStringTrait is a curve, with an odd number of points. +"A CircularStringTrait is a curve, with an odd number of points. A single segment consists of three points, where the first and last are the beginning and end, -while the second is halfway the curve.""" +while the second is halfway the curve." struct CircularStringTrait <: AbstractCurveTrait end -"""A CompoundCurveTrait is a curve that combines straight [`LineStringTrait`](@ref)s and curved [`CircularStringTrait`](@ref)s.""" +"A CompoundCurveTrait is a curve that combines straight [`LineStringTrait`](@ref)s and curved [`CircularStringTrait`](@ref)s." struct CompoundCurveTrait <: AbstractCurveTrait end -"""An AbstractSurfaceTrait type for all surfaces.""" +"An AbstractSurfaceTrait type for all surfaces." abstract type AbstractSurfaceTrait <: AbstractGeometryTrait end -"""An AbstractCurvePolygonTrait type for all curved polygons.""" +"An AbstractCurvePolygonTrait type for all curved polygons." abstract type AbstractCurvePolygonTrait <: AbstractSurfaceTrait end -"""An [`AbstractCurvePolygonTrait`](@ref) that can contain either circular or straight curves as rings.""" +"An [`AbstractCurvePolygonTrait`](@ref) that can contain either circular or straight curves as rings." struct CurvePolygonTrait <: AbstractCurvePolygonTrait end -"""An AbstractPolygonTrait type for all polygons.""" +"An AbstractPolygonTrait type for all polygons." abstract type AbstractPolygonTrait <: AbstractCurvePolygonTrait end -"""An [`AbstractSurfaceTrait`](@ref) with straight rings either as exterior or interior(s).""" +"An [`AbstractSurfaceTrait`](@ref) with straight rings either as exterior or interior(s)." struct PolygonTrait <: AbstractPolygonTrait end -"""A [`PolygonTrait`](@ref) that is triangular.""" +"A [`PolygonTrait`](@ref) that is triangular." struct TriangleTrait <: AbstractPolygonTrait end -"""A [`PolygonTrait`](@ref) that is rectangular and could be described by the minimum and maximum vertices.""" +"A [`PolygonTrait`](@ref) that is rectangular and could be described by the minimum and maximum vertices." struct RectangleTrait <: AbstractPolygonTrait end -"""A [`PolygonTrait`](@ref) with four vertices.""" +"A [`PolygonTrait`](@ref) with four vertices." struct QuadTrait <: AbstractPolygonTrait end -"""A [`PolygonTrait`](@ref) with five vertices.""" +"A [`PolygonTrait`](@ref) with five vertices." struct PentagonTrait <: AbstractPolygonTrait end -"""A [`PolygonTrait`](@ref) with six vertices.""" +"A [`PolygonTrait`](@ref) with six vertices." struct HexagonTrait <: AbstractPolygonTrait end -"""An AbstractPolyHedralSurfaceTrait type for all polyhedralsurfaces.""" +"An AbstractPolyHedralSurfaceTrait type for all polyhedralsurfaces." abstract type AbstractPolyHedralSurfaceTrait <: AbstractSurfaceTrait end -"""A PolyHedralSurfaceTrait is a connected surface consisting of [`PolygonTrait`](@ref)s.""" +"A PolyHedralSurfaceTrait is a connected surface consisting of [`PolygonTrait`](@ref)s." struct PolyHedralSurfaceTrait <: AbstractPolyHedralSurfaceTrait end -"""A TINTrait is a [`PolyHedralSurfaceTrait`](@ref) consisting of [`TriangleTrait`](@ref)s.""" +"A TINTrait is a [`PolyHedralSurfaceTrait`](@ref) consisting of [`TriangleTrait`](@ref)s." struct TINTrait <: AbstractPolyHedralSurfaceTrait end # Surface consisting of Triangles -"""An AbstractMultiPointTrait type for all multipoints.""" +"An AbstractMultiPointTrait type for all multipoints." abstract type AbstractMultiPointTrait <: AbstractGeometryCollectionTrait end -"""A MultiPointTrait is a collection of [`PointTrait`](@ref)s.""" +"A MultiPointTrait is a collection of [`PointTrait`](@ref)s." struct MultiPointTrait <: AbstractMultiPointTrait end -"""An AbstractMultiCurveTrait type for all multicurves.""" +"An AbstractMultiCurveTrait type for all multicurves." abstract type AbstractMultiCurveTrait <: AbstractGeometryCollectionTrait end -"""A MultiCurveTrait is a collection of [`CircularStringTrait`](@ref)s.""" +"A MultiCurveTrait is a collection of [`CircularStringTrait`](@ref)s." struct MultiCurveTrait <: AbstractMultiCurveTrait end -"""An AbstractMultiLineStringTrait type for all multilinestrings.""" +"An AbstractMultiLineStringTrait type for all multilinestrings." abstract type AbstractMultiLineStringTrait <: AbstractMultiCurveTrait end -"""A MultiLineStringTrait is a collection of [`LineStringTrait`](@ref)s.""" +"A MultiLineStringTrait is a collection of [`LineStringTrait`](@ref)s." struct MultiLineStringTrait <: AbstractMultiLineStringTrait end -"""An AbstractMultiSurfaceTrait type for all multisurfaces.""" +"An AbstractMultiSurfaceTrait type for all multisurfaces." abstract type AbstractMultiSurfaceTrait <: AbstractGeometryCollectionTrait end -"""A MultiSurfaceTrait is a collection of [`AbstractSurfaceTrait`](@ref)s.""" +"A MultiSurfaceTrait is a collection of [`AbstractSurfaceTrait`](@ref)s." struct MultiSurfaceTrait <: AbstractMultiSurfaceTrait end -"""An AbstractMultiPolygonTrait type for all multipolygons.""" +"An AbstractMultiPolygonTrait type for all multipolygons." abstract type AbstractMultiPolygonTrait <: AbstractMultiSurfaceTrait end -"""A MultiPolygonTrait is a collection of [`PolygonTrait`](@ref)s.""" +"A MultiPolygonTrait is a collection of [`PolygonTrait`](@ref)s." struct MultiPolygonTrait <: AbstractMultiPolygonTrait end From 69b38a709ac13e2405cd5a520f8bc65ee2bac537 Mon Sep 17 00:00:00 2001 From: Martijn Visser Date: Sun, 15 May 2022 13:41:19 +0200 Subject: [PATCH 3/6] replace argument _ with geom This makes it more clear what the unused argument is supposed to be. --- docs/src/guides/defaults.md | 12 ++++++------ src/fallbacks.jl | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/src/guides/defaults.md b/docs/src/guides/defaults.md index 41b2d95e..00873495 100644 --- a/docs/src/guides/defaults.md +++ b/docs/src/guides/defaults.md @@ -38,10 +38,10 @@ endpoint(geom) = getpoint(geom, length(geom)) In some cases, we know the return value of a function for a specific geometry (sub)type beforehand and have implemented them. ```julia -npoint(::LineTrait, _) = 2 -npoint(::TriangleTrait, _) = 3 -npoint(::RectangleTrait, _) = 4 -npoint(::QuadTrait, _) = 4 -npoint(::PentagonTrait, _) = 5 -npoint(::HexagonTrait, _) = 6 +npoint(::LineTrait, geom) = 2 +npoint(::TriangleTrait, geom) = 3 +npoint(::RectangleTrait, geom) = 4 +npoint(::QuadTrait, geom) = 4 +npoint(::PentagonTrait, geom) = 5 +npoint(::HexagonTrait, geom) = 6 ``` diff --git a/src/fallbacks.jl b/src/fallbacks.jl index 25b7c3f6..b15f41c8 100644 --- a/src/fallbacks.jl +++ b/src/fallbacks.jl @@ -66,17 +66,17 @@ getgeom(t::AbstractGeometryTrait, geom) = (getgeom(t, geom, i) for i in 1:ngeom( getcoord(t::AbstractPointTrait, geom) = (getcoord(t, geom, i) for i in 1:ncoord(t, geom)) ## Npoints -npoint(::LineTrait, _) = 2 -npoint(::TriangleTrait, _) = 3 -nring(::TriangleTrait, _) = 1 -npoint(::RectangleTrait, _) = 4 -nring(::RectangleTrait, _) = 1 -npoint(::QuadTrait, _) = 4 -nring(::QuadTrait, _) = 1 -npoint(::PentagonTrait, _) = 5 -nring(::PentagonTrait, _) = 1 -npoint(::HexagonTrait, _) = 6 -nring(::HexagonTrait, _) = 1 +npoint(::LineTrait, geom) = 2 +npoint(::TriangleTrait, geom) = 3 +nring(::TriangleTrait, geom) = 1 +npoint(::RectangleTrait, geom) = 4 +nring(::RectangleTrait, geom) = 1 +npoint(::QuadTrait, geom) = 4 +nring(::QuadTrait, geom) = 1 +npoint(::PentagonTrait, geom) = 5 +nring(::PentagonTrait, geom) = 1 +npoint(::HexagonTrait, geom) = 6 +nring(::HexagonTrait, geom) = 1 issimple(::AbstractCurveTrait, geom) = allunique([getpoint(t, geom, i) for i in 1:npoint(geom)-1]) && allunique([getpoint(t, geom, i) for i in 2:npoint(t, geom)]) From 7bef23760f85907be2968cbf691a40c4fe0559e2 Mon Sep 17 00:00:00 2001 From: Martijn Visser Date: Sun, 15 May 2022 13:51:59 +0200 Subject: [PATCH 4/6] drop module name for exported functions --- test/test_primitives.jl | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/test/test_primitives.jl b/test/test_primitives.jl index 41e69228..78fa613b 100644 --- a/test/test_primitives.jl +++ b/test/test_primitives.jl @@ -1,4 +1,5 @@ - +using GeoInterface +using Test @testset "Developer" begin # Implement interface @@ -19,7 +20,7 @@ GeoInterface.geomtype(::MyCurve) = GeoInterface.LineStringTrait() GeoInterface.ngeom(::GeoInterface.LineStringTrait, geom::MyCurve) = 2 GeoInterface.getgeom(::GeoInterface.LineStringTrait, geom::MyCurve, i) = MyPoint() - GeoInterface.convert(::Type{MyCurve}, ::GeoInterface.LineStringTrait, geom) = geom + convert(::Type{MyCurve}, ::GeoInterface.LineStringTrait, geom) = geom GeoInterface.isgeometry(::MyPolygon) = true GeoInterface.geomtype(::MyPolygon) = GeoInterface.PolygonTrait() @@ -29,15 +30,15 @@ @testset "Point" begin geom = MyPoint() - @test GeoInterface.testgeometry(geom) + @test testgeometry(geom) @test GeoInterface.x(geom) === 1 @test GeoInterface.y(geom) === 2 - @test GeoInterface.ncoord(geom) === 2 + @test ncoord(geom) === 2 end @testset "LineString" begin geom = MyCurve() - @test GeoInterface.testgeometry(geom) + @test testgeometry(geom) @test !isnothing(GeoInterface.convert(MyCurve, geom)) @test GeoInterface.npoint(geom) == 2 # defaults to ngeom @@ -49,7 +50,7 @@ @testset "Polygon" begin geom = MyPolygon() - @test GeoInterface.testgeometry(geom) + @test testgeometry(geom) @test GeoInterface.nring(geom) == 2 @test GeoInterface.nhole(geom) == 1 @@ -71,10 +72,10 @@ end struct Row end struct Point end - GeoInterface.isgeometry(::Point) = true - GeoInterface.geomtype(::Point) = GeoInterface.PointTrait() - GeoInterface.ncoord(::GeoInterface.PointTrait, geom::Point) = 2 - GeoInterface.getcoord(::GeoInterface.PointTrait, geom::Point, i) = [1, 2][i] + isgeometry(::Point) = true + geomtype(::Point) = GeoInterface.PointTrait() + ncoord(::GeoInterface.PointTrait, geom::Point) = 2 + getcoord(::GeoInterface.PointTrait, geom::Point, i) = [1, 2][i] GeoInterface.isfeature(::Row) = true GeoInterface.geometry(r::Row) = Point() From d1d95898fe1d13d749b0d6b57a744abd70f06f44 Mon Sep 17 00:00:00 2001 From: Martijn Visser Date: Sun, 15 May 2022 14:21:54 +0200 Subject: [PATCH 5/6] fix tests --- test/test_primitives.jl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/test_primitives.jl b/test/test_primitives.jl index 78fa613b..9c837252 100644 --- a/test/test_primitives.jl +++ b/test/test_primitives.jl @@ -20,7 +20,7 @@ using Test GeoInterface.geomtype(::MyCurve) = GeoInterface.LineStringTrait() GeoInterface.ngeom(::GeoInterface.LineStringTrait, geom::MyCurve) = 2 GeoInterface.getgeom(::GeoInterface.LineStringTrait, geom::MyCurve, i) = MyPoint() - convert(::Type{MyCurve}, ::GeoInterface.LineStringTrait, geom) = geom + Base.convert(::Type{MyCurve}, ::GeoInterface.LineStringTrait, geom) = geom GeoInterface.isgeometry(::MyPolygon) = true GeoInterface.geomtype(::MyPolygon) = GeoInterface.PolygonTrait() @@ -39,7 +39,7 @@ using Test @testset "LineString" begin geom = MyCurve() @test testgeometry(geom) - @test !isnothing(GeoInterface.convert(MyCurve, geom)) + @test !isnothing(convert(MyCurve, geom)) @test GeoInterface.npoint(geom) == 2 # defaults to ngeom @test GeoInterface.coordinates(geom) == [[1, 2], [1, 2]] @@ -72,10 +72,10 @@ end struct Row end struct Point end - isgeometry(::Point) = true - geomtype(::Point) = GeoInterface.PointTrait() - ncoord(::GeoInterface.PointTrait, geom::Point) = 2 - getcoord(::GeoInterface.PointTrait, geom::Point, i) = [1, 2][i] + GeoInterface.isgeometry(::Point) = true + GeoInterface.geomtype(::Point) = GeoInterface.PointTrait() + GeoInterface.ncoord(::GeoInterface.PointTrait, geom::Point) = 2 + GeoInterface.getcoord(::GeoInterface.PointTrait, geom::Point, i) = [1, 2][i] GeoInterface.isfeature(::Row) = true GeoInterface.geometry(r::Row) = Point() From f98a1397e30c6c9bd04727f56d6496e8a87e0bca Mon Sep 17 00:00:00 2001 From: Martijn Visser Date: Sun, 15 May 2022 14:17:26 +0200 Subject: [PATCH 6/6] export the traits --- docs/src/guides/developer.md | 74 ++++++++++++++++++------------------ docs/src/tutorials/usage.md | 4 +- src/GeoInterface.jl | 37 ++++++++++++++++++ src/fallbacks.jl | 12 +++--- src/interface.jl | 2 +- test/test_primitives.jl | 28 +++++++------- 6 files changed, 97 insertions(+), 60 deletions(-) diff --git a/docs/src/guides/developer.md b/docs/src/guides/developer.md index cef0a43b..3c7e581e 100644 --- a/docs/src/guides/developer.md +++ b/docs/src/guides/developer.md @@ -15,7 +15,7 @@ Last but not least, we also provide an interface for features--geometries with p ```julia GeoInterface.isgeometry(geom::customgeom)::Bool = true -GeoInterface.geomtype(geom::customgeom)::DataType = GeoInterface.XTrait() # <: AbstractGeometryTrait +GeoInterface.geomtype(geom::customgeom)::DataType = XTrait() # <: AbstractGeometryTrait # for PointTraits GeoInterface.ncoord(geomtype(geom), geom::customgeom)::Integer GeoInterface.getcoord(geomtype(geom), geom::customgeom, i)::Real @@ -93,79 +93,79 @@ GeoInterface.isgeometry(geom::customgeom)::Bool = true A `geom::customgeom` with "Point"-like traits implements ```julia -GeoInterface.geomtype(geom::customgeom)::DataType = GeoInterface.PointTrait() -GeoInterface.ncoord(::GeoInterface.PointTrait, geom::customgeom)::Integer -GeoInterface.getcoord(::GeoInterface.PointTrait, geom::customgeom, i)::Real +GeoInterface.geomtype(geom::customgeom)::DataType = PointTrait() +GeoInterface.ncoord(::PointTrait, geom::customgeom)::Integer +GeoInterface.getcoord(::PointTrait, geom::customgeom, i)::Real # Defaults -GeoInterface.ngeom(::GeoInterface.PointTrait, geom)::Integer = 0 -GeoInterface.getgeom(::GeoInterface.PointTrait, geom::customgeom, i) = nothing +GeoInterface.ngeom(::PointTrait, geom)::Integer = 0 +GeoInterface.getgeom(::PointTrait, geom::customgeom, i) = nothing ``` A `geom::customgeom` with "LineString"-like traits implements the following methods: ```julia -GeoInterface.geomtype(geom::customgeom)::DataType = GeoInterface.LineStringTrait() -GeoInterface.ncoord(::GeoInterface.LineStringTrait, geom::customgeom)::Integer +GeoInterface.geomtype(geom::customgeom)::DataType = LineStringTrait() +GeoInterface.ncoord(::LineStringTrait, geom::customgeom)::Integer # These alias for npoint and getpoint -GeoInterface.ngeom(::GeoInterface.LineStringTrait, geom::customgeom)::Integer -GeoInterface.getgeom(::GeoInterface.LineStringTrait, geom::customgeom, i) # of geomtype Point +GeoInterface.ngeom(::LineStringTrait, geom::customgeom)::Integer +GeoInterface.getgeom(::LineStringTrait, geom::customgeom, i) # of geomtype Point # Optional -GeoInterface.isclosed(::GeoInterface.LineStringTrait, geom::customgeom)::Bool -GeoInterface.issimple(::GeoInterface.LineStringTrait, geom::customgeom)::Bool -GeoInterface.length(::GeoInterface.LineStringTrait, geom::customgeom)::Real +GeoInterface.isclosed(::LineStringTrait, geom::customgeom)::Bool +GeoInterface.issimple(::LineStringTrait, geom::customgeom)::Bool +GeoInterface.length(::LineStringTrait, geom::customgeom)::Real ``` A `geom::customgeom` with "Polygon"-like traits can implement the following methods: ```julia -GeoInterface.geomtype(geom::customgeom)::DataType = GeoInterface.PolygonTrait() -GeoInterface.ncoord(::GeoInterface.PolygonTrait, geom::customgeom)::Integer +GeoInterface.geomtype(geom::customgeom)::DataType = PolygonTrait() +GeoInterface.ncoord(::PolygonTrait, geom::customgeom)::Integer # These alias for nring and getring -GeoInterface.ngeom(::GeoInterface.PolygonTrait, geom::customgeom)::Integer -GeoInterface.getgeom(::GeoInterface.PolygonTrait, geom::customgeom, i)::"LineStringTrait" +GeoInterface.ngeom(::PolygonTrait, geom::customgeom)::Integer +GeoInterface.getgeom(::PolygonTrait, geom::customgeom, i)::"LineStringTrait" # Optional -GeoInterface.area(::GeoInterface.PolygonTrait, geom::customgeom)::Real -GeoInterface.centroid(::GeoInterface.PolygonTrait, geom::customgeom)::"PointTrait" -GeoInterface.pointonsurface(::GeoInterface.PolygonTrait, geom::customgeom)::"PointTrait" -GeoInterface.boundary(::GeoInterface.PolygonTrait, geom::customgeom)::"LineStringTrait" +GeoInterface.area(::PolygonTrait, geom::customgeom)::Real +GeoInterface.centroid(::PolygonTrait, geom::customgeom)::"PointTrait" +GeoInterface.pointonsurface(::PolygonTrait, geom::customgeom)::"PointTrait" +GeoInterface.boundary(::PolygonTrait, geom::customgeom)::"LineStringTrait" ``` A `geom::customgeom` with "GeometryCollection"-like traits has to implement the following methods: ```julia -GeoInterface.geomtype(geom::customgeom) = GeoInterface.GeometryCollectionTrait() -GeoInterface.ncoord(::GeoInterface.GeometryCollectionTrait, geom::customgeom)::Integer -GeoInterface.ngeom(::GeoInterface.GeometryCollectionTrait, geom::customgeom)::Integer -GeoInterface.getgeom(::GeoInterface.GeometryCollectionTrait,geom::customgeomm, i)::"GeometryTrait" +GeoInterface.geomtype(geom::customgeom) = GeometryCollectionTrait() +GeoInterface.ncoord(::GeometryCollectionTrait, geom::customgeom)::Integer +GeoInterface.ngeom(::GeometryCollectionTrait, geom::customgeom)::Integer +GeoInterface.getgeom(::GeometryCollectionTrait,geom::customgeomm, i)::"GeometryTrait" ``` A `geom::customgeom` with "MultiPoint"-like traits has to implement the following methods: ```julia -GeoInterface.geomtype(geom::customgeom) = GeoInterface.MultiPointTrait() -GeoInterface.ncoord(::GeoInterface.MultiPointTrait, geom::customgeom)::Integer +GeoInterface.geomtype(geom::customgeom) = MultiPointTrait() +GeoInterface.ncoord(::MultiPointTrait, geom::customgeom)::Integer # These alias for npoint and getpoint -GeoInterface.ngeom(::GeoInterface.MultiPointTrait, geom::customgeom)::Integer -GeoInterface.getgeom(::GeoInterface.MultiPointTrait, geom::customgeom, i)::"PointTrait" +GeoInterface.ngeom(::MultiPointTrait, geom::customgeom)::Integer +GeoInterface.getgeom(::MultiPointTrait, geom::customgeom, i)::"PointTrait" ``` A `geom::customgeom` with "MultiLineString"-like traits has to implement the following methods: ```julia -GeoInterface.geomtype(geom::customgeom) = GeoInterface.MultiLineStringTrait() -GeoInterface.ncoord(::GeoInterface.MultiLineStringTrait, geom::customgeom)::Integer +GeoInterface.geomtype(geom::customgeom) = MultiLineStringTrait() +GeoInterface.ncoord(::MultiLineStringTrait, geom::customgeom)::Integer # These alias for nlinestring and getlinestring -GeoInterface.ngeom(::GeoInterface.MultiLineStringTrait, geom::customgeom)::Integer -GeoInterface.getgeom(::GeoInterface.MultiLineStringTrait,geom::customgeomm, i)::"LineStringTrait" +GeoInterface.ngeom(::MultiLineStringTrait, geom::customgeom)::Integer +GeoInterface.getgeom(::MultiLineStringTrait,geom::customgeomm, i)::"LineStringTrait" ``` A `geom::customgeom` with "MultiPolygon"-like traits has to implement the following methods: ```julia -GeoInterface.geomtype(geom::customgeom) = GeoInterface.MultiPolygonTrait() -GeoInterface.ncoord(::GeoInterface.MultiPolygonTrait, geom::customgeom)::Integer +GeoInterface.geomtype(geom::customgeom) = MultiPolygonTrait() +GeoInterface.ncoord(::MultiPolygonTrait, geom::customgeom)::Integer # These alias for npolygon and getpolygon -GeoInterface.ngeom(::GeoInterface.MultiPolygonTrait, geom::customgeom)::Integer -GeoInterface.getgeom(::GeoInterface.MultiPolygonTrait, geom::customgeom, i)::"PolygonTrait" +GeoInterface.ngeom(::MultiPolygonTrait, geom::customgeom)::Integer +GeoInterface.getgeom(::MultiPolygonTrait, geom::customgeom, i)::"PolygonTrait" ``` diff --git a/docs/src/tutorials/usage.md b/docs/src/tutorials/usage.md index bf6de7e2..c1f7bee4 100644 --- a/docs/src/tutorials/usage.md +++ b/docs/src/tutorials/usage.md @@ -41,10 +41,10 @@ julia> geom = createpolygon(...)::ArchGDAL.IGeometry # no idea about the interf julia> isgeometry(geom) True julia> geomtype(geom) -GeoInterface.PolygonTrait() +PolygonTrait() julia> ext = exterior(geom); julia> geomtype(ext) -GeoInterface.LineStringTrait() +LineStringTrait() julia> getcoords.(getpoint.(Ref(ext), 1:npoint(ext))) [[1.,2.],[2.,3.],[1.,2.]] julia> coordinates(geom) # fallback based on ngeom & npoint above diff --git a/src/GeoInterface.jl b/src/GeoInterface.jl index 6dda5923..41a05ee1 100644 --- a/src/GeoInterface.jl +++ b/src/GeoInterface.jl @@ -4,6 +4,43 @@ using Base.Iterators: flatten export testgeometry, isgeometry, geomtype, ncoord, getcoord, ngeom, getgeom +# traits +export AbstractGeometryTrait, + AbstractGeometryCollectionTrait, + GeometryCollectionTrait, + AbstractPointTrait, + PointTrait, + AbstractCurveTrait, + AbstractLineStringTrait, + LineStringTrait, + LineTrait, + LinearRingTrait, + CircularStringTrait, + CompoundCurveTrait, + AbstractSurfaceTrait, + AbstractCurvePolygonTrait, + CurvePolygonTrait, + AbstractPolygonTrait, + PolygonTrait, + TriangleTrait, + RectangleTrait, + QuadTrait, + PentagonTrait, + HexagonTrait, + AbstractPolyHedralSurfaceTrait, + PolyHedralSurfaceTrait, + TINTrait, + AbstractMultiPointTrait, + MultiPointTrait, + AbstractMultiCurveTrait, + MultiCurveTrait, + AbstractMultiLineStringTrait, + MultiLineStringTrait, + AbstractMultiSurfaceTrait, + MultiSurfaceTrait, + AbstractMultiPolygonTrait, + MultiPolygonTrait + include("types.jl") include("interface.jl") include("fallbacks.jl") diff --git a/src/fallbacks.jl b/src/fallbacks.jl index b15f41c8..c9e1675f 100644 --- a/src/fallbacks.jl +++ b/src/fallbacks.jl @@ -112,16 +112,16 @@ Gets the expected, possible abstract, (sub)trait for subgeometries (retrieved wi # Examples ```jldoctest; setup = :(using GeoInterface) -julia> GeoInterface.subtrait(GeoInterface.LineStringTrait()) -GeoInterface.AbstractPointTrait -julia> GeoInterface.subtrait(GeoInterface.PolygonTrait()) # Any of LineStringTrait, LineTrait, LinearRingTrait -GeoInterface.AbstractLineStringTrait +julia> GeoInterface.subtrait(LineStringTrait()) +AbstractPointTrait +julia> GeoInterface.subtrait(PolygonTrait()) # Any of LineStringTrait, LineTrait, LinearRingTrait +AbstractLineStringTrait ``` ```jldoctest; setup = :(using GeoInterface) # `nothing` is returned when there's no subtrait or when it's not known beforehand -julia> isnothing(GeoInterface.subtrait(GeoInterface.PointTrait())) +julia> isnothing(GeoInterface.subtrait(PointTrait())) true -julia> isnothing(GeoInterface.subtrait(GeoInterface.GeometryCollectionTrait())) +julia> isnothing(GeoInterface.subtrait(GeometryCollectionTrait())) true ``` """ diff --git a/src/interface.jl b/src/interface.jl index e1fe99bb..9666d500 100644 --- a/src/interface.jl +++ b/src/interface.jl @@ -43,7 +43,7 @@ properties(feat) = nothing """ GeoInterface.geomtype(geom) => T <: AbstractGeometry -Returns the geometry type, such as [`GeoInterface.PolygonTrait`](@ref) or [`GeoInterface.PointTrait`](@ref). +Returns the geometry type, such as [`PolygonTrait`](@ref) or [`PointTrait`](@ref). """ geomtype(geom) = nothing diff --git a/test/test_primitives.jl b/test/test_primitives.jl index 9c837252..e37b6a24 100644 --- a/test/test_primitives.jl +++ b/test/test_primitives.jl @@ -12,20 +12,20 @@ using Test struct MyCollection end GeoInterface.isgeometry(::MyPoint) = true - GeoInterface.geomtype(::MyPoint) = GeoInterface.PointTrait() - GeoInterface.ncoord(::GeoInterface.PointTrait, geom::MyPoint) = 2 - GeoInterface.getcoord(::GeoInterface.PointTrait, geom::MyPoint, i) = [1, 2][i] + GeoInterface.geomtype(::MyPoint) = PointTrait() + GeoInterface.ncoord(::PointTrait, geom::MyPoint) = 2 + GeoInterface.getcoord(::PointTrait, geom::MyPoint, i) = [1, 2][i] GeoInterface.isgeometry(::MyCurve) = true - GeoInterface.geomtype(::MyCurve) = GeoInterface.LineStringTrait() - GeoInterface.ngeom(::GeoInterface.LineStringTrait, geom::MyCurve) = 2 - GeoInterface.getgeom(::GeoInterface.LineStringTrait, geom::MyCurve, i) = MyPoint() - Base.convert(::Type{MyCurve}, ::GeoInterface.LineStringTrait, geom) = geom + GeoInterface.geomtype(::MyCurve) = LineStringTrait() + GeoInterface.ngeom(::LineStringTrait, geom::MyCurve) = 2 + GeoInterface.getgeom(::LineStringTrait, geom::MyCurve, i) = MyPoint() + Base.convert(::Type{MyCurve}, ::LineStringTrait, geom) = geom GeoInterface.isgeometry(::MyPolygon) = true - GeoInterface.geomtype(::MyPolygon) = GeoInterface.PolygonTrait() - GeoInterface.ngeom(::GeoInterface.PolygonTrait, geom::MyPolygon) = 2 - GeoInterface.getgeom(::GeoInterface.PolygonTrait, geom::MyPolygon, i) = MyCurve() + GeoInterface.geomtype(::MyPolygon) = PolygonTrait() + GeoInterface.ngeom(::PolygonTrait, geom::MyPolygon) = 2 + GeoInterface.getgeom(::PolygonTrait, geom::MyPolygon, i) = MyCurve() @testset "Point" begin @@ -65,7 +65,7 @@ using Test end @testset "Defaults" begin - @test GeoInterface.subtrait(GeoInterface.TINTrait()) == GeoInterface.TriangleTrait + @test GeoInterface.subtrait(TINTrait()) == TriangleTrait end @testset "Feature" begin @@ -73,9 +73,9 @@ end struct Point end GeoInterface.isgeometry(::Point) = true - GeoInterface.geomtype(::Point) = GeoInterface.PointTrait() - GeoInterface.ncoord(::GeoInterface.PointTrait, geom::Point) = 2 - GeoInterface.getcoord(::GeoInterface.PointTrait, geom::Point, i) = [1, 2][i] + GeoInterface.geomtype(::Point) = PointTrait() + GeoInterface.ncoord(::PointTrait, geom::Point) = 2 + GeoInterface.getcoord(::PointTrait, geom::Point, i) = [1, 2][i] GeoInterface.isfeature(::Row) = true GeoInterface.geometry(r::Row) = Point()