Skip to content

Move the GeoInterface.jl code to an extension #212

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
name = "GeometryBasics"
uuid = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
authors = ["SimonDanisch <sdanisch@gmail.com>"]
version = "0.4.10"
version = "0.4.11"

[deps]
EarCut_jll = "5ae413db-bbd1-5e63-b57d-d24a61df00f5"
Extents = "411431e0-e8b7-467b-b5e0-f676ba4f2910"
GeoInterface = "cf35fbd7-0cd7-5166-be24-54bfbe79505f"
IterTools = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"

[weakdeps]
GeoInterface = "cf35fbd7-0cd7-5166-be24-54bfbe79505f"

[extensions]
GeometryBasicsGeoInterfaceExt = "GeoInterface"

[compat]
Aqua = "0.8"
EarCut_jll = "2"
Expand All @@ -32,9 +37,10 @@ julia = "1.6"
[extras]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
GeoJSON = "61d90e0f-e114-555e-ac52-39dfb47a3ef9"
GeoInterface = "cf35fbd7-0cd7-5166-be24-54bfbe79505f"
OffsetArrays = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Aqua", "GeoJSON", "Test", "Random", "OffsetArrays"]
test = ["Aqua", "GeoInterface", "GeoJSON", "Test", "Random", "OffsetArrays"]
164 changes: 164 additions & 0 deletions ext/GeometryBasicsGeoInterfaceExt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
module GeometryBasicsGeoInterfaceExt

using GeoInterface, GeometryBasics

import GeometryBasics: geointerface_geomtype

# Implementation of trait based interface from https://github.com/JuliaGeo/GeoInterface.jl/

GeoInterface.isgeometry(::Type{<:AbstractGeometry}) = true
GeoInterface.isgeometry(::Type{<:AbstractFace}) = true
GeoInterface.isgeometry(::Type{<:AbstractPoint}) = true
GeoInterface.isgeometry(::Type{<:AbstractMesh}) = true
GeoInterface.isgeometry(::Type{<:AbstractPolygon}) = true
GeoInterface.isgeometry(::Type{<:LineString}) = true
GeoInterface.isgeometry(::Type{<:MultiPoint}) = true
GeoInterface.isgeometry(::Type{<:MultiLineString}) = true
GeoInterface.isgeometry(::Type{<:MultiPolygon}) = true
GeoInterface.isgeometry(::Type{<:Mesh}) = true

GeoInterface.geomtrait(::Point) = PointTrait()
GeoInterface.geomtrait(::Line) = LineTrait()
GeoInterface.geomtrait(::LineString) = LineStringTrait()
GeoInterface.geomtrait(::Polygon) = PolygonTrait()
GeoInterface.geomtrait(::MultiPoint) = MultiPointTrait()
GeoInterface.geomtrait(::MultiLineString) = MultiLineStringTrait()
GeoInterface.geomtrait(::MultiPolygon) = MultiPolygonTrait()
GeoInterface.geomtrait(::GeometryBasics.Ngon) = PolygonTrait()
GeoInterface.geomtrait(::AbstractMesh) = PolyhedralSurfaceTrait()

# GeoInterface calls this method in `GeoInterface.convert(GeometryBasics, ...)`
geointerface_geomtype(::GeoInterface.PointTrait) = Point
geointerface_geomtype(::GeoInterface.MultiPointTrait) = MultiPoint
geointerface_geomtype(::GeoInterface.LineTrait) = Line
geointerface_geomtype(::GeoInterface.LineStringTrait) = LineString
geointerface_geomtype(::GeoInterface.MultiLineStringTrait) = MultiLineString
geointerface_geomtype(::GeoInterface.PolygonTrait) = Polygon
geointerface_geomtype(::GeoInterface.MultiPolygonTrait) = MultiPolygon
geointerface_geomtype(::GeoInterface.PolyhedralSurfaceTrait) = Mesh

GeoInterface.geomtrait(::GeometryBasics.Simplex{Dim,T,1}) where {Dim,T} = PointTrait()
GeoInterface.geomtrait(::GeometryBasics.Simplex{Dim,T,2}) where {Dim,T} = LineStringTrait()
GeoInterface.geomtrait(::GeometryBasics.Simplex{Dim,T,3}) where {Dim,T} = PolygonTrait()

GeoInterface.ncoord(::PointTrait, g::GeometryBasics.Point) = length(g)
GeoInterface.getcoord(::PointTrait, g::GeometryBasics.Point, i::Int) = g[i]

GeoInterface.ngeom(::LineTrait, g::GeometryBasics.Line) = length(g)
GeoInterface.getgeom(::LineTrait, g::GeometryBasics.Line, i::Int) = g[i]

GeoInterface.ngeom(::LineStringTrait, g::GeometryBasics.LineString) = length(g) + 1 # n line segments + 1
GeoInterface.ncoord(::LineStringTrait, g::GeometryBasics.LineString{Dim}) where {Dim} = Dim
function GeoInterface.getgeom(::LineStringTrait, g::GeometryBasics.LineString, i::Int)
return GeometryBasics.coordinates(g)[i]
end

GeoInterface.ngeom(::PolygonTrait, g::GeometryBasics.Polygon) = length(g.interiors) + 1 # +1 for exterior
function GeoInterface.getgeom(::PolygonTrait,
g::GeometryBasics.Polygon,
i::Int)::typeof(g.exterior)
return i > 1 ? g.interiors[i - 1] : g.exterior
end

GeoInterface.ngeom(::MultiPointTrait, g::GeometryBasics.MultiPoint) = length(g)
GeoInterface.getgeom(::MultiPointTrait, g::GeometryBasics.MultiPoint, i::Int) = g[i]

function GeoInterface.ngeom(::MultiLineStringTrait, g::GeometryBasics.MultiLineString)
return length(g)
end
function GeoInterface.getgeom(::MultiLineStringTrait, g::GeometryBasics.MultiLineString, i::Int)
return g[i]
end
GeoInterface.ncoord(::MultiLineStringTrait, g::GeometryBasics.MultiLineString{Dim}) where {Dim} = Dim

GeoInterface.ngeom(::MultiPolygonTrait, g::GeometryBasics.MultiPolygon) = length(g)
GeoInterface.getgeom(::MultiPolygonTrait, g::GeometryBasics.MultiPolygon, i::Int) = g[i]

function GeoInterface.ncoord(::AbstractGeometryTrait,
::Simplex{Dim,T,N,P}) where {Dim,T,N,P}
return Dim
end
function GeoInterface.ncoord(::AbstractGeometryTrait,
::AbstractGeometry{Dim,T}) where {Dim,T}
return Dim
end
function GeoInterface.ngeom(::AbstractGeometryTrait,
::Simplex{Dim,T,N,P}) where {Dim,T,N,P}
return N
end
GeoInterface.ngeom(::PolygonTrait, ::GeometryBasics.Ngon) = 1 # can't have any holes
GeoInterface.getgeom(::PolygonTrait, g::GeometryBasics.Ngon, _) = LineString(g.points)

function GeoInterface.ncoord(::PolyhedralSurfaceTrait,
::Mesh{Dim,T,E,V} where {Dim,T,E,V})
return Dim
end
GeoInterface.ngeom(::PolyhedralSurfaceTrait, g::GeometryBasics.AbstractMesh) = length(g)
GeoInterface.getgeom(::PolyhedralSurfaceTrait, g::GeometryBasics.AbstractMesh, i) = g[i]

function GeoInterface.convert(::Type{Point}, type::PointTrait, geom)
x, y = GeoInterface.x(geom), GeoInterface.y(geom)
if GeoInterface.is3d(geom)
z = GeoInterface.z(geom)
T = promote_type(typeof(x), typeof(y), typeof(z))
return Point{3,T}(x, y, z)
else
GeoInterface.x(geom), GeoInterface.y(geom)
T = promote_type(typeof(x), typeof(y))
return Point{2,T}(x, y)
end
end

function GeoInterface.convert(::Type{LineString}, type::LineStringTrait, geom)
g1 = getgeom(geom, 1)
x, y = GeoInterface.x(g1), GeoInterface.y(g1)
if GeoInterface.is3d(geom)
z = GeoInterface.z(g1)
T = promote_type(typeof(x), typeof(y), typeof(z))
return LineString([Point{3,T}(GeoInterface.x(p), GeoInterface.y(p), GeoInterface.z(p)) for p in getgeom(geom)])
else
T = promote_type(typeof(x), typeof(y))
return LineString([Point{2,T}(GeoInterface.x(p), GeoInterface.y(p)) for p in getgeom(geom)])
end
end

function GeoInterface.convert(::Type{Polygon}, type::PolygonTrait, geom)
t = LineStringTrait()
exterior = GeoInterface.convert(LineString, t, GeoInterface.getexterior(geom))
if GeoInterface.nhole(geom) == 0
return Polygon(exterior)
else
interiors = map(h -> GeoInterface.convert(LineString, t, h), GeoInterface.gethole(geom))
return Polygon(exterior, interiors)
end
end

function GeoInterface.convert(::Type{MultiPoint}, type::MultiPointTrait, geom)
g1 = getgeom(geom, 1)
x, y = GeoInterface.x(g1), GeoInterface.y(g1)
if GeoInterface.is3d(geom)
z = GeoInterface.z(g1)
T = promote_type(typeof(x), typeof(y), typeof(z))
return MultiPoint([Point{3,T}(GeoInterface.x(p), GeoInterface.y(p), GeoInterface.z(p)) for p in getgeom(geom)])
else
T = promote_type(typeof(x), typeof(y))
return MultiPoint([Point{2,T}(GeoInterface.x(p), GeoInterface.y(p)) for p in getgeom(geom)])
end
end

function GeoInterface.convert(::Type{MultiLineString}, type::MultiLineStringTrait, geom)
t = LineStringTrait()
return MultiLineString(map(l -> GeoInterface.convert(LineString, t, l), getgeom(geom)))
end

function GeoInterface.convert(::Type{MultiPolygon}, type::MultiPolygonTrait, geom)
t = PolygonTrait()
return MultiPolygon(map(poly -> GeoInterface.convert(Polygon, t, poly), getgeom(geom)))
end

function GeometryBasics.Extents.extent(rect::Rect2)
(xmin, ymin), (xmax, ymax) = extrema(rect)
return GeometryBasics.Extents.Extent(X=(xmin, xmax), Y=(ymin, ymax))
end

end
1 change: 0 additions & 1 deletion src/GeometryBasics.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
module GeometryBasics

using StaticArrays, Tables, StructArrays, IterTools, LinearAlgebra
using GeoInterface
import Extents
using EarCut_jll

Expand Down
159 changes: 4 additions & 155 deletions src/geointerface.jl
Original file line number Diff line number Diff line change
@@ -1,156 +1,5 @@
# Implementation of trait based interface from https://github.com/JuliaGeo/GeoInterface.jl/

GeoInterface.isgeometry(::Type{<:AbstractGeometry}) = true
GeoInterface.isgeometry(::Type{<:AbstractFace}) = true
GeoInterface.isgeometry(::Type{<:AbstractPoint}) = true
GeoInterface.isgeometry(::Type{<:AbstractMesh}) = true
GeoInterface.isgeometry(::Type{<:AbstractPolygon}) = true
GeoInterface.isgeometry(::Type{<:LineString}) = true
GeoInterface.isgeometry(::Type{<:MultiPoint}) = true
GeoInterface.isgeometry(::Type{<:MultiLineString}) = true
GeoInterface.isgeometry(::Type{<:MultiPolygon}) = true
GeoInterface.isgeometry(::Type{<:Mesh}) = true

GeoInterface.geomtrait(::Point) = PointTrait()
GeoInterface.geomtrait(::Line) = LineTrait()
GeoInterface.geomtrait(::LineString) = LineStringTrait()
GeoInterface.geomtrait(::Polygon) = PolygonTrait()
GeoInterface.geomtrait(::MultiPoint) = MultiPointTrait()
GeoInterface.geomtrait(::MultiLineString) = MultiLineStringTrait()
GeoInterface.geomtrait(::MultiPolygon) = MultiPolygonTrait()
GeoInterface.geomtrait(::Ngon) = PolygonTrait()
GeoInterface.geomtrait(::AbstractMesh) = PolyhedralSurfaceTrait()

# GeoInterface calls this method in `GeoInterface.convert(GeometryBasics, ...)`
geointerface_geomtype(::GeoInterface.PointTrait) = Point
geointerface_geomtype(::GeoInterface.MultiPointTrait) = MultiPoint
geointerface_geomtype(::GeoInterface.LineTrait) = Line
geointerface_geomtype(::GeoInterface.LineStringTrait) = LineString
geointerface_geomtype(::GeoInterface.MultiLineStringTrait) = MultiLineString
geointerface_geomtype(::GeoInterface.PolygonTrait) = Polygon
geointerface_geomtype(::GeoInterface.MultiPolygonTrait) = MultiPolygon
geointerface_geomtype(::GeoInterface.PolyhedralSurfaceTrait) = Mesh

GeoInterface.geomtrait(::Simplex{Dim,T,1}) where {Dim,T} = PointTrait()
GeoInterface.geomtrait(::Simplex{Dim,T,2}) where {Dim,T} = LineStringTrait()
GeoInterface.geomtrait(::Simplex{Dim,T,3}) where {Dim,T} = PolygonTrait()

GeoInterface.ncoord(::PointTrait, g::Point) = length(g)
GeoInterface.getcoord(::PointTrait, g::Point, i::Int) = g[i]

GeoInterface.ngeom(::LineTrait, g::Line) = length(g)
GeoInterface.getgeom(::LineTrait, g::Line, i::Int) = g[i]

GeoInterface.ngeom(::LineStringTrait, g::LineString) = length(g) + 1 # n line segments + 1
GeoInterface.ncoord(::LineStringTrait, g::LineString{Dim}) where {Dim} = Dim
function GeoInterface.getgeom(::LineStringTrait, g::LineString, i::Int)
return GeometryBasics.coordinates(g)[i]
end

GeoInterface.ngeom(::PolygonTrait, g::Polygon) = length(g.interiors) + 1 # +1 for exterior
function GeoInterface.getgeom(::PolygonTrait,
g::Polygon,
i::Int)::typeof(g.exterior)
return i > 1 ? g.interiors[i - 1] : g.exterior
end

GeoInterface.ngeom(::MultiPointTrait, g::MultiPoint) = length(g)
GeoInterface.getgeom(::MultiPointTrait, g::MultiPoint, i::Int) = g[i]

function GeoInterface.ngeom(::MultiLineStringTrait, g::MultiLineString)
return length(g)
end
function GeoInterface.getgeom(::MultiLineStringTrait, g::MultiLineString, i::Int)
return g[i]
end
GeoInterface.ncoord(::MultiLineStringTrait, g::MultiLineString{Dim}) where {Dim} = Dim

GeoInterface.ngeom(::MultiPolygonTrait, g::MultiPolygon) = length(g)
GeoInterface.getgeom(::MultiPolygonTrait, g::MultiPolygon, i::Int) = g[i]

function GeoInterface.ncoord(::AbstractGeometryTrait,
::Simplex{Dim,T,N,P}) where {Dim,T,N,P}
return Dim
end
function GeoInterface.ncoord(::AbstractGeometryTrait,
::AbstractGeometry{Dim,T}) where {Dim,T}
return Dim
end
function GeoInterface.ngeom(::AbstractGeometryTrait,
::Simplex{Dim,T,N,P}) where {Dim,T,N,P}
return N
end
GeoInterface.ngeom(::PolygonTrait, ::Ngon) = 1 # can't have any holes
GeoInterface.getgeom(::PolygonTrait, g::Ngon, _) = LineString(g.points)

function GeoInterface.ncoord(::PolyhedralSurfaceTrait,
::Mesh{Dim,T,E,V} where {Dim,T,E,V})
return Dim
end
GeoInterface.ngeom(::PolyhedralSurfaceTrait, g::AbstractMesh) = length(g)
GeoInterface.getgeom(::PolyhedralSurfaceTrait, g::AbstractMesh, i) = g[i]

function GeoInterface.convert(::Type{Point}, type::PointTrait, geom)
x, y = GeoInterface.x(geom), GeoInterface.y(geom)
if GeoInterface.is3d(geom)
z = GeoInterface.z(geom)
T = promote_type(typeof(x), typeof(y), typeof(z))
return Point{3,T}(x, y, z)
else
GeoInterface.x(geom), GeoInterface.y(geom)
T = promote_type(typeof(x), typeof(y))
return Point{2,T}(x, y)
end
end

function GeoInterface.convert(::Type{LineString}, type::LineStringTrait, geom)
g1 = getgeom(geom, 1)
x, y = GeoInterface.x(g1), GeoInterface.y(g1)
if GeoInterface.is3d(geom)
z = GeoInterface.z(g1)
T = promote_type(typeof(x), typeof(y), typeof(z))
return LineString([Point{3,T}(GeoInterface.x(p), GeoInterface.y(p), GeoInterface.z(p)) for p in getgeom(geom)])
else
T = promote_type(typeof(x), typeof(y))
return LineString([Point{2,T}(GeoInterface.x(p), GeoInterface.y(p)) for p in getgeom(geom)])
end
end

function GeoInterface.convert(::Type{Polygon}, type::PolygonTrait, geom)
t = LineStringTrait()
exterior = GeoInterface.convert(LineString, t, GeoInterface.getexterior(geom))
if GeoInterface.nhole(geom) == 0
return Polygon(exterior)
else
interiors = map(h -> GeoInterface.convert(LineString, t, h), GeoInterface.gethole(geom))
return Polygon(exterior, interiors)
end
end

function GeoInterface.convert(::Type{MultiPoint}, type::MultiPointTrait, geom)
g1 = getgeom(geom, 1)
x, y = GeoInterface.x(g1), GeoInterface.y(g1)
if GeoInterface.is3d(geom)
z = GeoInterface.z(g1)
T = promote_type(typeof(x), typeof(y), typeof(z))
return MultiPoint([Point{3,T}(GeoInterface.x(p), GeoInterface.y(p), GeoInterface.z(p)) for p in getgeom(geom)])
else
T = promote_type(typeof(x), typeof(y))
return MultiPoint([Point{2,T}(GeoInterface.x(p), GeoInterface.y(p)) for p in getgeom(geom)])
end
end

function GeoInterface.convert(::Type{MultiLineString}, type::MultiLineStringTrait, geom)
t = LineStringTrait()
return MultiLineString(map(l -> GeoInterface.convert(LineString, t, l), getgeom(geom)))
end

function GeoInterface.convert(::Type{MultiPolygon}, type::MultiPolygonTrait, geom)
t = PolygonTrait()
return MultiPolygon(map(poly -> GeoInterface.convert(Polygon, t, poly), getgeom(geom)))
end

function Extents.extent(rect::Rect2)
(xmin, ymin), (xmax, ymax) = extrema(rect)
return Extents.Extent(X=(xmin, xmax), Y=(ymin, ymax))
end
# This is a stub definition of `geointerface_geomtype` for GeometryBasics
# There are no actual methods defined here.
# All the implementation is in `ext/GeometryBasicsGeoInterfaceExt.jl`
function geointerface_geomtype end