Skip to main content

Crate geometry_strategy

Crate geometry_strategy 

Source
Expand description

§Pluggable algorithm strategies, keyed by coordinate-system family.

Mirrors boost/geometry/strategies/ — every algorithm has a strategy trait here; concrete strategies live in submodules keyed by coordinate-system family (cartesian, spherical, geographic).

§Writing a new strategy

Take the worked example: a Cartesian point-to-point distance strategy (Pythagoras). A strategy for any algorithm follows the same three steps.

§Step 1 — Pick the coordinate-system family to bind on

Strategies bind on the CoordinateSystem::Family — never on the concrete CS — so that one impl covers both Spherical<Degree> and Spherical<Radian> (or Geographic<Degree> / Geographic<Radian>). The bound is expressed via the geometry_tag::SameAs trait, the Rust analogue of C++’s std::is_same:

impl<P1, P2> DistanceStrategy<P1, P2> for Pythagoras
where
    P1: Point,
    P2: Point<Scalar = P1::Scalar>,
    <P1::Cs as CoordinateSystem>::Family: SameAs<CartesianFamily>,
    <P2::Cs as CoordinateSystem>::Family: SameAs<CartesianFamily>,
{ /* ... */ }

The two SameAs<CartesianFamily> bounds form the family fence: they refuse to monomorphise for a Spherical or Geographic point. The #[diagnostic::on_unimplemented] plate on geometry_tag::SameAs then redirects the resulting compile error to the correct mitigation (wrap in geometry_adapt::WithCs<_, Geographic<_>>, or pick a CS-appropriate strategy such as Haversine / Andoyer / Vincenty).

§Step 2 — Decide whether to provide a Comparable form

A “comparable” form is a sibling strategy that returns the same ordering as the real strategy but skips work the ordering does not need. For Pythagoras this means returning the squared distance and skipping the final sqrt. The squared form sorts identically and is roughly twice as fast on a hot inner loop:

impl<P1, P2> DistanceStrategy<P1, P2> for Pythagoras /* ... */ {
    type Out = P1::Scalar;
    type Comparable = ComparablePythagoras; // <- skip-sqrt sibling
    fn distance(&self, a: &P1, b: &P2) -> Self::Out {
        self.comparable().distance(a, b).sqrt()
    }
    fn comparable(&self) -> Self::Comparable { ComparablePythagoras }
}

If the math has no equivalent shortcut (Andoyer, Vincenty, Haversine after the half-angle formula), set type Comparable = Self; — the optimiser collapses the indirection. The doc on distance::DistanceStrategy::Comparable warns implementers not to over-engineer this.

§Step 3 — Wire the default selection

Each coordinate-system family picks one default strategy per algorithm via distance::DefaultDistance:

impl DefaultDistance<CartesianFamily>  for CartesianFamily  { type Strategy = Pythagoras; }
impl DefaultDistance<SphericalFamily>  for SphericalFamily  { type Strategy = Haversine;  }
impl DefaultDistance<GeographicFamily> for GeographicFamily { type Strategy = Andoyer;    }

That is what makes the no-strategy distance(a, b) overload resolve to the right algorithm: the type-level walk A → A::Point → Cs → Family → DefaultDistance<…B's family…>::Strategy resolves to the correct concrete strategy at the call site.

§Reverse dispatch — argument symmetry

For algorithms whose arguments are symmetric, write one impl per tag pair (A, B) and the Reversed<S> blanket impl in distance::Reversed picks up (B, A) automatically. The analogue of Boost’s core/reverse_dispatch.hpp partial specialisation, done once at the strategy-trait layer instead of per-algorithm.

§Module layout

Each algorithm has its own strategy trait module — distance, area, length, envelope, within, intersects, disjoint, equals. Concrete strategies live under cartesian, spherical, or geographic per coordinate-system family.

Re-exports§

pub use area::AreaStrategy;
pub use area::DefaultArea;
pub use area::DefaultAreaStrategy;
pub use area::ShoelaceArea;
pub use area::ShoelaceBoxArea;
pub use area::ShoelaceMultiPolygonArea;
pub use area::ShoelacePolygonArea;
pub use azimuth::AzimuthStrategy;
pub use azimuth::CartesianAzimuth;
pub use azimuth::DefaultAzimuth;
pub use azimuth::DefaultAzimuthStrategy;
pub use buffer::BufferDistanceStrategy;
pub use buffer::BufferEndStrategy;
pub use buffer::BufferJoinStrategy;
pub use buffer::BufferPointStrategy;
pub use buffer::BufferSettings;
pub use buffer::BufferSideStrategy;
pub use buffer::CartesianBuffer;
pub use buffer::DefaultBuffer;
pub use buffer::DefaultBufferStrategy;
pub use buffer::GeographicBuffer;
pub use buffer::SphericalBuffer;
pub use cartesian::ComparablePythagoras;
pub use cartesian::PointToSegment;
pub use cartesian::Pythagoras;
pub use centroid::CartesianBoxCentroid;
pub use centroid::CartesianLinestringCentroid;
pub use centroid::CartesianMultiPointCentroid;
pub use centroid::CartesianPolygonCentroid;
pub use centroid::CartesianRingCentroid;
pub use centroid::CartesianSegmentCentroid;
pub use centroid::CentroidStrategy;
pub use closest_points::CartesianClosestPoints;
pub use closest_points::ClosestPointsStrategy;
pub use compare::ALL_DIMENSIONS;
pub use compare::EqualTo;
pub use compare::Greater;
pub use compare::Less;
pub use compare::LessExact;
pub use convex_hull::ConvexHullStrategy;
pub use convex_hull::MonotoneChain;
pub use densify::CartesianDensify;
pub use densify::DensifyStrategy;
pub use destination::DefaultDestination;
pub use destination::DefaultDestinationStrategy;
pub use destination::DestinationStrategy;
pub use disjoint::CartesianDisjoint;
pub use disjoint::DisjointStrategy;
pub use distance::DefaultDistance;
pub use distance::DefaultDistanceStrategy;
pub use distance::DistanceStrategy;
pub use envelope::EnvelopeBox;
pub use envelope::EnvelopeLinestring;
pub use envelope::EnvelopeMultiLinestring;
pub use envelope::EnvelopeMultiPoint;
pub use envelope::EnvelopeMultiPolygon;
pub use envelope::EnvelopePoint;
pub use envelope::EnvelopePolygon;
pub use envelope::EnvelopeRing;
pub use envelope::EnvelopeSegment;
pub use envelope::EnvelopeStrategy;
pub use equals::EqPointPoint;
pub use equals::EqPolygonPolygon;
pub use equals::EqSegmentSegment;
pub use equals::EqualsStrategy;
pub use geographic::Andoyer;
pub use geographic::DirectResult;
pub use geographic::GeographicArea;
pub use geographic::GeographicAzimuth;
pub use geographic::GeographicLength;
pub use geographic::GeographicPerimeter;
pub use geographic::GeographicPolygonArea;
pub use geographic::InverseResult;
pub use geographic::Karney;
pub use geographic::KarneyDirect;
pub use geographic::KarneyInverse;
pub use geographic::Rhumb;
pub use geographic::Thomas;
pub use geographic::ThomasDirect;
pub use geographic::Vincenty;
pub use geographic::VincentyDirect;
pub use intersects::CartesianIntersects;
pub use intersects::IntersectsStrategy;
pub use length::CartesianLength;
pub use length::CartesianPerimeter;
pub use length::DefaultLength;
pub use length::DefaultLengthStrategy;
pub use length::DefaultPerimeter;
pub use length::DefaultPerimeterStrategy;
pub use length::LengthStrategy;
pub use line_interpolate::CartesianLineInterpolate;
pub use line_interpolate::LineInterpolateStrategy;
pub use segmentize::CartesianSegmentize;
pub use segmentize::SegmentizeStrategy;
pub use simplify::DouglasPeucker;
pub use simplify::SimplifyStrategy;
pub use simplify::VisvalingamWhyatt;
pub use simplify::VisvalingamWhyattPreserve;
pub use spherical::ChamberlainDuquetteArea;
pub use spherical::ComparableHaversine;
pub use spherical::CrossTrack;
pub use spherical::Haversine;
pub use spherical::HaversineClosestPoints;
pub use spherical::SphericalArea;
pub use spherical::SphericalAzimuth;
pub use spherical::SphericalLength;
pub use spherical::SphericalPerimeter;
pub use spherical::SphericalPolygonArea;
pub use transform::Affine2;
pub use transform::Affine3;
pub use transform::Rotate;
pub use transform::Scale;
pub use transform::Skew;
pub use transform::TransformStrategy;
pub use transform::Translate;
pub use within::WithinBox;
pub use within::WithinPoly;
pub use within::WithinRing;
pub use within::WithinStrategy;

Modules§

area
Strategy for computing the area of a Cartesian geometry.
azimuth
AzimuthStrategy<P1, P2> — the angle from p1 to p2.
buffer
Composable buffer strategies.
cartesian
Strategies bound to the Cartesian coordinate-system family.
centroid
CentroidStrategy<G> — geometric centre of a geometry.
closest_points
ClosestPointsStrategy<A, B> — pair of nearest points on (A, B).
compare
Point-ordering policies.
convex_hull
Convex hull strategies.
densify
Densification strategies.
destination
Point-at-bearing-and-distance strategies.
disjoint
Per-CS strategy for the disjoint set-relation algorithm.
distance
The DistanceStrategy trait, default strategy selection, and the Reversed argument-swapping adapter.
envelope
Per-CS strategy for the axis-aligned bounding box (envelope).
equals
Per-CS strategy for the equals set-relation algorithm.
geographic
Strategies bound to the Geographic coordinate-system family.
intersects
Per-CS strategy for the intersects set-relation algorithm.
length
Strategy for summing the length of a sequence of points.
line_interpolate
LineInterpolateStrategy<L> — point at fractional arc-length t.
segmentize
Equal-length linestring subdivision strategies.
simplify
Line simplification — Douglas–Peucker.
spherical
Strategies bound to the Spherical coordinate-system family.
transform
TransformStrategy<P> and affine implementations.
within
Per-CS strategy for point-in-polygon containment (within / covered_by).

Structs§

Reversed
Lift a strategy for (A, B) into the same strategy concept for (B, A).