Geometry Corrections
export fixThis file simply defines the GeometryCorrection abstract type, and the interface that any GeometryCorrection must implement.
A geometry correction is a transformation that is applied to a geometry to correct it in some way.
For example, a ClosedRing correction might be applied to a Polygon to ensure that its exterior ring is closed.
Interface
All GeometryCorrections are callable structs which, when called, apply the correction to the given geometry, and return either a copy or the original geometry (if nothing needed to be corrected).
See below for the full interface specification.
GeometryOps.GeometryCorrection Type
abstract type GeometryCorrectionThis abstract type represents a geometry correction.
Interface
Any GeometryCorrection must implement two functions: * application_level(::GeometryCorrection)::AbstractGeometryTrait: This function should return the GeoInterface trait that the correction is intended to be applied to, like PointTrait or LineStringTrait or PolygonTrait. * (::GeometryCorrection)(::AbstractGeometryTrait, geometry)::(some_geometry): This function should apply the correction to the given geometry, and return a new geometry.
Any geometry correction must implement the interface as given above.
"""
abstract type GeometryCorrection
This abstract type represents a geometry correction.
# Interface
Any `GeometryCorrection` must implement two functions:
* `application_level(::GeometryCorrection)::AbstractGeometryTrait`: This function should return the `GeoInterface` trait that the correction is intended to be applied to, like `PointTrait` or `LineStringTrait` or `PolygonTrait`.
* `(::GeometryCorrection)(::AbstractGeometryTrait, geometry)::(some_geometry)`: This function should apply the correction to the given geometry, and return a new geometry.
"""
abstract type GeometryCorrection end
application_level(gc::GeometryCorrection) = error("Not implemented yet for $(gc)")
(gc::GeometryCorrection)(geometry) = gc(GI.trait(geometry), geometry)
(gc::GeometryCorrection)(trait::GI.AbstractGeometryTrait, geometry) = error("Not implemented yet for $(gc) and $(trait).")
function fix(geometry; corrections = GeometryCorrection[ClosedRing(),], kwargs...)
traits = application_level.(corrections)
final_geometry = geometry
for Trait in (GI.PointTrait, GI.MultiPointTrait, GI.LineStringTrait, GI.LinearRingTrait, GI.MultiLineStringTrait, GI.PolygonTrait, GI.MultiPolygonTrait)
available_corrections = findall(x -> x == Trait, traits)
isempty(available_corrections) && continue
@debug "Correcting for $(Trait)"
net_function = reduce(∘, corrections[available_corrections])
final_geometry = apply(WithTrait(net_function), TraitTarget(Trait), final_geometry; kwargs...)
end
return final_geometry
endAvailable corrections
GeometryOps.AntipodalEdgeSplit Type
AntipodalEdgeSplit() <: GeometryCorrectionSplit every edge whose endpoints map to exactly-antipodal unit vectors by inserting the lon/lat midpoint of the edge, so each edge has a well-defined great-circle arc. This is the remedy for the antipodal-edge ArgumentError thrown by relate on the Spherical manifold.
It can be called on any geometry as usual (AntipodalEdgeSplit()(geom)), or passed to GeometryOps.fix.
See also GeometryCorrection.
GeometryOps.ClosedRing Type
ClosedRing() <: GeometryCorrectionThis correction ensures that a polygon's exterior and interior rings are closed.
It can be called on any geometry correction as usual.
See also GeometryCorrection.
GeometryOps.CrossingEdgeSplit Type
CrossingEdgeSplit() <: GeometryCorrectionSplit every polygon ring at the points where two of its non-adjacent edges cross properly as great-circle arcs, reassembling the resulting loops as separate rings (even-odd semantics: both lobes of a figure-eight are kept, matching S2Builder's undirected split_crossing_edges repair). A polygon whose shell splits becomes a MultiPolygon; when it carries holes, each (likewise repaired) hole loop is assigned to the shell loop that contains it. This is the remedy for the ring-crossing ArgumentError thrown by prepare on the Spherical manifold.
Crossing points are constructed in Float64 (lon/lat of the exact crossing direction) — corrections construct geometry; they don't decide predicates — the same standard as AntipodalEdgeSplit's midpoint insertion.
Scope
The correction handles isolated pairwise crossings — the needle and bowtie class, where no edge participates in more than one crossing and no two crossings interleave around the ring. Rings with tangled multi-crossing topology beyond that throw an ArgumentError rather than emitting wrong geometry. Vertex touches (rings meeting at a point) are valid and are not split.
It can be called on any polygonal geometry as usual (CrossingEdgeSplit()(geom)), or passed to GeometryOps.fix. Because a split changes the geometry type (Polygon → MultiPolygon), apply it directly to MultiPolygon inputs rather than through fix's per-polygon traversal.
See also GeometryCorrection, AntipodalEdgeSplit.
GeometryOps.DiffIntersectingPolygons Type
DiffIntersectingPolygons() <: GeometryCorrectionThis correction ensures that the polygons included in a multipolygon aren't intersecting. If any polygon's are intersecting, they will be made nonintersecting through the difference operation to create a unique set of disjoint (other than potentially connections by a single point) polygons covering the same area. See also GeometryCorrection, UnionIntersectingPolygons.
GeometryOps.GeometryCorrection Type
abstract type GeometryCorrectionThis abstract type represents a geometry correction.
Interface
Any GeometryCorrection must implement two functions: * application_level(::GeometryCorrection)::AbstractGeometryTrait: This function should return the GeoInterface trait that the correction is intended to be applied to, like PointTrait or LineStringTrait or PolygonTrait. * (::GeometryCorrection)(::AbstractGeometryTrait, geometry)::(some_geometry): This function should apply the correction to the given geometry, and return a new geometry.
GeometryOps.UnionIntersectingPolygons Type
UnionIntersectingPolygons() <: GeometryCorrectionThis correction ensures that the polygon's included in a multipolygon aren't intersecting. If any polygon's are intersecting, they will be combined through the union operation to create a unique set of disjoint (other than potentially connections by a single point) polygons covering the same area.
See also GeometryCorrection.
This page was generated using Literate.jl.