Skip to content
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

Move the GeoInterface.jl code to an extension #212

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 <[email protected]>"]
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

Check warning on line 10 in ext/GeometryBasicsGeoInterfaceExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryBasicsGeoInterfaceExt.jl#L9-L10

Added lines #L9 - L10 were not covered by tests
GeoInterface.isgeometry(::Type{<:AbstractPoint}) = true
GeoInterface.isgeometry(::Type{<:AbstractMesh}) = true

Check warning on line 12 in ext/GeometryBasicsGeoInterfaceExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryBasicsGeoInterfaceExt.jl#L12

Added line #L12 was not covered by tests
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

Check warning on line 33 in ext/GeometryBasicsGeoInterfaceExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryBasicsGeoInterfaceExt.jl#L33

Added line #L33 was not covered by tests
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

Check warning on line 38 in ext/GeometryBasicsGeoInterfaceExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryBasicsGeoInterfaceExt.jl#L38

Added line #L38 was not covered by tests

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()

Check warning on line 42 in ext/GeometryBasicsGeoInterfaceExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryBasicsGeoInterfaceExt.jl#L40-L42

Added lines #L40 - L42 were not covered by tests

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,

Check warning on line 77 in ext/GeometryBasicsGeoInterfaceExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryBasicsGeoInterfaceExt.jl#L77

Added line #L77 was not covered by tests
::Simplex{Dim,T,N,P}) where {Dim,T,N,P}
return Dim

Check warning on line 79 in ext/GeometryBasicsGeoInterfaceExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryBasicsGeoInterfaceExt.jl#L79

Added line #L79 was not covered by tests
end
function GeoInterface.ncoord(::AbstractGeometryTrait,

Check warning on line 81 in ext/GeometryBasicsGeoInterfaceExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryBasicsGeoInterfaceExt.jl#L81

Added line #L81 was not covered by tests
::AbstractGeometry{Dim,T}) where {Dim,T}
return Dim

Check warning on line 83 in ext/GeometryBasicsGeoInterfaceExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryBasicsGeoInterfaceExt.jl#L83

Added line #L83 was not covered by tests
end
function GeoInterface.ngeom(::AbstractGeometryTrait,

Check warning on line 85 in ext/GeometryBasicsGeoInterfaceExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryBasicsGeoInterfaceExt.jl#L85

Added line #L85 was not covered by tests
::Simplex{Dim,T,N,P}) where {Dim,T,N,P}
return N

Check warning on line 87 in ext/GeometryBasicsGeoInterfaceExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryBasicsGeoInterfaceExt.jl#L87

Added line #L87 was not covered by tests
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,

Check warning on line 92 in ext/GeometryBasicsGeoInterfaceExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryBasicsGeoInterfaceExt.jl#L92

Added line #L92 was not covered by tests
::Mesh{Dim,T,E,V} where {Dim,T,E,V})
return Dim

Check warning on line 94 in ext/GeometryBasicsGeoInterfaceExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryBasicsGeoInterfaceExt.jl#L94

Added line #L94 was not covered by tests
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)])

Check warning on line 118 in ext/GeometryBasicsGeoInterfaceExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryBasicsGeoInterfaceExt.jl#L116-L118

Added lines #L116 - L118 were not covered by tests
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)])

Check warning on line 142 in ext/GeometryBasicsGeoInterfaceExt.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryBasicsGeoInterfaceExt.jl#L140-L142

Added lines #L140 - L142 were not covered by tests
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
Loading