Full GeometryOps API documentation
Warning
This page is still very much WIP!
Documentation for GeometryOps's full API (only for reference!).
GeometryOps.GEOMETRYOPS_NO_OPTIMIZE_EDGEINTERSECT_NUMVERTSGeometryOpsCore.WGS84_EARTH_INV_FLATTENINGGeometryOpsCore.WGS84_EARTH_MEAN_RADIUSGeometryOpsCore.WGS84_EARTH_SEMI_MAJOR_RADIUSGeometryOps.AbstractBarycentricCoordinateMethodGeometryOps.AutoAcceleratorGeometryOps.CLibraryPlanarAlgorithmGeometryOps.ChaikinGeometryOps.ClosedRingGeometryOps.DiffIntersectingPolygonsGeometryOps.DouglasPeuckerGeometryOps.FosterHormannClippingGeometryOps.GEOSGeometryOps.GeodesicSegmentsGeometryOps.GeometryCorrectionGeometryOps.IntersectionAcceleratorGeometryOps.LineOrientationGeometryOps.LinearSegmentsGeometryOps.MeanValueGeometryOps.MonotoneChainMethodGeometryOps.PROJGeometryOps.PointOrientationGeometryOps.RadialDistanceGeometryOps.SimplifyAlgGeometryOps.TGGeometryOps.TracingErrorGeometryOps.UnionIntersectingPolygonsGeometryOps.VisvalingamWhyattGeometryOps._VecTypesGeometryOpsCore.AlgorithmGeometryOpsCore.ApplicatorGeometryOpsCore.ApplyToArrayGeometryOpsCore.ApplyToFeaturesGeometryOpsCore.ApplyToGeomGeometryOpsCore.AutoAlgorithmGeometryOpsCore.AutoManifoldGeometryOpsCore.BoolsAsTypesGeometryOpsCore.FalseGeometryOpsCore.GeodesicGeometryOpsCore.ManifoldGeometryOpsCore.ManifoldIndependentAlgorithmGeometryOpsCore.MissingKeywordInAlgorithmExceptionGeometryOpsCore.NoAlgorithmGeometryOpsCore.OperationGeometryOpsCore.PlanarGeometryOpsCore.SingleManifoldAlgorithmGeometryOpsCore.SphericalGeometryOpsCore.TaskFunctorsGeometryOpsCore.TraitTargetGeometryOpsCore.TrueGeometryOpsCore.WithTraitGeometryOpsCore.WrongManifoldExceptionGeometryOps._detGeometryOps._equals_curvesGeometryOps.anglesGeometryOps.anglesGeometryOps.areaGeometryOps.areaGeometryOps.centroidGeometryOps.centroidGeometryOps.centroid_and_areaGeometryOps.centroid_and_lengthGeometryOps.containsGeometryOps.containsGeometryOps.containsGeometryOps.convex_hullGeometryOps.coverageGeometryOps.coveredbyGeometryOps.coveredbyGeometryOps.coveredbyGeometryOps.coversGeometryOps.coversGeometryOps.coversGeometryOps.crossesGeometryOps.crossesGeometryOps.crossesGeometryOps.cutGeometryOps.differenceGeometryOps.disjointGeometryOps.disjointGeometryOps.disjointGeometryOps.distanceGeometryOps.distanceGeometryOps.eachedgeGeometryOps.edge_extentsGeometryOps.embed_extentGeometryOps.embed_extentGeometryOps.enforceGeometryOps.equalsGeometryOps.equalsGeometryOps.equalsGeometryOps.equalsGeometryOps.equalsGeometryOps.equalsGeometryOps.equalsGeometryOps.equalsGeometryOps.equalsGeometryOps.equalsGeometryOps.equalsGeometryOps.equalsGeometryOps.equalsGeometryOps.equalsGeometryOps.equalsGeometryOps.equalsGeometryOps.extent_to_polygonGeometryOps.flipGeometryOps.forcexyGeometryOps.forcexyzGeometryOps.foreach_pair_of_maybe_intersecting_edges_in_orderGeometryOps.intersectionGeometryOps.intersection_pointsGeometryOps.intersectsGeometryOps.intersectsGeometryOps.intersectsGeometryOps.isclockwiseGeometryOps.isconcaveGeometryOps.lazy_edge_extentsGeometryOps.lazy_edgelistGeometryOps.overlapsGeometryOps.overlapsGeometryOps.overlapsGeometryOps.overlapsGeometryOps.overlapsGeometryOps.overlapsGeometryOps.overlapsGeometryOps.overlapsGeometryOps.overlapsGeometryOps.overlapsGeometryOps.overlapsGeometryOps.polygon_to_lineGeometryOps.polygonizeGeometryOps.reprojectGeometryOps.segmentizeGeometryOps.signed_areaGeometryOps.signed_areaGeometryOps.signed_distanceGeometryOps.signed_distanceGeometryOps.simplifyGeometryOps.smoothGeometryOps.t_valueGeometryOps.to_edgelistGeometryOps.to_edgelistGeometryOps.to_edgesGeometryOps.touchesGeometryOps.touchesGeometryOps.touchesGeometryOps.transformGeometryOps.transformGeometryOps.tuplesGeometryOps.unionGeometryOps.weighted_meanGeometryOps.withinGeometryOps.withinGeometryOps.withinGeometryOpsCore.applyGeometryOpsCore.applyGeometryOpsCore.applyreduceGeometryOpsCore.applyreduceGeometryOpsCore.best_manifoldGeometryOpsCore.booltypeGeometryOpsCore.flattenGeometryOpsCore.manifoldGeometryOpsCore.rebuildGeometryOpsCore.reconstructGeometryOpsCore.reconstruct_tableGeometryOpsCore.unwrapGeometryOpsCore.used_reconstruct_table_kwargs
apply and associated functions
GeometryOpsCore.apply Function
apply(f, target::Union{TraitTarget, GI.AbstractTrait}, obj; kw...)Reconstruct a geometry, feature, feature collection, or nested vectors of either using the function f on the target trait.
f(target_geom) => x where x also has the target trait, or a trait that can be substituted. For example, swapping PolgonTrait to MultiPointTrait will fail if the outer object has MultiPolygonTrait, but should work if it has FeatureTrait.
Objects "shallower" than the target trait are always completely rebuilt, like a Vector of FeatureCollectionTrait of FeatureTrait when the target has PolygonTrait and is held in the features. These will always be GeoInterface geometries/feature/feature collections. But "deeper" objects may remain unchanged or be whatever GeoInterface compatible objects f returns.
The result is a functionally similar geometry with values depending on f.
threaded:trueorfalse. Whether to use multithreading. Defaults tofalse.crs: The CRS to attach to geometries. Defaults tonothing.calc_extent:trueorfalse. Whether to calculate the extent. Defaults tofalse.
Example
Flipped point the order in any feature or geometry, or iterables of either:
import GeoInterface as GI
import GeometryOps as GO
geom = GI.Polygon([GI.LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]),
GI.LinearRing([(3, 4), (5, 6), (6, 7), (3, 4)])])
flipped_geom = GO.apply(GI.PointTrait, geom) do p
(GI.y(p), GI.x(p))
endGeometryOpsCore.applyreduce Function
applyreduce(f, op, target::Union{TraitTarget, GI.AbstractTrait}, obj; threaded, init, kw...)Apply function f to all objects with the target trait, and reduce the result with an op like +.
The order and grouping of application of op is not guaranteed.
If threaded==true threads will be used over arrays and iterables, feature collections and nested geometries.
init functions the same way as it does in base Julia functions like reduce.
GeometryOps.reproject Function
reproject(geometry; source_crs, target_crs, transform, always_xy, time)
reproject(geometry, source_crs, target_crs; always_xy, time)
reproject(geometry, transform; always_xy, time)Reproject any GeoInterface.jl compatible geometry from source_crs to target_crs.
The returned object will be constructed from GeoInterface wrapper geometries, wrapping Vector{NTuple{D, Float64}}, where D is the dimension.
Tip
The Proj.jl package must be loaded for this method to work, since it is implemented in a package extension.
Arguments
geometry: Any GeoInterface.jl compatible geometries.source_crs: the source coordinate reference system, as a GeoFormatTypes.jl object or a string.target_crs: the target coordinate reference system, as a GeoFormatTypes.jl object or a string.
If these a passed as keywords, transform will take priority. Without it target_crs is always needed, and source_crs is needed if it is not retrievable from the geometry with GeoInterface.crs(geometry).
Keywords
always_xy: force x, y coordinate order,trueby default.falsewill expect and return points in the crs coordinate order.time: the time for the coordinates.Infby default.threaded:trueorfalse. Whether to use multithreading. Defaults tofalse.crs: The CRS to attach to geometries. Defaults tonothing.calc_extent:trueorfalse. Whether to calculate the extent. Defaults tofalse.
GeometryOps.transform Function
transform(f, obj)Apply a function f to all the points in obj.
Points will be passed to f as an SVector to allow using CoordinateTransformations.jl and Rotations.jl without hassle.
SVector is also a valid GeoInterface.jl point, so will work in all GeoInterface.jl methods.
Example
julia> import GeoInterface as GI
julia> import GeometryOps as GO
julia> geom = GI.Polygon([GI.LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]), GI.LinearRing([(3, 4), (5, 6), (6, 7), (3, 4)])]);
julia> f = CoordinateTransformations.Translation(3.5, 1.5)
Translation(3.5, 1.5)
julia> GO.transform(f, geom)
GeoInterface.Wrappers.Polygon{false, false, Vector{GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Float64}}, Nothing, Nothing}}, Nothing, Nothing}(GeoInterface.Wrappers.Linea
rRing{false, false, Vector{StaticArraysCore.SVector{2, Float64}}, Nothing, Nothing}[GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Float64}}, Nothing, Nothing}(StaticArraysCo
re.SVector{2, Float64}[[4.5, 3.5], [6.5, 5.5], [8.5, 7.5], [4.5, 3.5]], nothing, nothing), GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Float64}}, Nothing, Nothing}(StaticA
rraysCore.SVector{2, Float64}[[6.5, 5.5], [8.5, 7.5], [9.5, 8.5], [6.5, 5.5]], nothing, nothing)], nothing, nothing)With Rotations.jl you need to actually multiply the Rotation by the SVector point, which is easy using an anonymous function.
julia> using Rotations
julia> GO.transform(p -> one(RotMatrix{2}) * p, geom)
GeoInterface.Wrappers.Polygon{false, false, Vector{GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Int64}}, Nothing, Nothing}}, Nothing, Nothing}(GeoInterface.Wrappers.LinearR
ing{false, false, Vector{StaticArraysCore.SVector{2, Int64}}, Nothing, Nothing}[GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Int64}}, Nothing, Nothing}(StaticArraysCore.SVe
ctor{2, Int64}[[2, 1], [4, 3], [6, 5], [2, 1]], nothing, nothing), GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Int64}}, Nothing, Nothing}(StaticArraysCore.SVector{2, Int64
}[[4, 3], [6, 5], [7, 6], [4, 3]], nothing, nothing)], nothing, nothing)General geometry methods
OGC methods
GeometryOps.contains Function
contains(g1::AbstractGeometry, g2::AbstractGeometry)::BoolReturn true if the second geometry is completely contained by the first geometry. The interiors of both geometries must intersect and the interior and boundary of the secondary (g2) must not intersect the exterior of the first (g1).
contains returns the exact opposite result of within.
Examples
import GeometryOps as GO, GeoInterface as GI
line = GI.LineString([(1, 1), (1, 2), (1, 3), (1, 4)])
point = GI.Point((1, 2))
GO.contains(line, point)
# output
truecontains(g1)Return a function that checks if its input contains g1. This is equivalent to x -> contains(x, g1).
GeometryOps.coveredby Function
coveredby(g1, g2)::BoolReturn true if the first geometry is completely covered by the second geometry. The interior and boundary of the primary geometry (g1) must not intersect the exterior of the secondary geometry (g2).
Furthermore, coveredby returns the exact opposite result of covers. They are equivalent with the order of the arguments swapped.
Examples
import GeometryOps as GO, GeoInterface as GI
p1 = GI.Point(0.0, 0.0)
p2 = GI.Point(1.0, 1.0)
l1 = GI.Line([p1, p2])
GO.coveredby(p1, l1)
# output
truecoveredby(g1)Return a function that checks if its input is covered by g1. This is equivalent to x -> coveredby(x, g1).
GeometryOps.covers Function
covers(g1::AbstractGeometry, g2::AbstractGeometry)::BoolReturn true if the first geometry is completely covers the second geometry, The exterior and boundary of the second geometry must not be outside of the interior and boundary of the first geometry. However, the interiors need not intersect.
covers returns the exact opposite result of coveredby.
Examples
import GeometryOps as GO, GeoInterface as GI
l1 = GI.LineString([(1.0, 1.0), (1.0, 2.0), (1.0, 3.0), (1.0, 4.0)])
l2 = GI.LineString([(1.0, 1.0), (1.0, 2.0)])
GO.covers(l1, l2)
# output
truecovers(g1)Return a function that checks if its input covers g1. This is equivalent to x -> covers(x, g1).
GeometryOps.crosses Function
crosses(geom1, geom2)::BoolReturn true if the intersection results in a geometry whose dimension is one less than the maximum dimension of the two source geometries and the intersection set is interior to both source geometries.
TODO: broken
Examples
import GeoInterface as GI, GeometryOps as GO
# TODO: Add working examplecrosses(g1)Return a function that checks if its input crosses g1. This is equivalent to x -> crosses(x, g1).
GeometryOps.disjoint Function
disjoint(geom1, geom2)::BoolReturn true if the first geometry is disjoint from the second geometry.
Return true if the first geometry is disjoint from the second geometry. The interiors and boundaries of both geometries must not intersect.
Examples
import GeometryOps as GO, GeoInterface as GI
line = GI.LineString([(1, 1), (1, 2), (1, 3), (1, 4)])
point = (2, 2)
GO.disjoint(point, line)
# output
truedisjoint(g1)Return a function that checks if its input is disjoint from g1. This is equivalent to x -> disjoint(x, g1).
GeometryOps.intersects Function
intersects(geom1, geom2)::BoolReturn true if the interiors or boundaries of the two geometries interact.
intersects returns the exact opposite result of disjoint.
Example
import GeoInterface as GI, GeometryOps as GO
line1 = GI.Line([(124.584961,-12.768946), (126.738281,-17.224758)])
line2 = GI.Line([(123.354492,-15.961329), (127.22168,-14.008696)])
GO.intersects(line1, line2)
# output
trueintersects(g1)Return a function that checks if its input intersects g1. This is equivalent to x -> intersects(x, g1).
GeometryOps.overlaps Function
overlaps(geom1, geom2)::BoolCompare two Geometries of the same dimension and return true if their intersection set results in a geometry different from both but of the same dimension. This means one geometry cannot be within or contain the other and they cannot be equal
Examples
import GeometryOps as GO, GeoInterface as GI
poly1 = GI.Polygon([[(0,0), (0,5), (5,5), (5,0), (0,0)]])
poly2 = GI.Polygon([[(1,1), (1,6), (6,6), (6,1), (1,1)]])
GO.overlaps(poly1, poly2)
# output
trueoverlaps(g1)Return a function that checks if its input overlaps g1. This is equivalent to x -> overlaps(x, g1).
overlaps(::GI.AbstractTrait, geom1, ::GI.AbstractTrait, geom2)::BoolFor any non-specified pair, all have non-matching dimensions, return false.
sourceoverlaps(
::GI.MultiPointTrait, points1,
::GI.MultiPointTrait, points2,
)::BoolIf the multipoints overlap, meaning some, but not all, of the points within the multipoints are shared, return true.
sourceoverlaps(::GI.LineTrait, line1, ::GI.LineTrait, line)::BoolIf the lines overlap, meaning that they are collinear but each have one endpoint outside of the other line, return true. Else false.
sourceoverlaps(
::Union{GI.LineStringTrait, GI.LinearRing}, line1,
::Union{GI.LineStringTrait, GI.LinearRing}, line2,
)::BoolIf the curves overlap, meaning that at least one edge of each curve overlaps, return true. Else false.
sourceoverlaps(
trait_a::GI.PolygonTrait, poly_a,
trait_b::GI.PolygonTrait, poly_b,
)::BoolIf the two polygons intersect with one another, but are not equal, return true. Else false.
sourceoverlaps(
::GI.PolygonTrait, poly1,
::GI.MultiPolygonTrait, polys2,
)::BoolReturn true if polygon overlaps with at least one of the polygons within the multipolygon. Else false.
sourceoverlaps(
::GI.MultiPolygonTrait, polys1,
::GI.PolygonTrait, poly2,
)::BoolReturn true if polygon overlaps with at least one of the polygons within the multipolygon. Else false.
sourceoverlaps(
::GI.MultiPolygonTrait, polys1,
::GI.MultiPolygonTrait, polys2,
)::BoolReturn true if at least one pair of polygons from multipolygons overlap. Else false.
sourceGeometryOps.touches Function
touches(geom1, geom2)::BoolReturn true if the first geometry touches the second geometry. In other words, the two interiors cannot interact, but one of the geometries must have a boundary point that interacts with either the other geometry's interior or boundary.
Examples
import GeometryOps as GO, GeoInterface as GI
l1 = GI.Line([(0.0, 0.0), (1.0, 0.0)])
l2 = GI.Line([(1.0, 1.0), (1.0, -1.0)])
GO.touches(l1, l2)
# output
truetouches(g1)Return a function that checks if its input touches g1. This is equivalent to x -> touches(x, g1).
GeometryOps.within Function
within(geom1, geom2)::BoolReturn true if the first geometry is completely within the second geometry. The interiors of both geometries must intersect and the interior and boundary of the primary geometry (geom1) must not intersect the exterior of the secondary geometry (geom2).
Furthermore, within returns the exact opposite result of contains.
Examples
import GeometryOps as GO, GeoInterface as GI
line = GI.LineString([(1, 1), (1, 2), (1, 3), (1, 4)])
point = (1, 2)
GO.within(point, line)
# output
truewithin(g1)Return a function that checks if its input is within g1. This is equivalent to x -> within(x, g1).
Other general methods
GeometryOps.equals Function
equals(geom1, geom2)::BoolCompare two Geometries return true if they are the same geometry.
Examples
import GeometryOps as GO, GeoInterface as GI
poly1 = GI.Polygon([[(0,0), (0,5), (5,5), (5,0), (0,0)]])
poly2 = GI.Polygon([[(0,0), (0,5), (5,5), (5,0), (0,0)]])
GO.equals(poly1, poly2)
# output
trueequals(::T, geom_a, ::T, geom_b)::BoolTwo geometries of the same type, which don't have a equals function to dispatch off of should throw an error.
sourceequals(trait_a, geom_a, trait_b, geom_b)Two geometries which are not of the same type cannot be equal so they always return false.
sourceequals(::GI.PointTrait, p1, ::GI.PointTrait, p2)::BoolTwo points are the same if they have the same x and y (and z if 3D) coordinates.
sourceequals(::GI.PointTrait, p1, ::GI.MultiPointTrait, mp2)::BoolA point and a multipoint are equal if the multipoint is composed of a single point that is equivalent to the given point.
sourceequals(::GI.MultiPointTrait, mp1, ::GI.PointTrait, p2)::BoolA point and a multipoint are equal if the multipoint is composed of a single point that is equivalent to the given point.
sourceequals(::GI.MultiPointTrait, mp1, ::GI.MultiPointTrait, mp2)::BoolTwo multipoints are equal if they share the same set of points.
sourceequals(
::Union{GI.LineTrait, GI.LineStringTrait}, l1,
::Union{GI.LineTrait, GI.LineStringTrait}, l2,
)::BoolTwo lines/linestrings are equal if they share the same set of points going along the curve. Note that lines/linestrings aren't closed by definition.
sourceequals(
::Union{GI.LineTrait, GI.LineStringTrait}, l1,
::GI.LinearRingTrait, l2,
)::BoolA line/linestring and a linear ring are equal if they share the same set of points going along the curve. Note that lines aren't closed by definition, but rings are, so the line must have a repeated last point to be equal
sourceequals(
::GI.LinearRingTrait, l1,
::Union{GI.LineTrait, GI.LineStringTrait}, l2,
)::BoolA linear ring and a line/linestring are equal if they share the same set of points going along the curve. Note that lines aren't closed by definition, but rings are, so the line must have a repeated last point to be equal
sourceequals(
::GI.LinearRingTrait, l1,
::GI.LinearRingTrait, l2,
)::BoolTwo linear rings are equal if they share the same set of points going along the curve. Note that rings are closed by definition, so they can have, but don't need, a repeated last point to be equal.
sourceequals(::GI.PolygonTrait, geom_a, ::GI.PolygonTrait, geom_b)::BoolTwo polygons are equal if they share the same exterior edge and holes.
sourceequals(::GI.PolygonTrait, geom_a, ::GI.MultiPolygonTrait, geom_b)::BoolA polygon and a multipolygon are equal if the multipolygon is composed of a single polygon that is equivalent to the given polygon.
sourceequals(::GI.MultiPolygonTrait, geom_a, ::GI.PolygonTrait, geom_b)::BoolA polygon and a multipolygon are equal if the multipolygon is composed of a single polygon that is equivalent to the given polygon.
sourceequals(::GI.PolygonTrait, geom_a, ::GI.PolygonTrait, geom_b)::BoolTwo multipolygons are equal if they share the same set of polygons.
sourceGeometryOps.centroid Function
centroid(geom, [T=Float64])::Tuple{T, T}Returns the centroid of a given line segment, linear ring, polygon, or mutlipolygon.
sourceGeometryOps.distance Function
distance(point, geom, ::Type{T} = Float64)::TCalculates the ditance from the geometry g1 to the point. The distance will always be positive or zero.
The method will differ based on the type of the geometry provided: - The distance from a point to a point is just the Euclidean distance between the points. - The distance from a point to a line is the minimum distance from the point to the closest point on the given line. - The distance from a point to a linestring is the minimum distance from the point to the closest segment of the linestring. - The distance from a point to a linear ring is the minimum distance from the point to the closest segment of the linear ring. - The distance from a point to a polygon is zero if the point is within the polygon and otherwise is the minimum distance from the point to an edge of the polygon. This includes edges created by holes. - The distance from a point to a multigeometry or a geometry collection is the minimum distance between the point and any of the sub-geometries.
Result will be of type T, where T is an optional argument with a default value of Float64.
sourceGeometryOps.signed_distance Function
signed_distance(point, geom, ::Type{T} = Float64)::TCalculates the signed distance from the geometry geom to the given point. Points within geom have a negative signed distance, and points outside of geom have a positive signed distance. - The signed distance from a point to a point, line, linestring, or linear ring is equal to the distance between the two. - The signed distance from a point to a polygon is negative if the point is within the polygon and is positive otherwise. The value of the distance is the minimum distance from the point to an edge of the polygon. This includes edges created by holes. - The signed distance from a point to a multigeometry or a geometry collection is the minimum signed distance between the point and any of the sub-geometries.
Result will be of type T, where T is an optional argument with a default value of Float64.
sourceGeometryOps.area Function
area(geom, [T = Float64])::TReturns the area of a geometry or collection of geometries. This is computed slightly differently for different geometries:
- The area of a point/multipoint is always zero.
- The area of a curve/multicurve is always zero.
- The area of a polygon is the absolute value of the signed area.
- The area multi-polygon is the sum of the areas of all of the sub-polygons.
- The area of a geometry collection, feature collection of array/iterable
is the sum of the areas of all of the sub-geometries.Result will be of type T, where T is an optional argument with a default value of Float64.
sourceGeometryOps.signed_area Function
signed_area(geom, [T = Float64])::TReturns the signed area of a single geometry, based on winding order. This is computed slightly differently for different geometries:
- The signed area of a point is always zero.
- The signed area of a curve is always zero.
- The signed area of a polygon is computed with the shoelace formula and is
positive if the polygon coordinates wind clockwise and negative if
counterclockwise.
- You cannot compute the signed area of a multipolygon as it doesn't have a
meaning as each sub-polygon could have a different winding order.Result will be of type T, where T is an optional argument with a default value of Float64.
sourceGeometryOps.angles Function
angles(geom, ::Type{T} = Float64)Returns the angles of a geometry or collection of geometries. This is computed differently for different geometries:
- The angles of a point is an empty vector.
- The angles of a single line segment is an empty vector.
- The angles of a linestring or linearring is a vector of angles formed by the curve.
- The angles of a polygon is a vector of vectors of angles formed by each ring.
- The angles of a multi-geometry collection is a vector of the angles of each of the
sub-geometries as defined above.Result will be a Vector, or nested set of vectors, of type T where an optional argument with a default value of Float64.
sourceGeometryOps.embed_extent Function
embed_extent(obj)Recursively wrap the object with a GeoInterface.jl geometry, calculating and adding an Extents.Extent to all objects.
This can improve performance when extents need to be checked multiple times, such when needing to check if many points are in geometries, and using their extents as a quick filter for obviously exterior points.
Keywords
threaded:trueorfalse. Whether to use multithreading. Defaults tofalse.crs: The CRS to attach to geometries. Defaults tonothing.
Barycentric coordinates
Missing docstring.
Missing docstring for barycentric_coordinates. Check Documenter's build log for details.
Missing docstring.
Missing docstring for barycentric_coordinates!. Check Documenter's build log for details.
Missing docstring.
Missing docstring for barycentric_interpolate. Check Documenter's build log for details.
Other methods
GeometryOps.GEOMETRYOPS_NO_OPTIMIZE_EDGEINTERSECT_NUMVERTS Constant
The number of vertices past which we should use a STRtree for edge intersection checking.
sourceGeometryOps.AbstractBarycentricCoordinateMethod Type
abstract type AbstractBarycentricCoordinateMethodAbstract supertype for barycentric coordinate methods. The subtypes may serve as dispatch types, or may cache some information about the target polygon.
API
The following methods must be implemented for all subtypes:
barycentric_coordinates!(λs::Vector{<: Real}, method::AbstractBarycentricCoordinateMethod, exterior::Vector{<: Point{2, T1}}, point::Point{2, T2})barycentric_interpolate(method::AbstractBarycentricCoordinateMethod, exterior::Vector{<: Point{2, T1}}, values::Vector{V}, point::Point{2, T2})::Vbarycentric_interpolate(method::AbstractBarycentricCoordinateMethod, exterior::Vector{<: Point{2, T1}}, interiors::Vector{<: Vector{<: Point{2, T1}}} values::Vector{V}, point::Point{2, T2})::V
The rest of the methods will be implemented in terms of these, and have efficient dispatches for broadcasting.
sourceGeometryOps.AutoAccelerator Type
AutoAccelerator()Let the algorithm choose the best accelerator based on the size of the input polygons.
Once we have prepared geometry, this will also consider the existing preparations on the geoms.
sourceGeometryOps.CLibraryPlanarAlgorithm Type
abstract type CLibraryPlanarAlgorithm <: GeometryOpsCore.SingleManifoldAlgorithm{Planar} endThis is a type which extends GeometryOpsCore.SingleManifoldAlgorithm{Planar}, and is used as an abstract supertype for some C library based algorithms.
The type requires that algorithm structs be arranged as:
struct MyAlgorithm <: CLibraryPlanarAlgorithm
manifold::Planar
params::NamedTuple
endThen you get a nice constructor for free, as well as the get(alg, key, value) and get(alg, key) do ... syntax. Plus the enforce method, which will check that given keyword arguments are present.
GeometryOps.Chaikin Type
Chaikin(; iterations=1, manifold=Planar())Smooths geometries using Chaikin's corner-cutting algorithm [1]. This algorithm "slices" off every corner of the geometry to smooth it out, equivalent to a sequence of quadratic Bezier curves.
Keywords
iterations: the number of times to apply the algorithm.manifold: theManifoldto smooth the geometry on. Currently,PlanarandSphericalare supported.
Extended help
The algorithm is very simple; for each corner of the line (a -> b -> c), insert two new points and remove b, such that a -> b -> c becomes a -> q -> r -> c, where q and r are the new points such that:
In practice the replacement happens on the level of each edge.
References
sourceGeometryOps.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.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.DouglasPeucker Type
DouglasPeucker <: SimplifyAlg
DouglasPeucker(; number, ratio, tol)Simplifies geometries by removing points below tol distance from the line between its neighboring points.
Keywords
ratio: the fraction of points that should remain aftersimplify. Useful as it will generalise for large collections of objects.number: the number of points that should remain aftersimplify. Less useful for large collections of mixed size objects.tol: the minimum distance a point will be from the line joining its neighboring points.
Note: user input tol is squared to avoid unnecessary computation in algorithm.
GeometryOps.FosterHormannClipping Type
FosterHormannClipping{M <: Manifold, A <: Union{Nothing, Accelerator}} <: GeometryOpsCore.Algorithm{M}Applies the Foster-Hormann clipping algorithm.
Arguments
manifold::M: The manifold on which the algorithm operates.accelerator::A: The accelerator to use for the algorithm. Can benothingfor automatic choice, or a custom accelerator.
GeometryOps.GEOS Type
GEOS(; params...)A struct which instructs the method it's passed to as an algorithm to use the appropriate GEOS function via LibGEOS.jl for the operation.
Dispatch is generally carried out using the names of the keyword arguments. For example, segmentize will only accept a GEOS struct with only a max_distance keyword, and no other.
It's generally somewhat slower than the native Julia implementations, since it must convert to the LibGEOS implementation and back - so be warned!
Extended help
This uses the LibGEOS.jl package, which is a Julia wrapper around the C library GEOS (https://trac.osgeo.org/geos).
sourceGeometryOps.GeodesicSegments Type
GeodesicSegments(; max_distance::Real, equatorial_radius::Real=6378137, flattening::Real=1/298.257223563)Warning
This is deprecated - call segmentize(Geodesic(; semimajor_axis, inv_flattening), geom; max_distance) instead.
A method for segmentizing geometries by adding extra vertices to the geometry so that no segment is longer than a given distance. This method calculates the distance between points on the geodesic, and assumes input in lat/long coordinates.
Warning
Any input geometries must be in lon/lat coordinates! If not, the method may fail or error.
Arguments
max_distance::Real: The maximum distance, in meters, between vertices in the geometry.equatorial_radius::Real=6378137: The equatorial radius of the Earth, in meters. Passed toProj.geod_geodesic.flattening::Real=1/298.257223563: The flattening of the Earth, which is the ratio of the difference between the equatorial and polar radii to the equatorial radius. Passed toProj.geod_geodesic.
One can also omit the equatorial_radius and flattening keyword arguments, and pass a geodesic object directly to the eponymous keyword.
This method uses the Proj/GeographicLib API for geodesic calculations.
sourceGeometryOps.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.IntersectionAccelerator Type
abstract type IntersectionAcceleratorThe abstract supertype for all intersection accelerator types.
The idea is that these speed up the edge-edge intersection checking process, perhaps at the cost of memory.
The naive case is NestedLoop, which is just a nested loop, running in O(n*m) time.
Then we have SingleSTRtree, which is a single STRtree, running in O(n*log(m)) time.
Then we have DoubleSTRtree, which is a simultaneous double-tree traversal of two STRtrees.
Finally, we have AutoAccelerator, which chooses the best accelerator based on the size of the input polygons. This gets materialized in build_a_list for now. AutoAccelerator should also try to respect existing spatial indices, if they exist.
GeometryOps.LineOrientation Type
Enum LineOrientationEnum for the orientation of a line with respect to a curve. A line can be line_cross (crossing over the curve), line_hinge (crossing the endpoint of the curve), line_over (collinear with the curve), or line_out (not interacting with the curve).
GeometryOps.LinearSegments Type
LinearSegments(; max_distance::Real)Warning
This is deprecated - call segmentize(Planar(), geom; max_distance) instead.
A method for segmentizing geometries by adding extra vertices to the geometry so that no segment is longer than a given distance.
Here, max_distance is a purely nondimensional quantity and will apply in the input space. This is to say, that if the polygon is provided in lat/lon coordinates then the max_distance will be in degrees of arc. If the polygon is provided in meters, then the max_distance will be in meters.
GeometryOps.MeanValue Type
MeanValue() <: AbstractBarycentricCoordinateMethodThis method calculates barycentric coordinates using the mean value method.
References
sourceGeometryOps.MonotoneChainMethod Type
MonotoneChainMethod()This is an algorithm for the convex_hull function.
Uses DelaunayTriangulation.jl to compute the convex hull. This is a pure Julia algorithm which provides an optimal Delaunay triangulation.
See also convex_hull
GeometryOps.PROJ Type
PROJ(; params...)A struct which instructs the method it's passed to as an algorithm to use the appropriate PROJ function via Proj.jl for the operation.
Extended help
This is the default algorithm for reproject, and will also be the default algorithm for operations on geodesics like area and arclength.
GeometryOps.PointOrientation Type
Enum PointOrientationEnum for the orientation of a point with respect to a curve. A point can be point_in the curve, point_on the curve, or point_out of the curve.
GeometryOps.RadialDistance Type
RadialDistance <: SimplifyAlgSimplifies geometries by removing points less than tol distance from the line between its neighboring points.
Keywords
ratio: the fraction of points that should remain aftersimplify. Useful as it will generalise for large collections of objects.number: the number of points that should remain aftersimplify. Less useful for large collections of mixed size objects.tol: the minimum distance between points.
Note: user input tol is squared to avoid unnecessary computation in algorithm.
GeometryOps.SimplifyAlg Type
abstract type SimplifyAlgAbstract type for simplification algorithms.
API
For now, the algorithm must hold the number, ratio and tol properties.
Simplification algorithm types can hook into the interface by implementing the _simplify(trait, alg, geom) methods for whichever traits are necessary.
GeometryOps.TG Type
TG(; params...)A struct which instructs the method it's passed to as an algorithm to use the appropriate TG function via TGGeometry.jl for the operation.
It's generally a lot faster than the native Julia implementations, but only supports planar manifolds / operations. Also, it only supports geometric predicates, specifically the ones which the underlying tg library supports. These are:
equals, intersects, disjoint, contains, within, covers, coveredby, and touches.
Extended help
This uses the TGGeometry.jl package, which is a Julia wrapper around the tg C library (https://github.com/tidwall/tg).
GeometryOps.TracingError Type
TracingError{T1, T2} <: ExceptionAn error that is thrown when the clipping tracing algorithm fails somehow. This is a bug in the algorithm, and should be reported.
The polygons are contained in the exception object, accessible by try-catch or as err in the REPL.
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.
GeometryOps.VisvalingamWhyatt Type
VisvalingamWhyatt <: SimplifyAlg
VisvalingamWhyatt(; kw...)Simplifies geometries by removing points below tol distance from the line between its neighboring points.
Keywords
ratio: the fraction of points that should remain aftersimplify. Useful as it will generalise for large collections of objects.number: the number of points that should remain aftersimplify. Less useful for large collections of mixed size objects.tol: the minimum area of a triangle made with a point and its neighboring points.
Note: user input tol is doubled to avoid unnecessary computation in algorithm.
GeometryOps._det Method
_det(s1::Point2{T1}, s2::Point2{T2}) where {T1 <: Real, T2 <: Real}Returns the determinant of the matrix formed by hcat'ing two points s1 and s2.
Specifically, this is:
s1[1] * s2[2] - s1[2] * s2[1]GeometryOps._equals_curves Method
_equals_curves(c1, c2, closed_type1, closed_type2)::BoolTwo curves are equal if they share the same set of point, representing the same geometry. Both curves must must be composed of the same set of points, however, they do not have to wind in the same direction, or start on the same point to be equivalent. Inputs: c1 first geometry c2 second geometry closed_type1::Bool true if c1 is closed by definition (polygon, linear ring) closed_type2::Bool true if c2 is closed by definition (polygon, linear ring)
sourceGeometryOps.angles Method
angles(geom, ::Type{T} = Float64)Returns the angles of a geometry or collection of geometries. This is computed differently for different geometries:
- The angles of a point is an empty vector.
- The angles of a single line segment is an empty vector.
- The angles of a linestring or linearring is a vector of angles formed by the curve.
- The angles of a polygon is a vector of vectors of angles formed by each ring.
- The angles of a multi-geometry collection is a vector of the angles of each of the
sub-geometries as defined above.Result will be a Vector, or nested set of vectors, of type T where an optional argument with a default value of Float64.
sourceGeometryOps.area Method
area(geom, [T = Float64])::TReturns the area of a geometry or collection of geometries. This is computed slightly differently for different geometries:
- The area of a point/multipoint is always zero.
- The area of a curve/multicurve is always zero.
- The area of a polygon is the absolute value of the signed area.
- The area multi-polygon is the sum of the areas of all of the sub-polygons.
- The area of a geometry collection, feature collection of array/iterable
is the sum of the areas of all of the sub-geometries.Result will be of type T, where T is an optional argument with a default value of Float64.
sourceGeometryOps.centroid Method
centroid(geom, [T=Float64])::Tuple{T, T}Returns the centroid of a given line segment, linear ring, polygon, or mutlipolygon.
sourceGeometryOps.centroid_and_area Method
centroid_and_area(geom, [T=Float64])::(::Tuple{T, T}, ::Real)Returns the centroid and area of a given geometry.
sourceGeometryOps.centroid_and_length Method
centroid_and_length(geom, [T=Float64])::(::Tuple{T, T}, ::Real)Returns the centroid and length of a given line/ring. Note this is only valid for line strings and linear rings.
sourceGeometryOps.contains Method
contains(g1::AbstractGeometry, g2::AbstractGeometry)::BoolReturn true if the second geometry is completely contained by the first geometry. The interiors of both geometries must intersect and the interior and boundary of the secondary (g2) must not intersect the exterior of the first (g1).
contains returns the exact opposite result of within.
Examples
import GeometryOps as GO, GeoInterface as GI
line = GI.LineString([(1, 1), (1, 2), (1, 3), (1, 4)])
point = GI.Point((1, 2))
GO.contains(line, point)
# output
trueGeometryOps.contains Method
contains(g1)Return a function that checks if its input contains g1. This is equivalent to x -> contains(x, g1).
GeometryOps.convex_hull Function
convex_hull([method], geometries)Compute the convex hull of the points in geometries. Returns a GI.Polygon representing the convex hull.
Note that the polygon returned is wound counterclockwise as in the Simple Features standard by default. If you choose GEOS, the winding order will be inverted.
Warning
This interface only computes the 2-dimensional convex hull!
For higher dimensional hulls, use the relevant package (Qhull.jl, Quickhull.jl, or similar).
GeometryOps.coverage Method
coverage(geom, xmin, xmax, ymin, ymax, [T = Float64])::TReturns the area of intersection between given geometry and grid cell defined by its minimum and maximum x and y-values. This is computed differently for different geometries:
The signed area of a point is always zero.
The signed area of a curve is always zero.
The signed area of a polygon is calculated by tracing along its edges and switching to the cell edges if needed.
The coverage of a geometry collection, multi-geometry, feature collection of array/iterable is the sum of the coverages of all of the sub-geometries.
Result will be of type T, where T is an optional argument with a default value of Float64.
sourceGeometryOps.coveredby Method
coveredby(g1, g2)::BoolReturn true if the first geometry is completely covered by the second geometry. The interior and boundary of the primary geometry (g1) must not intersect the exterior of the secondary geometry (g2).
Furthermore, coveredby returns the exact opposite result of covers. They are equivalent with the order of the arguments swapped.
Examples
import GeometryOps as GO, GeoInterface as GI
p1 = GI.Point(0.0, 0.0)
p2 = GI.Point(1.0, 1.0)
l1 = GI.Line([p1, p2])
GO.coveredby(p1, l1)
# output
trueGeometryOps.coveredby Method
coveredby(g1)Return a function that checks if its input is covered by g1. This is equivalent to x -> coveredby(x, g1).
GeometryOps.covers Method
covers(g1::AbstractGeometry, g2::AbstractGeometry)::BoolReturn true if the first geometry is completely covers the second geometry, The exterior and boundary of the second geometry must not be outside of the interior and boundary of the first geometry. However, the interiors need not intersect.
covers returns the exact opposite result of coveredby.
Examples
import GeometryOps as GO, GeoInterface as GI
l1 = GI.LineString([(1.0, 1.0), (1.0, 2.0), (1.0, 3.0), (1.0, 4.0)])
l2 = GI.LineString([(1.0, 1.0), (1.0, 2.0)])
GO.covers(l1, l2)
# output
trueGeometryOps.covers Method
covers(g1)Return a function that checks if its input covers g1. This is equivalent to x -> covers(x, g1).
GeometryOps.crosses Method
crosses(geom1, geom2)::BoolReturn true if the intersection results in a geometry whose dimension is one less than the maximum dimension of the two source geometries and the intersection set is interior to both source geometries.
TODO: broken
Examples
import GeoInterface as GI, GeometryOps as GO
# TODO: Add working exampleGeometryOps.crosses Method
crosses(g1)Return a function that checks if its input crosses g1. This is equivalent to x -> crosses(x, g1).
GeometryOps.cut Method
cut(geom, line, [T::Type])Return given geom cut by given line as a list of geometries of the same type as the input geom. Return the original geometry as only list element if none are found. Line must cut fully through given geometry or the original geometry will be returned.
Note: This currently doesn't work for degenerate cases there line crosses through vertices.
Example
import GeoInterface as GI, GeometryOps as GO
poly = GI.Polygon([[(0.0, 0.0), (10.0, 0.0), (10.0, 10.0), (0.0, 10.0), (0.0, 0.0)]])
line = GI.Line([(5.0, -5.0), (5.0, 15.0)])
cut_polys = GO.cut(poly, line)
GI.coordinates.(cut_polys)
# output
2-element Vector{Vector{Vector{Vector{Float64}}}}:
[[[0.0, 0.0], [5.0, 0.0], [5.0, 10.0], [0.0, 10.0], [0.0, 0.0]]]
[[[5.0, 0.0], [10.0, 0.0], [10.0, 10.0], [5.0, 10.0], [5.0, 0.0]]]GeometryOps.difference Method
difference(geom_a, geom_b, [T::Type]; target::Type, fix_multipoly = UnionIntersectingPolygons())Return the difference between two geometries as a list of geometries. Return an empty list if none are found. The type of the list will be constrained as much as possible given the input geometries. Furthermore, the user can provide a taget type as a keyword argument and a list of target geometries found in the difference will be returned. The user can also provide a float type that they would like the points of returned geometries to be. If the user is taking a intersection involving one or more multipolygons, and the multipolygon might be comprised of polygons that intersect, if fix_multipoly is set to an IntersectingPolygons correction (the default is UnionIntersectingPolygons()), then the needed multipolygons will be fixed to be valid before performing the intersection to ensure a correct answer. Only set fix_multipoly to false if you know that the multipolygons are valid, as it will avoid unneeded computation.
Example
import GeoInterface as GI, GeometryOps as GO
poly1 = GI.Polygon([[[0.0, 0.0], [5.0, 5.0], [10.0, 0.0], [5.0, -5.0], [0.0, 0.0]]])
poly2 = GI.Polygon([[[3.0, 0.0], [8.0, 5.0], [13.0, 0.0], [8.0, -5.0], [3.0, 0.0]]])
diff_poly = GO.difference(poly1, poly2; target = GI.PolygonTrait())
GI.coordinates.(diff_poly)
# output
1-element Vector{Vector{Vector{Vector{Float64}}}}:
[[[6.5, 3.5], [5.0, 5.0], [0.0, 0.0], [5.0, -5.0], [6.5, -3.5], [3.0, 0.0], [6.5, 3.5]]]GeometryOps.disjoint Method
disjoint(geom1, geom2)::BoolReturn true if the first geometry is disjoint from the second geometry.
Return true if the first geometry is disjoint from the second geometry. The interiors and boundaries of both geometries must not intersect.
Examples
import GeometryOps as GO, GeoInterface as GI
line = GI.LineString([(1, 1), (1, 2), (1, 3), (1, 4)])
point = (2, 2)
GO.disjoint(point, line)
# output
trueGeometryOps.disjoint Method
disjoint(g1)Return a function that checks if its input is disjoint from g1. This is equivalent to x -> disjoint(x, g1).
GeometryOps.distance Method
distance(point, geom, ::Type{T} = Float64)::TCalculates the ditance from the geometry g1 to the point. The distance will always be positive or zero.
The method will differ based on the type of the geometry provided: - The distance from a point to a point is just the Euclidean distance between the points. - The distance from a point to a line is the minimum distance from the point to the closest point on the given line. - The distance from a point to a linestring is the minimum distance from the point to the closest segment of the linestring. - The distance from a point to a linear ring is the minimum distance from the point to the closest segment of the linear ring. - The distance from a point to a polygon is zero if the point is within the polygon and otherwise is the minimum distance from the point to an edge of the polygon. This includes edges created by holes. - The distance from a point to a multigeometry or a geometry collection is the minimum distance between the point and any of the sub-geometries.
Result will be of type T, where T is an optional argument with a default value of Float64.
sourceGeometryOps.eachedge Method
eachedge(geom, [::Type{T}])Decompose a geometry into a list of edges. Currently only works for LineString and LinearRing.
Returns some iterator, which yields tuples of points. Each tuple is an edge.
It goes (p1, p2), (p2, p3), (p3, p4), ... etc.
GeometryOps.edge_extents Method
edge_extents(geom, [::Type{T}])Return a vector of the extents of the edges (line segments) of geom.
GeometryOps.embed_extent Method
embed_extent(obj)Recursively wrap the object with a GeoInterface.jl geometry, calculating and adding an Extents.Extent to all objects.
This can improve performance when extents need to be checked multiple times, such when needing to check if many points are in geometries, and using their extents as a quick filter for obviously exterior points.
Keywords
threaded:trueorfalse. Whether to use multithreading. Defaults tofalse.crs: The CRS to attach to geometries. Defaults tonothing.
GeometryOps.enforce Method
enforce(alg::CLibraryPlanarAlgorithm, kw::Symbol, f)Enforce the presence of a keyword argument in a GEOS algorithm, and return alg.params[kw].
Throws an error if the key is not present, and mentions f in the error message (since there isn't a good way to get the name of the function that called this method).
This applies to all CLibraryPlanarAlgorithm types, like GEOS and TG.
GeometryOps.equals Method
equals(trait_a, geom_a, trait_b, geom_b)Two geometries which are not of the same type cannot be equal so they always return false.
sourceGeometryOps.equals Method
equals(geom1, geom2)::BoolCompare two Geometries return true if they are the same geometry.
Examples
import GeometryOps as GO, GeoInterface as GI
poly1 = GI.Polygon([[(0,0), (0,5), (5,5), (5,0), (0,0)]])
poly2 = GI.Polygon([[(0,0), (0,5), (5,5), (5,0), (0,0)]])
GO.equals(poly1, poly2)
# output
trueGeometryOps.equals Method
equals(
::GI.LinearRingTrait, l1,
::GI.LinearRingTrait, l2,
)::BoolTwo linear rings are equal if they share the same set of points going along the curve. Note that rings are closed by definition, so they can have, but don't need, a repeated last point to be equal.
sourceGeometryOps.equals Method
equals(
::GI.LinearRingTrait, l1,
::Union{GI.LineTrait, GI.LineStringTrait}, l2,
)::BoolA linear ring and a line/linestring are equal if they share the same set of points going along the curve. Note that lines aren't closed by definition, but rings are, so the line must have a repeated last point to be equal
sourceGeometryOps.equals Method
equals(::GI.MultiPointTrait, mp1, ::GI.MultiPointTrait, mp2)::BoolTwo multipoints are equal if they share the same set of points.
sourceGeometryOps.equals Method
equals(::GI.MultiPointTrait, mp1, ::GI.PointTrait, p2)::BoolA point and a multipoint are equal if the multipoint is composed of a single point that is equivalent to the given point.
sourceGeometryOps.equals Method
equals(::GI.PolygonTrait, geom_a, ::GI.PolygonTrait, geom_b)::BoolTwo multipolygons are equal if they share the same set of polygons.
sourceGeometryOps.equals Method
equals(::GI.MultiPolygonTrait, geom_a, ::GI.PolygonTrait, geom_b)::BoolA polygon and a multipolygon are equal if the multipolygon is composed of a single polygon that is equivalent to the given polygon.
sourceGeometryOps.equals Method
equals(::GI.PointTrait, p1, ::GI.MultiPointTrait, mp2)::BoolA point and a multipoint are equal if the multipoint is composed of a single point that is equivalent to the given point.
sourceGeometryOps.equals Method
equals(::GI.PointTrait, p1, ::GI.PointTrait, p2)::BoolTwo points are the same if they have the same x and y (and z if 3D) coordinates.
sourceGeometryOps.equals Method
equals(::GI.PolygonTrait, geom_a, ::GI.MultiPolygonTrait, geom_b)::BoolA polygon and a multipolygon are equal if the multipolygon is composed of a single polygon that is equivalent to the given polygon.
sourceGeometryOps.equals Method
equals(::GI.PolygonTrait, geom_a, ::GI.PolygonTrait, geom_b)::BoolTwo polygons are equal if they share the same exterior edge and holes.
sourceGeometryOps.equals Method
equals(
::Union{GI.LineTrait, GI.LineStringTrait}, l1,
::GI.LinearRingTrait, l2,
)::BoolA line/linestring and a linear ring are equal if they share the same set of points going along the curve. Note that lines aren't closed by definition, but rings are, so the line must have a repeated last point to be equal
sourceGeometryOps.equals Method
equals(
::Union{GI.LineTrait, GI.LineStringTrait}, l1,
::Union{GI.LineTrait, GI.LineStringTrait}, l2,
)::BoolTwo lines/linestrings are equal if they share the same set of points going along the curve. Note that lines/linestrings aren't closed by definition.
sourceGeometryOps.equals Method
equals(::T, geom_a, ::T, geom_b)::BoolTwo geometries of the same type, which don't have a equals function to dispatch off of should throw an error.
sourceGeometryOps.extent_to_polygon Method
extent_to_polygon(ext::Extents.Extent)Convert an extent to a polygon.
Examples
import GeometryOps as GO, Extents
ext = Extents.Extent(X=(1.0, 2.0), Y=(1.0, 2.0))
GO.extent_to_polygon(ext)
# output
GeoInterface.Wrappers.Polygon{false, false}([GeoInterface.Wrappers.LinearRing([(1.0, 1.0), … (3) … , (1.0, 1.0)])])GeometryOps.flip Method
flip(obj)Swap all of the x and y coordinates in obj, otherwise keeping the original structure (but not necessarily the original type).
Keywords
threaded:trueorfalse. Whether to use multithreading. Defaults tofalse.crs: The CRS to attach to geometries. Defaults tonothing.calc_extent:trueorfalse. Whether to calculate the extent. Defaults tofalse.
GeometryOps.forcexy Method
forcexy(geom)Force the geometry to be 2D. Works on any geometry, vector of geometries, feature collection, or table!
sourceGeometryOps.forcexyz Function
forcexyz(geom, z = 0)Force the geometry to be 3D. Works on any geometry, vector of geometries, feature collection, or table!
The z parameter is the default z value - if a point has no z value, it will be set to this value. If it does, then the z value will be kept.
GeometryOps.foreach_pair_of_maybe_intersecting_edges_in_order Method
foreach_pair_of_maybe_intersecting_edges_in_order(
manifold::M, accelerator::A,
f_on_each_a::FA,
f_after_each_a::FAAfter,
f_on_each_maybe_intersect::FI,
geom_a,
geom_b,
::Type{T} = Float64
) where {FA, FAAfter, FI, T, M <: Manifold, A <: IntersectionAccelerator}Decompose geom_a and geom_b into edge lists (unsorted), and then, logically, perform the following iteration:
for (a_edge, i) in enumerate(eachedge(geom_a))
f_on_each_a(a_edge, i)
for (b_edge, j) in enumerate(eachedge(geom_b))
if may_intersect(a_edge, b_edge)
f_on_each_maybe_intersect(a_edge, b_edge)
end
end
f_after_each_a(a_edge, i)
endThis may not be the exact acceleration that is performed - but it is the logical sequence of events. It also uses the accelerator, and can automatically choose the best one based on an internal heuristic if you pass in an AutoAccelerator.
For example, the SingleSTRtree accelerator is used along with extent thinning to avoid unnecessary edge intersection checks in the inner loop.
GeometryOps.intersection Method
intersection(geom_a, geom_b, [T::Type]; target::Type, fix_multipoly = UnionIntersectingPolygons())Return the intersection between two geometries as a list of geometries. Return an empty list if none are found. The type of the list will be constrained as much as possible given the input geometries. Furthermore, the user can provide a target type as a keyword argument and a list of target geometries found in the intersection will be returned. The user can also provide a float type that they would like the points of returned geometries to be. If the user is taking a intersection involving one or more multipolygons, and the multipolygon might be comprised of polygons that intersect, if fix_multipoly is set to an IntersectingPolygons correction (the default is UnionIntersectingPolygons()), then the needed multipolygons will be fixed to be valid before performing the intersection to ensure a correct answer. Only set fix_multipoly to nothing if you know that the multipolygons are valid, as it will avoid unneeded computation.
Example
import GeoInterface as GI, GeometryOps as GO
line1 = GI.Line([(124.584961,-12.768946), (126.738281,-17.224758)])
line2 = GI.Line([(123.354492,-15.961329), (127.22168,-14.008696)])
inter_points = GO.intersection(line1, line2; target = GI.PointTrait())
GI.coordinates.(inter_points)
# output
1-element Vector{Vector{Float64}}:
[125.58375366067548, -14.83572303404496]GeometryOps.intersection_points Method
intersection_points(geom_a, geom_b, [T::Type])Return a list of intersection tuple points between two geometries. If no intersection points exist, returns an empty list.
Example
line1 = GI.Line([(124.584961,-12.768946), (126.738281,-17.224758)]) line2 = GI.Line([(123.354492,-15.961329), (127.22168,-14.008696)]) inter_points = GO.intersection_points(line1, line2)
**output**
1-element Vector{Tuple{Float64, Float64}}: (125.58375366067548, -14.83572303404496)
<Badge type="info" class="source-link" text="source"><a href="https://github.com/JuliaGeo/GeometryOps.jl/blob/fc8e36d773574981634b0e4f8627ab3fe61adbcf/src/methods/clipping/intersection.jl#L202-L220" target="_blank" rel="noreferrer">source</a></Badge>
</details>
<details class='jldocstring custom-block' open>
<summary><a id='GeometryOps.intersects-Tuple{Any, Any}' href='#GeometryOps.intersects-Tuple{Any, Any}'><span class="jlbinding">GeometryOps.intersects</span></a> <Badge type="info" class="jlObjectType jlMethod" text="Method" /></summary>
```julia
intersects(geom1, geom2)::BoolReturn true if the interiors or boundaries of the two geometries interact.
intersects returns the exact opposite result of disjoint.
Example
import GeoInterface as GI, GeometryOps as GO
line1 = GI.Line([(124.584961,-12.768946), (126.738281,-17.224758)])
line2 = GI.Line([(123.354492,-15.961329), (127.22168,-14.008696)])
GO.intersects(line1, line2)
# output
trueGeometryOps.intersects Method
intersects(g1)Return a function that checks if its input intersects g1. This is equivalent to x -> intersects(x, g1).
GeometryOps.isclockwise Method
isclockwise(line::Union{LineString, Vector{Position}})::BoolTake a ring and return true if the line goes clockwise, or false if the line goes counter-clockwise. "Going clockwise" means, mathematically,
Example
julia> import GeoInterface as GI, GeometryOps as GO
julia> ring = GI.LinearRing([(0, 0), (1, 1), (1, 0), (0, 0)]);
julia> GO.isclockwise(ring)
# output
trueGeometryOps.isconcave Method
isconcave(poly::Polygon)::BoolTake a polygon and return true or false as to whether it is concave or not.
Examples
import GeoInterface as GI, GeometryOps as GO
poly = GI.Polygon([[(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)]])
GO.isconcave(poly)
# output
falseGeometryOps.lazy_edge_extents Method
lazy_edge_extents(geom)Return an iterator over the extents of the edges (line segments) of geom. This is lazy but nonallocating.
GeometryOps.lazy_edgelist Method
lazy_edgelist(geom, [::Type{T}])Return an iterator over GI.Line objects with attached extents.
GeometryOps.overlaps Method
overlaps(geom1, geom2)::BoolCompare two Geometries of the same dimension and return true if their intersection set results in a geometry different from both but of the same dimension. This means one geometry cannot be within or contain the other and they cannot be equal
Examples
import GeometryOps as GO, GeoInterface as GI
poly1 = GI.Polygon([[(0,0), (0,5), (5,5), (5,0), (0,0)]])
poly2 = GI.Polygon([[(1,1), (1,6), (6,6), (6,1), (1,1)]])
GO.overlaps(poly1, poly2)
# output
trueGeometryOps.overlaps Method
overlaps(g1)Return a function that checks if its input overlaps g1. This is equivalent to x -> overlaps(x, g1).
GeometryOps.overlaps Method
overlaps(::GI.AbstractTrait, geom1, ::GI.AbstractTrait, geom2)::BoolFor any non-specified pair, all have non-matching dimensions, return false.
sourceGeometryOps.overlaps Method
overlaps(::GI.LineTrait, line1, ::GI.LineTrait, line)::BoolIf the lines overlap, meaning that they are collinear but each have one endpoint outside of the other line, return true. Else false.
sourceGeometryOps.overlaps Method
overlaps(
::GI.MultiPointTrait, points1,
::GI.MultiPointTrait, points2,
)::BoolIf the multipoints overlap, meaning some, but not all, of the points within the multipoints are shared, return true.
sourceGeometryOps.overlaps Method
overlaps(
::GI.MultiPolygonTrait, polys1,
::GI.MultiPolygonTrait, polys2,
)::BoolReturn true if at least one pair of polygons from multipolygons overlap. Else false.
sourceGeometryOps.overlaps Method
overlaps(
::GI.MultiPolygonTrait, polys1,
::GI.PolygonTrait, poly2,
)::BoolReturn true if polygon overlaps with at least one of the polygons within the multipolygon. Else false.
sourceGeometryOps.overlaps Method
overlaps(
::GI.PolygonTrait, poly1,
::GI.MultiPolygonTrait, polys2,
)::BoolReturn true if polygon overlaps with at least one of the polygons within the multipolygon. Else false.
sourceGeometryOps.overlaps Method
overlaps(
trait_a::GI.PolygonTrait, poly_a,
trait_b::GI.PolygonTrait, poly_b,
)::BoolIf the two polygons intersect with one another, but are not equal, return true. Else false.
sourceGeometryOps.overlaps Method
overlaps(
::Union{GI.LineStringTrait, GI.LinearRing}, line1,
::Union{GI.LineStringTrait, GI.LinearRing}, line2,
)::BoolIf the curves overlap, meaning that at least one edge of each curve overlaps, return true. Else false.
sourceGeometryOps.polygon_to_line Method
polygon_to_line(poly::Polygon)Converts a Polygon to LineString or MultiLineString
Examples
import GeometryOps as GO, GeoInterface as GI
poly = GI.Polygon([[(-2.275543, 53.464547), (-2.275543, 53.489271), (-2.215118, 53.489271), (-2.215118, 53.464547), (-2.275543, 53.464547)]])
GO.polygon_to_line(poly)
# output
GeoInterface.Wrappers.LineString{false, false}([(-2.275543, 53.464547), … (3) … , (-2.275543, 53.464547)])GeometryOps.polygonize Method
polygonize(A::AbstractMatrix{Bool}; kw...)
polygonize(f, A::AbstractMatrix; kw...)
polygonize(xs, ys, A::AbstractMatrix{Bool}; kw...)
polygonize(f, xs, ys, A::AbstractMatrix; kw...)Polygonize an AbstractMatrix of values, currently to a single class of polygons.
Returns a MultiPolygon for Bool values and f return values, and a FeatureCollection of Features holding MultiPolygon for all other values.
Function f should return either true or false or a transformation of values into simpler groups, especially useful for floating point arrays.
If xs and ys are ranges, they are used as the pixel/cell center points. If they are Vector of Tuple they are used as the lower and upper bounds of each pixel/cell.
Keywords
minpoints: ignore polygons with less thanminpointspoints.values: the values to turn into polygons. By default these areunion(A), If functionfis passed these refer to the return values off, by defaultunion(map(f, A). If valuesBool, false is ignored and a singleMultiPolygonis returned rather than aFeatureCollection.
Example
using GeometryOps
A = rand(100, 100)
multipolygon = polygonize(>(0.5), A);GeometryOps.segmentize Method
segmentize([method = Planar()], geom; max_distance::Real, threaded)Segmentize a geometry by adding extra vertices to the geometry so that no segment is longer than a given distance. This is useful for plotting geometries with a limited number of vertices, or for ensuring that a geometry is not too "coarse" for a given application.
Arguments
method::Manifold = Planar(): The method to use for segmentizing the geometry. At the moment, onlyPlanar(assumes a flat plane) andGeodesic(assumes geometry on the ellipsoidal Earth and uses Vincenty's formulae) are available.geom: The geometry to segmentize. Must be aLineString,LinearRing,Polygon,MultiPolygon, orGeometryCollection, or some vector or table of those.max_distance::Real: The maximum distance between vertices in the geometry. Beware: forPlanar, this is in the units of the geometry, but forGeodesicandSphericalit's in units of the radius of the sphere.
Returns a geometry of similar type to the input geometry, but resampled.
sourceGeometryOps.signed_area Method
signed_area(geom, [T = Float64])::TReturns the signed area of a single geometry, based on winding order. This is computed slightly differently for different geometries:
- The signed area of a point is always zero.
- The signed area of a curve is always zero.
- The signed area of a polygon is computed with the shoelace formula and is
positive if the polygon coordinates wind clockwise and negative if
counterclockwise.
- You cannot compute the signed area of a multipolygon as it doesn't have a
meaning as each sub-polygon could have a different winding order.Result will be of type T, where T is an optional argument with a default value of Float64.
sourceGeometryOps.signed_distance Method
signed_distance(point, geom, ::Type{T} = Float64)::TCalculates the signed distance from the geometry geom to the given point. Points within geom have a negative signed distance, and points outside of geom have a positive signed distance. - The signed distance from a point to a point, line, linestring, or linear ring is equal to the distance between the two. - The signed distance from a point to a polygon is negative if the point is within the polygon and is positive otherwise. The value of the distance is the minimum distance from the point to an edge of the polygon. This includes edges created by holes. - The signed distance from a point to a multigeometry or a geometry collection is the minimum signed distance between the point and any of the sub-geometries.
Result will be of type T, where T is an optional argument with a default value of Float64.
sourceGeometryOps.simplify Method
simplify(obj; kw...)
simplify(::SimplifyAlg, obj; kw...)Simplify a geometry, feature, feature collection, or nested vectors or a table of these.
RadialDistance, DouglasPeucker, or VisvalingamWhyatt algorithms are available, listed in order of increasing quality but decreasing performance.
PoinTrait and MultiPointTrait are returned unchanged.
The default behaviour is simplify(DouglasPeucker(; kw...), obj). Pass in other SimplifyAlg to use other algorithms.
Keywords
prefilter_alg:SimplifyAlgalgorithm used to pre-filter object before using primary filtering algorithm.threaded:trueorfalse. Whether to use multithreading. Defaults tofalse.crs: The CRS to attach to geometries. Defaults tonothing.calc_extent:trueorfalse. Whether to calculate the extent. Defaults tofalse.
Keywords for DouglasPeucker are allowed when no algorithm is specified:
Keywords
ratio: the fraction of points that should remain aftersimplify. Useful as it will generalise for large collections of objects.number: the number of points that should remain aftersimplify. Less useful for large collections of mixed size objects.tol: the minimum distance a point will be from the line joining its neighboring points.
Example
Simplify a polygon to have six points:
import GeoInterface as GI
import GeometryOps as GO
poly = GI.Polygon([[
[-70.603637, -33.399918],
[-70.614624, -33.395332],
[-70.639343, -33.392466],
[-70.659942, -33.394759],
[-70.683975, -33.404504],
[-70.697021, -33.419406],
[-70.701141, -33.434306],
[-70.700454, -33.446339],
[-70.694274, -33.458369],
[-70.682601, -33.465816],
[-70.668869, -33.472117],
[-70.646209, -33.473835],
[-70.624923, -33.472117],
[-70.609817, -33.468107],
[-70.595397, -33.458369],
[-70.587158, -33.442901],
[-70.587158, -33.426283],
[-70.590591, -33.414248],
[-70.594711, -33.406224],
[-70.603637, -33.399918]]])
simple = GO.simplify(poly; number=6)
GI.npoint(simple)
# output
6GeometryOps.smooth Method
smooth(alg::Algorithm, geom)
smooth(geom; kw...)Smooths a geometry using the provided algorithm.
The default algorithm is Chaikin(), which can be used on the spherical or planar manifolds.
GeometryOps.t_value Method
t_value(sᵢ, sᵢ₊₁, rᵢ, rᵢ₊₁)Returns the "T-value" as described in Hormann's presentation [2] on how to calculate the mean-value coordinate.
Here, sᵢ is the vector from vertex vᵢ to the point, and rᵢ is the norm (length) of sᵢ. s must be Point and r must be real numbers.
<Badge type="info" class="source-link" text="source"><a href="https://github.com/JuliaGeo/GeometryOps.jl/blob/fc8e36d773574981634b0e4f8627ab3fe61adbcf/src/methods/barycentric.jl#L211-L227" target="_blank" rel="noreferrer">source</a></Badge>
</details>
<details class='jldocstring custom-block' open>
<summary><a id='GeometryOps.to_edgelist-Union{Tuple{Any}, Tuple{T}, Tuple{Any, Type{T}}} where T' href='#GeometryOps.to_edgelist-Union{Tuple{Any}, Tuple{T}, Tuple{Any, Type{T}}} where T'><span class="jlbinding">GeometryOps.to_edgelist</span></a> <Badge type="info" class="jlObjectType jlMethod" text="Method" /></summary>
```julia
to_edgelist(geom, [::Type{T}])Convert a geometry into a vector of GI.Line objects with attached extents.
GeometryOps.to_edgelist Method
to_edgelist(ext::E, geom, [::Type{T}])::(::Vector{GI.Line}, ::Vector{Int})Filter the edges of geom for those that intersect ext, and return:
a vector of
GI.Lineobjects with attached extents,a vector of indices into the original geometry.
GeometryOps.to_edges Method
to_edges()Convert any geometry or collection of geometries into a flat vector of Tuple{Tuple{Float64,Float64},Tuple{Float64,Float64}} edges.
GeometryOps.touches Method
touches(geom1, geom2)::BoolReturn true if the first geometry touches the second geometry. In other words, the two interiors cannot interact, but one of the geometries must have a boundary point that interacts with either the other geometry's interior or boundary.
Examples
import GeometryOps as GO, GeoInterface as GI
l1 = GI.Line([(0.0, 0.0), (1.0, 0.0)])
l2 = GI.Line([(1.0, 1.0), (1.0, -1.0)])
GO.touches(l1, l2)
# output
trueGeometryOps.touches Method
touches(g1)Return a function that checks if its input touches g1. This is equivalent to x -> touches(x, g1).
GeometryOps.transform Method
transform(f, obj)Apply a function f to all the points in obj.
Points will be passed to f as an SVector to allow using CoordinateTransformations.jl and Rotations.jl without hassle.
SVector is also a valid GeoInterface.jl point, so will work in all GeoInterface.jl methods.
Example
julia> import GeoInterface as GI
julia> import GeometryOps as GO
julia> geom = GI.Polygon([GI.LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]), GI.LinearRing([(3, 4), (5, 6), (6, 7), (3, 4)])]);
julia> f = CoordinateTransformations.Translation(3.5, 1.5)
Translation(3.5, 1.5)
julia> GO.transform(f, geom)
GeoInterface.Wrappers.Polygon{false, false, Vector{GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Float64}}, Nothing, Nothing}}, Nothing, Nothing}(GeoInterface.Wrappers.Linea
rRing{false, false, Vector{StaticArraysCore.SVector{2, Float64}}, Nothing, Nothing}[GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Float64}}, Nothing, Nothing}(StaticArraysCo
re.SVector{2, Float64}[[4.5, 3.5], [6.5, 5.5], [8.5, 7.5], [4.5, 3.5]], nothing, nothing), GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Float64}}, Nothing, Nothing}(StaticA
rraysCore.SVector{2, Float64}[[6.5, 5.5], [8.5, 7.5], [9.5, 8.5], [6.5, 5.5]], nothing, nothing)], nothing, nothing)With Rotations.jl you need to actually multiply the Rotation by the SVector point, which is easy using an anonymous function.
julia> using Rotations
julia> GO.transform(p -> one(RotMatrix{2}) * p, geom)
GeoInterface.Wrappers.Polygon{false, false, Vector{GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Int64}}, Nothing, Nothing}}, Nothing, Nothing}(GeoInterface.Wrappers.LinearR
ing{false, false, Vector{StaticArraysCore.SVector{2, Int64}}, Nothing, Nothing}[GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Int64}}, Nothing, Nothing}(StaticArraysCore.SVe
ctor{2, Int64}[[2, 1], [4, 3], [6, 5], [2, 1]], nothing, nothing), GeoInterface.Wrappers.LinearRing{false, false, Vector{StaticArraysCore.SVector{2, Int64}}, Nothing, Nothing}(StaticArraysCore.SVector{2, Int64
}[[4, 3], [6, 5], [7, 6], [4, 3]], nothing, nothing)], nothing, nothing)GeometryOps.tuples Method
tuples(obj)Convert all points in obj to Tuples, wherever the are nested.
Returns a similar object or collection of objects using GeoInterface.jl geometries wrapping Tuple points.
Keywords
threaded:trueorfalse. Whether to use multithreading. Defaults tofalse.crs: The CRS to attach to geometries. Defaults tonothing.calc_extent:trueorfalse. Whether to calculate the extent. Defaults tofalse.
GeometryOps.union Method
union(geom_a, geom_b, [::Type{T}]; target::Type, fix_multipoly = UnionIntersectingPolygons())Return the union between two geometries as a list of geometries. Return an empty list if none are found. The type of the list will be constrained as much as possible given the input geometries. Furthermore, the user can provide a taget type as a keyword argument and a list of target geometries found in the difference will be returned. The user can also provide a float type 'T' that they would like the points of returned geometries to be. If the user is taking a intersection involving one or more multipolygons, and the multipolygon might be comprised of polygons that intersect, if fix_multipoly is set to an IntersectingPolygons correction (the default is UnionIntersectingPolygons()), then the needed multipolygons will be fixed to be valid before performing the intersection to ensure a correct answer. Only set fix_multipoly to false if you know that the multipolygons are valid, as it will avoid unneeded computation.
Calculates the union between two polygons.
Example
import GeoInterface as GI, GeometryOps as GO
p1 = GI.Polygon([[(0.0, 0.0), (5.0, 5.0), (10.0, 0.0), (5.0, -5.0), (0.0, 0.0)]])
p2 = GI.Polygon([[(3.0, 0.0), (8.0, 5.0), (13.0, 0.0), (8.0, -5.0), (3.0, 0.0)]])
union_poly = GO.union(p1, p2; target = GI.PolygonTrait())
GI.coordinates.(union_poly)
# output
1-element Vector{Vector{Vector{Vector{Float64}}}}:
[[[6.5, 3.5], [5.0, 5.0], [0.0, 0.0], [5.0, -5.0], [6.5, -3.5], [8.0, -5.0], [13.0, 0.0], [8.0, 5.0], [6.5, 3.5]]]GeometryOps.weighted_mean Method
weighted_mean(weight::Real, x1, x2)Returns the weighted mean of x1 and x2, where weight is the weight of x1.
Specifically, calculates x1 * weight + x2 * (1 - weight).
Note
The idea for this method is that you can override this for custom types, like Color types, in extension modules.
GeometryOps.within Method
within(geom1, geom2)::BoolReturn true if the first geometry is completely within the second geometry. The interiors of both geometries must intersect and the interior and boundary of the primary geometry (geom1) must not intersect the exterior of the secondary geometry (geom2).
Furthermore, within returns the exact opposite result of contains.
Examples
import GeometryOps as GO, GeoInterface as GI
line = GI.LineString([(1, 1), (1, 2), (1, 3), (1, 4)])
point = (1, 2)
GO.within(point, line)
# output
trueGeometryOps.within Method
within(g1)Return a function that checks if its input is within g1. This is equivalent to x -> within(x, g1).
Core types
GeometryOpsCore.WGS84_EARTH_INV_FLATTENING Constant
The inverse flattening of the WGS84 ellipsoid
sourceGeometryOpsCore.WGS84_EARTH_MEAN_RADIUS Constant
The mean radius of the WGS84 ellipsoid, used for spherical manifold default
sourceGeometryOpsCore.WGS84_EARTH_SEMI_MAJOR_RADIUS Constant
The semi-major axis of the WGS84 ellipsoid
sourceGeometryOpsCore.Algorithm Type
abstract type Algorithm{M <: Manifold}The abstract supertype for all GeometryOps algorithms. These define how to perform a particular Operation.
An algorithm may be associated with one or many Manifolds. It may either have the manifold as a field, or have it as a static parameter (e.g. struct GEOS <: Algorithm{Planar}).
Interface
All Algorithms must implement the following methods:
rebuild(alg, manifold::Manifold)Rebuild algorithmalgwith a new manifold as passed in the second argument. This may error and throw aWrongManifoldExceptionif the manifold is not compatible with that algorithm.manifold(alg::Algorithm)Return the manifold associated with the algorithm.best_manifold(alg::Algorithm, input): Return the best manifold for that algorithm, in the absence of any other context. WARNING: this may change in future and is not stable!
The actual implementation is left to the implementation of that particular Operation.
Notable subtypes
AutoAlgorithm: Tells theOperationreceiving it to automatically select the best algorithm for its input data.ManifoldIndependentAlgorithm: An abstract supertype for an algorithm that works on any manifold. The manifold must be stored in the algorithm for aManifoldIndependentAlgorithm, and accessed viamanifold(alg).SingleManifoldAlgorithm: An abstract supertype for an algorithm that only works on a single manifold, specified in its type parameter.SingleManifoldAlgorithm{Planar}is a special case that does not have to store its manifold, since that doesn't contain any information. All otherSingleManifoldAlgorithms must store their manifold, since they do contain information.NoAlgorithm: A type that indicates no algorithm is to be used, essentially the equivalent ofnothing.
GeometryOpsCore.Applicator Type
abstract type Applicator{F,T}An abstract type for applicators that apply a function to a target object.
The type parameter F is the type of the function to apply, and T is the type of the target object.
A common dispatch pattern is to dispatch on F which may also be e.g. a ThreadFunctor.
Interface
All applicators must be callable by an index integer, and define the following methods:
rebuild(a::Applicator, f)- swap out the function and return a new applicator.
The calling convention is my_applicator(i::Int), so applicators must define this method.
GeometryOpsCore.ApplyToArray Type
ApplyToArray(f, target, arr, kw)Create an Applicator that applies a function to all elements of arr.
GeometryOpsCore.ApplyToFeatures Type
ApplyToFeatures(f, target, fc, kw)Create an Applicator that applies a function to all features of fc.
GeometryOpsCore.ApplyToGeom Type
ApplyToGeom(f, target, geom, kw)Create an Applicator that applies a function to all sub-geometries of geom.
GeometryOpsCore.AutoAlgorithm Type
AutoAlgorithm{T, M <: Manifold}(manifold::M, x::T)Indicates that the Operation should automatically select the best algorithm for its input data, based on the passed in manifold (may be an AutoManifold) and data x.
The actual implementation is left to the implementation of that particular Operation.
GeometryOpsCore.AutoManifold Type
AutoManifold()The AutoManifold is a special manifold that automatically selects the best manifold for the operation. It does not carry any parameters, nor does it indicate anything about the nature of the space.
This gets resolved to a specific manifold when an operation is applied, using the format method.
GeometryOpsCore.Geodesic Type
Geodesic(; semimajor_axis, inv_flattening)A geodesic manifold means that the geometry is on a 3-dimensional ellipsoid, parameterized by semimajor_axis (inv_flattening (
Usually, this is only relevant for area and segmentization calculations. It becomes more relevant as one grows closer to the poles (or equator).
sourceGeometryOpsCore.Manifold Type
abstract type ManifoldA manifold is mathematically defined as a topological space that resembles Euclidean space locally.
We use the manifold definition to define the space in which an operation should be performed, or where a geometry lies.
Currently we have Planar, Spherical, and Geodesic manifolds.
GeometryOpsCore.ManifoldIndependentAlgorithm Type
abstract type ManifoldIndependentAlgorithm{M <: Manifold} <: Algorithm{M}The abstract supertype for a manifold-independent algorithm, i.e., one which may work on any manifold.
The manifold is stored in the algorithm for a ManifoldIndependentAlgorithm, and accessed via manifold(alg).
GeometryOpsCore.MissingKeywordInAlgorithmException Type
MissingKeywordInAlgorithmException{Alg, F} <: ExceptionAn error type which is thrown when a keyword argument is missing from an algorithm.
The alg argument is the algorithm struct, and the keyword argument is the keyword that was missing.
This error message is used in the enforce method.
Usage
This is of course not how you would actually use this error type, but it is how you construct and throw it.
throw(MissingKeywordInAlgorithmException(GEOS(; tokl = 1.0), my_function, :tol))Real world usage will often look like this:
function my_function(alg::CLibraryPlanarAlgorithm, args...)
mykwarg = enforce(alg, :mykwarg, my_function) # this will throw an error if :mykwarg is not present in alg
endGeometryOpsCore.NoAlgorithm Type
NoAlgorithm(manifold)A type that indicates no algorithm is to be used, essentially the equivalent of nothing.
Stores a manifold within itself.
sourceGeometryOpsCore.Operation Type
abstract type Operation{Alg <: Algorithm} endOperations are callable structs, that contain the entire specification for what the algorithm will do.
Sometimes they may be underspecified and only materialized fully when you see the geometry, so you can extract the best manifold for those geometries.
sourceGeometryOpsCore.Planar Type
Planar()A planar manifold refers to the 2D Euclidean plane.
Z coordinates may be accepted but will not influence geometry calculations, which are done purely on 2D geometry. This is the standard "2.5D" model used by e.g. GEOS.
sourceGeometryOpsCore.SingleManifoldAlgorithm Type
abstract type SingleManifoldAlgorithm{M <: Manifold} <: Algorithm{M}The abstract supertype for a single-manifold algorithm, i.e., one which is known to only work on a single manifold.
The manifold may be accessed via manifold(alg).
GeometryOpsCore.Spherical Type
Spherical(; radius)A spherical manifold means that the geometry is on the 3-sphere (but is represented by 2-D longitude and latitude).
Extended help
Note
The traditional definition of spherical coordinates in physics and mathematics, z-axis.
Here, we use the geographic definition of longitude and latitude, meaning that lon is longitude between -180 and 180, and lat is latitude between -90 (south pole) and 90 (north pole).
GeometryOpsCore.TaskFunctors Type
TaskFunctors(functors, tasks_per_thread)A struct to hold the functors and tasks_per_thread, for internal use with _maptasks where functions have state that cannot be shared accross threads, such as Proj.Transformation.
functors must be an array or tuple of functors, one per thread, and tasks_per_thread must be an integer. This also allows you to control the number of tasks per thread that _maptasks launches, useful for tuning performance if you like.
GeometryOpsCore.TraitTarget Type
TraitTarget{T}This struct holds a trait parameter or a union of trait parameters.
It is primarily used for dispatch into methods which select trait levels, like apply, or as a parameter to target.
Constructors
TraitTarget(GI.PointTrait())
TraitTarget(GI.LineStringTrait(), GI.LinearRingTrait()) # and other traits as you may like
TraitTarget(TraitTarget(...))
# There are also type based constructors available, but that's not advised.
TraitTarget(GI.PointTrait)
TraitTarget(Union{GI.LineStringTrait, GI.LinearRingTrait})
# etc.GeometryOpsCore.WithTrait Type
WithTrait(f)WithTrait is a functor that applies a function to a trait and an object.
Specifically, the calling convention is for f is changed from f(geom) to f(trait, geom; kw...).
This is useful to keep the trait materialized through the call stack, which can improve inferrability and performance.
sourceGeometryOpsCore.WrongManifoldException Type
WrongManifoldException{InputManifold, DesiredManifold, Algorithm} <: ExceptionThis error is thrown when an Algorithm is called with a manifold that it was not designed for.
It's mainly thrown when constructing SingleManifoldAlgorithm types.
GeometryOpsCore.apply Method
apply(f, target::Union{TraitTarget, GI.AbstractTrait}, obj; kw...)Reconstruct a geometry, feature, feature collection, or nested vectors of either using the function f on the target trait.
f(target_geom) => x where x also has the target trait, or a trait that can be substituted. For example, swapping PolgonTrait to MultiPointTrait will fail if the outer object has MultiPolygonTrait, but should work if it has FeatureTrait.
Objects "shallower" than the target trait are always completely rebuilt, like a Vector of FeatureCollectionTrait of FeatureTrait when the target has PolygonTrait and is held in the features. These will always be GeoInterface geometries/feature/feature collections. But "deeper" objects may remain unchanged or be whatever GeoInterface compatible objects f returns.
The result is a functionally similar geometry with values depending on f.
threaded:trueorfalse. Whether to use multithreading. Defaults tofalse.crs: The CRS to attach to geometries. Defaults tonothing.calc_extent:trueorfalse. Whether to calculate the extent. Defaults tofalse.
Example
Flipped point the order in any feature or geometry, or iterables of either:
import GeoInterface as GI
import GeometryOps as GO
geom = GI.Polygon([GI.LinearRing([(1, 2), (3, 4), (5, 6), (1, 2)]),
GI.LinearRing([(3, 4), (5, 6), (6, 7), (3, 4)])])
flipped_geom = GO.apply(GI.PointTrait, geom) do p
(GI.y(p), GI.x(p))
endGeometryOpsCore.applyreduce Method
applyreduce(f, op, target::Union{TraitTarget, GI.AbstractTrait}, obj; threaded, init, kw...)Apply function f to all objects with the target trait, and reduce the result with an op like +.
The order and grouping of application of op is not guaranteed.
If threaded==true threads will be used over arrays and iterables, feature collections and nested geometries.
init functions the same way as it does in base Julia functions like reduce.
GeometryOpsCore.best_manifold Function
best_manifold(alg::Algorithm, input)::ManifoldReturn the best Manifold for the algorithm alg based on the given input.
May be any subtype of Manifold.
GeometryOpsCore.booltype Function
booltype(x)Returns a BoolsAsTypes from x, whether it's a boolean or a BoolsAsTypes.
GeometryOpsCore.flatten Method
flatten(target::Type{<:GI.AbstractTrait}, obj)
flatten(f, target::Type{<:GI.AbstractTrait}, obj)Lazily flatten any AbstractArray, iterator, FeatureCollectionTrait, FeatureTrait or AbstractGeometryTrait object obj, so that objects with the target trait are returned by the iterator.
If f is passed in it will be applied to the target geometries.
GeometryOpsCore.manifold Function
manifold(alg::Algorithm)::ManifoldReturn the manifold associated with the algorithm.
May be any subtype of Manifold.
GeometryOpsCore.rebuild Method
rebuild(geom, child_geoms)Rebuild a geometry from child geometries.
By default geometries will be rebuilt as a GeoInterface.Wrappers geometry, but rebuild can have methods added to it to dispatch on geometries from other packages and specify how to rebuild them.
(Maybe it should go into GeoInterface.jl)
sourceGeometryOpsCore.reconstruct Method
reconstruct(geom, components)Reconstruct geom from an iterable of component objects that match its structure.
All objects in components must have the same GeoInterface.trait.
Usually used in combination with flatten.
GeometryOpsCore.reconstruct_table Method
reconstruct_table(input, geometry_column_names, geometry_columns, other_column_names, args...; kwargs...)Reconstruct a table from the given input, geometry column names, geometry columns, and other column names.
Any function that defines reconstruct_table must also define used_reconstruct_table_kwargs.
The input must be a table.
The function should return a best-effort attempt at a table of the same type as the input, with the new geometry column(s) and other columns.
The fallback implementation invokes Tables.materializer. But if you want to be efficient and pass e.g. arbitrary kwargs to the materializer, or materialize in a different way, you can do so by overloading this function for your desired input type.
This is "semi-public" API and while it may add optional arguments, it will not add new required positional arguments. All implementations must allow arbitrary kwargs to pass through and harvest what they need.
sourceGeometryOpsCore.unwrap Function
unwrap(target::Type{<:AbstractTrait}, obj)
unwrap(f, target::Type{<:AbstractTrait}, obj)Unwrap the object to vectors, down to the target trait.
If f is passed in it will be applied to the target geometries as they are found.
GeometryOpsCore.used_reconstruct_table_kwargs Method
used_reconstruct_table_kwargs(input)Return a tuple of the kwargs that should be passed to reconstruct_table for the given input.
This is "semi-public" API, and required for any input type that defines reconstruct_table.