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

Wrap all GEOS() results in GI wrappers #216

Merged
merged 5 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
4 changes: 4 additions & 0 deletions ext/GeometryOpsLibGEOSExt/GeometryOpsLibGEOSExt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ for name in filter(!in((:var"#eval", :eval, :var"#include", :include)), names(Ge
@eval using GeometryOps: $name
end

function _wrap(geom; crs=GI.crs(geom), calc_extent = true)
return GI.geointerface_geomtype(GI.geomtrait(geom))(geom; crs, extent = GI.extent(geom, calc_extent))
end

include("buffer.jl")
include("segmentize.jl")
include("simplify.jl")
Expand Down
7 changes: 4 additions & 3 deletions ext/GeometryOpsLibGEOSExt/buffer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,17 @@ to_join_style(style::Symbol) = _GEOS_JOINSTYLE_LOOKUP[style]
to_join_style(style::LG.GEOSBufJoinStyles) = style
to_join_style(num::Integer) = num

function GO.buffer(alg::GEOS, geometry, distance)
function GO.buffer(alg::GEOS, geometry, distance; calc_extent = true, kwargs...)
# The reason we use apply here is so that this also works with featurecollections,
# tables, vectors of geometries, etc!
return apply(TraitTarget{GI.AbstractGeometryTrait}(), geometry) do geom
LG.bufferWithStyle(
return apply(TraitTarget{GI.AbstractGeometryTrait}(), geometry; kwargs...) do geom
newgeom = LG.bufferWithStyle(
GI.convert(LG, geom), distance;
quadsegs = get(alg, :quadsegs, 8),
endCapStyle = to_cap_style(get(alg, :endCapStyle, :round)),
joinStyle = to_join_style(get(alg, :joinStyle, :round)),
mitreLimit = get(alg, :mitreLimit, 5.0),
)
return _wrap(newgeom; crs = GI.crs(geom), calc_extent)
end
end
9 changes: 8 additions & 1 deletion ext/GeometryOpsLibGEOSExt/segmentize.jl
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,20 @@ end

_segmentize_geos(geom, max_distance) = _segmentize_geos(GI.convert(LG, geom), max_distance)

function _wrap_and_segmentize_geos(geom, max_distance)
_wrap(_segmentize_geos(geom, max_distance); crs = GI.crs(geom), calc_extent = false)
end

# 2 behaviours:
# - enforce: enforce the presence of a kwargs
# - fetch: fetch the value of a kwargs, or return a default value
@inline function GO.segmentize(alg::GEOS, geom; threaded::Union{Bool, GO.BoolsAsTypes} = _False())
max_distance = enforce(alg, :max_distance, GO.segmentize)
return GO.apply(
Base.Fix2(_segmentize_geos, max_distance),
Base.Fix2(_wrap_and_segmentize_geos, max_distance),
# TODO: should this just be a target on GI.AbstractGeometryTrait()?
# But Geos doesn't support eg RectangleTrait
# Maybe we need an abstract trait `GI.AbstractWKBGeomTrait`?
GO.TraitTarget(GI.GeometryCollectionTrait(), GI.MultiPolygonTrait(), GI.PolygonTrait(), GI.MultiLineStringTrait(), GI.LineStringTrait(), GI.LinearRingTrait(), GI.MultiPointTrait(), GI.PointTrait()),
geom;
threaded
Expand Down
36 changes: 20 additions & 16 deletions ext/GeometryOpsLibGEOSExt/simple_overrides.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@
=#
# ## Polygon set operations
# ### Difference
function GO.difference(::GEOS, geom_a, geom_b; target=nothing)
return LG.difference(GI.convert(LG, geom_a), GI.convert(LG, geom_b))
function GO.difference(::GEOS, geom_a, geom_b; target=nothing, calc_extent = false)
return _wrap(LG.difference(GI.convert(LG, geom_a), GI.convert(LG, geom_b)); crs = GI.crs(geom_a), calc_extent)
end
# ### Union
function GO.union(::GEOS, geom_a, geom_b; target=nothing)
return LG.union(GI.convert(LG, geom_a), GI.convert(LG, geom_b))
function GO.union(::GEOS, geom_a, geom_b; target=nothing, calc_extent = false)
return _wrap(LG.union(GI.convert(LG, geom_a), GI.convert(LG, geom_b)); crs = GI.crs(geom_a), calc_extent)
end
# ### Intersection
function GO.intersection(::GEOS, geom_a, geom_b; target=nothing)
return LG.intersection(GI.convert(LG, geom_a), GI.convert(LG, geom_b))
function GO.intersection(::GEOS, geom_a, geom_b; target=nothing, calc_extent = false)
return _wrap(LG.intersection(GI.convert(LG, geom_a), GI.convert(LG, geom_b)); crs = GI.crs(geom_a), calc_extent)
end
# ### Symmetric difference
function GO.symdifference(::GEOS, geom_a, geom_b; target=nothing)
return LG.symmetric_difference(GI.convert(LG, geom_a), GI.convert(LG, geom_b))
function GO.symdifference(::GEOS, geom_a, geom_b; target=nothing, calc_extent = false)
return _wrap(LG.symmetric_difference(GI.convert(LG, geom_a), GI.convert(LG, geom_b)); crs = GI.crs(geom_a), calc_extent)

Check warning on line 22 in ext/GeometryOpsLibGEOSExt/simple_overrides.jl

View check run for this annotation

Codecov / codecov/patch

ext/GeometryOpsLibGEOSExt/simple_overrides.jl#L21-L22

Added lines #L21 - L22 were not covered by tests
end

# ## DE-9IM boolean methods
Expand Down Expand Up @@ -66,15 +66,19 @@

# ## Convex hull
function GO.convex_hull(::GEOS, geoms)
return LG.convexhull(
LG.MultiPoint(
collect(
GO.flatten(
x -> GI.convert(LG, x),
GI.PointTrait,
geoms
return _wrap(
asinghvi17 marked this conversation as resolved.
Show resolved Hide resolved
LG.convexhull(
LG.MultiPoint(
collect(
GO.flatten(
x -> GI.convert(LG, x),
asinghvi17 marked this conversation as resolved.
Show resolved Hide resolved
GI.PointTrait,
geoms
)
)
)
)
);
crs = GI.crs(geoms),
calc_extent = false
)
end
Loading