Skip to content

Conversation

@cookiedan42
Copy link
Contributor

  • I agree to follow the project's code of conduct.
  • I added an entry to CHANGES.md if knowledge of this change could be valuable to users.

Simplification of Contains in the opposite direction of #1427 , Covers trait allows for simpler Geom in Geom operations because we don't need to be concerned about rhs being inside self's boundary

Parts implemented

  1. New Covers Trait
  2. Blanket implementation based on Relate
  3. Results which can be derived from intersects
  4. Some results which are equivalent to Contains
  5. enable jts-tests-runner case for Covers

lacking in the test department, but these are the basic derivable implementations

@cookiedan42
Copy link
Contributor Author

Bench

Big leap over Contains delegated to Relate

rect covers line        time:   [949.68 ps 951.09 ps 952.49 ps]
                        change: [-1.8060% -1.4820% -1.1652%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 9 outliers among 100 measurements (9.00%)
  2 (2.00%) low severe
  5 (5.00%) low mild
  2 (2.00%) high severe

rect contains line      time:   [2.4912 µs 2.5091 µs 2.5262 µs]
                        change: [-1.7329% -1.1366% -0.5625%] (p = 0.00 < 0.05)
                        Change within noise threshold.
Found 2 outliers among 100 measurements (2.00%)
  2 (2.00%) high mild

@michaelkirk
Copy link
Member

Is there a reason that this is a draft? I haven't looked at it closely yet, but directionally it makes sense.

Sorry again for the slow review cycle. I appreciate the new functionality and speedups! I've been busy elsewhere, but trying to steadily get through these geo PRs.

@cookiedan42
Copy link
Contributor Author

A few reasons

  1. I'm pretty confident in the implementations here, but I do want to add tests for anything not relate-derived
  2. just generally being busy in cloud/infra headspace

I probably could clean this up and add tests for the non relate and intersects-derived parts,
Or I could pare the PR back to just the base trait and relate-derived implementations, and add back the others when I have the time to work on them properly

@michaelkirk
Copy link
Member

Ok, no rush! I just wanted to be sure you weren't waiting on the repository maintainers for something.

@cookiedan42 cookiedan42 force-pushed the covers-base branch 3 times, most recently from 3aae4e0 to a1071b6 Compare November 28, 2025 16:12
@cookiedan42 cookiedan42 marked this pull request as ready for review November 28, 2025 16:40
@cookiedan42
Copy link
Contributor Author

Added tests for the non-derived linestring functions to ensure they're correctly different with the contains functions

@frewsxcv
Copy link
Member

Please add an entry for this somewhere in the geo algorithm index:

geo/geo/src/lib.rs

Lines 45 to 187 in 87b70cc

//! # Algorithms
//!
//! ## Measures
//!
//! Algorithms for measures along a line, and how a line is measured.
//!
//! ### Metric Spaces
//!
//! - **[`Euclidean`]**: The [Euclidean plane] measures distance with the pythagorean formula. Not suitable for lon/lat geometries.
//! - **[`Haversine`]**: The [Haversine Formula] measures distance on a sphere. Only suitable for lon/lat geometries.
//! - **[`Geodesic`]**: Geodesic methods based on [Karney (2013)] more accurately reflect the shape of the Earth, but are slower than Haversine. Only suitable for lon/lat geometries.
//! - **[`Rhumb`]**: [Rhumb line] (a.k.a. loxodrome) measures can be useful for navigation applications where maintaining a constant bearing or direction is important. Only suitable for lon/lat geometries.
//!
//! ### Operations on Metric Spaces
//!
//! - **[`Distance`]**: Calculate the minimum distance between two geometries.
//! - **[`Length`]**: Calculate the length of a `Line`, `LineString`, or `MultiLineString`.
//! - **[`Bearing`]**: Calculate the bearing between two points.
//!
//! - **[`Destination`]**: Calculate the destination point from an origin point, given a bearing and a distance.
//! - **[`InterpolateLine`]**: Interpolate a `Point` along a `Line` or `LineString`.
//! - **[`InterpolatePoint`]**: Interpolate points along a line.
//! - **[`Densify`]**: Insert points into a geometry so there is never more than `max_segment_length` between points.
//!
//! ### Misc measures
//!
//! - **[`HausdorffDistance`]**: Calculate "the maximum of the distances from a point in any of the sets to the nearest point in the other set." (Rote, 1991)
//! - **[`VincentyDistance`]**: Calculate the minimum geodesic distance between geometries using Vincenty’s formula
//! - **[`VincentyLength`]**: Calculate the geodesic length of a geometry using Vincenty’s formula
//! - **[`FrechetDistance`]**: Calculate the similarity between [`LineString`]s using the Fréchet distance
//!
//! ## Area
//!
//! - **[`Area`]**: Calculate the planar area of a geometry
//! - **[`ChamberlainDuquetteArea`]**: Calculate the geodesic area of a geometry on a sphere using the algorithm presented in _Some Algorithms for Polygons on a Sphere_ by Chamberlain and Duquette (2007)
//! - **[`GeodesicArea`]**: Calculate the geodesic area and perimeter of a geometry on an ellipsoid using the algorithm presented in _Algorithms for geodesics_ by Charles Karney (2013)
//!
//! ## Boolean Operations
//!
//! - **[`BooleanOps`]**: Combine or split (Multi)Polygons using intersection, union, xor, or difference operations
//! - **[`unary_union`]**: Efficient union of many [`Polygon`] or [`MultiPolygon`]s
//!
//! ## Outlier Detection / Clustering
//!
//! - **[`OutlierDetection`]**: Detect outliers in a group of points using [LOF](https://en.wikipedia.org/wiki/Local_outlier_factor)
//! - **[`Dbscan`]**: Calculate point clusters using the DBSCAN algorithm
//! - **[`KMeans`]**: Calculate point clusters using the k-means algorithm
//!
//! ## Simplification
//!
//! - **[`Simplify`]**: Simplify a geometry using the Ramer–Douglas–Peucker algorithm
//! - **[`SimplifyIdx`]**: Calculate a simplified geometry using the Ramer–Douglas–Peucker algorithm, returning coordinate indices
//! - **[`SimplifyVw`]**: Simplify a geometry using the Visvalingam-Whyatt algorithm
//! - **[`SimplifyVwPreserve`]**: Simplify a geometry using a topology-preserving variant of the Visvalingam-Whyatt algorithm
//! - **[`SimplifyVwIdx`]**: Calculate a simplified geometry using the Visvalingam-Whyatt algorithm, returning coordinate indices
//!
//! ## Query
//!
//! - **[`ClosestPoint`]**: Find the point on a geometry
//! closest to a given point
//! - **[`HaversineClosestPoint`]**: Find the point on a geometry
//! closest to a given point on a sphere using spherical coordinates and lines being great arcs
//! - **[`IsConvex`]**: Calculate the convexity of a [`LineString`]
//! - **[`LineLocatePoint`]**: Calculate the
//! fraction of a line’s total length representing the location of the closest point on the
//! line to the given point
//! - **[`InteriorPoint`]**:
//! Calculates a representative point inside a `Geometry`
//!
//! ## Topology
//!
//! - **[`Contains`]**: Calculate if a geometry contains another
//! geometry
//! - **[`CoordinatePosition`]**: Calculate
//! the position of a coordinate relative to a geometry
//! - **[`HasDimensions`]**: Determine the dimensions of a geometry
//! - **[`Intersects`]**: Calculate if a geometry intersects
//! another geometry
//! - **[`line_intersection`]**: Calculates the
//! intersection, if any, between two lines
//! - **[`Intersections`]**: Find all line segment intersections using an efficient sweep line algorithm (Bentley-Ottmann)
//! - **[`Relate`]**: Topologically relate two geometries based on
//! [DE-9IM](https://en.wikipedia.org/wiki/DE-9IM) semantics
//! - **[`Within`]**: Calculate if a geometry lies completely within another geometry
//!
//! ## Triangulation
//!
//! - **[`TriangulateEarcut`](triangulate_earcut)**: Triangulate polygons using the earcut algorithm. Requires the `earcutr` feature, which is enabled by default
//! - **[`TriangulateDelaunay`](triangulate_delaunay)**: Produce constrained or unconstrained Delaunay triangulations of polygons. Requires the `spade` feature, which is enabled by default
//!
//! ## Winding
//!
//! - **[`Orient`]**: Apply a specified winding [`Direction`](orient::Direction) to a [`Polygon`]’s interior and exterior rings
//! - **[`Winding`]**: Calculate and manipulate the [`WindingOrder`](winding_order::WindingOrder) of a [`LineString`]
//!
//! ## Iteration
//!
//! - **[`CoordsIter`]**: Iterate over the coordinates of a geometry
//! - **[`MapCoords`]**: Map a function over all the coordinates
//! in a geometry, returning a new geometry
//! - **[`MapCoordsInPlace`]**: Map a function over all the
//! coordinates in a geometry in-place
//! - **[`LinesIter`]**: Iterate over lines of a geometry
//!
//! ## Boundary
//!
//! - **[`BoundingRect`]**: Calculate the axis-aligned
//! bounding rectangle of a geometry
//! - **[`MinimumRotatedRect`]**: Calculate the
//! minimum bounding box of a geometry
//! - **[`ConcaveHull`]**: Calculate the concave hull of a
//! geometry
//! - **[`ConvexHull`]**: Calculate the convex hull of a
//! geometry
//! - **[`Extremes`]**: Calculate the extreme coordinates and
//! indices of a geometry
//!
//! ## Affine transformations
//!
//! - **[`Rotate`]**: Rotate a geometry around its centroid
//! - **[`Scale`]**: Scale a geometry up or down by a factor
//! - **[`Skew`]**: Skew a geometry by shearing angles along the `x` and `y` dimension
//! - **[`Translate`]**: Translate a geometry along its axis
//! - **[`AffineOps`]**: generalised composable affine operations
//!
//! ## Conversion
//!
//! - **[`Convert`]**: Convert (infallibly) the numeric type of a geometry’s coordinate value
//! - **[`TryConvert`]**: Convert (fallibly) the numeric type of a geometry’s coordinate value
//! - **[`ToDegrees`]**: Radians to degrees coordinate transforms for a given geometry
//! - **[`ToRadians`]**: Degrees to radians coordinate transforms for a given geometry
//!
//! ## Miscellaneous
//!
//! - **[`Buffer`]**: Create a new geometry whose boundary is offset the specified distance from the input.
//! - **[`Centroid`]**: Calculate the centroid of a geometry
//! - **[`ChaikinSmoothing`]**: Smoothen `LineString`, `Polygon`, `MultiLineString` and `MultiPolygon` using Chaikin's algorithm
//! - **[`proj`]**: Project geometries with the `proj` crate (requires the `use-proj` feature)
//! - **[`LineStringSegmentize`]**: Segment a LineString into `n` segments
//! - **[`LineStringSegmentizeHaversine`]**: Segment a LineString using Haversine distance
//! - **[`Transform`]**: Transform a geometry using Proj
//! - **[`RemoveRepeatedPoints`]**: Remove repeated points from a geometry
//! - **[`Validation`]**: Checks if the geometry is well formed. Some algorithms may not work correctly with invalid geometries

@urschrei
Copy link
Member

urschrei commented Dec 1, 2025

@cookiedan42 Please squash your commits!

@urschrei urschrei added this pull request to the merge queue Dec 2, 2025
Merged via the queue into georust:main with commit d6a376b Dec 2, 2025
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants