geometry-adapt
Part of the boost_geometry workspace — a Rust port of Boost.Geometry. Most users should depend on the facade crate, which re-exports this one; depend on this crate directly only for a slimmer build.
Adapting your own types
Three paths get a user type into the geometry kernel, ordered from least to most indirect. Pick the first one that applies.
Path 1 — Direct impl Point for MyPoint
If you own the type, implement [geometry_trait::Geometry] and
[geometry_trait::Point] directly (add [geometry_trait::PointMut]
too if you need to write coordinates). This is the most explicit
form and the one with the smallest compile-time footprint — no
wrapper types, no macros.
use Cartesian;
use PointTag;
use ;
#
Path 2 — #[derive(Point)]
For the common "struct with named coordinate fields" case the
Point proc-macro generates the impl. Mirrors the C++
BOOST_GEOMETRY_REGISTER_POINT_2D macro from
boost/geometry/geometries/register/point.hpp. The derive lives
in geometry-derive and is re-exported by the geometry facade
so downstream users only need a single dependency:
use Point; // the derive macro
use *; // brings in the `Point` trait + algorithms
#
#
let d = distance;
assert_eq!;
Path 3 — Adapt<T> + optional WithCs<T, Cs>
When you do not own the type (a [T; N], a (T, T), a foreign
crate's point type), wrap it in [Adapt<T>]. Adapt is a
#[repr(transparent)] newtype that forwards coordinate access
into the foreign storage layout. Coherence forbids a blanket impl
on the foreign type directly; the wrapper sidesteps the orphan
rule with zero runtime cost.
use Adapt;
use Point;
let p = Adapt;
assert_eq!;
assert_eq!;
[Adapt<T>] is shape-only and defaults the coordinate system
to Cartesian. For any other CS (latitude /
longitude in degrees, radians, …) layer [WithCs<T, Cs>] on top.
This is the orthogonality from proposal §3.7: Adapt answers
"how do I read coordinates out of this foreign data layout?",
while WithCs answers "what does that coordinate pair mean?".
use ;
use distance;
use ;
// [lon, lat] degrees on WGS84.
let ams = new;
let par = new;
let _ = distance; // picks Andoyer for the geographic family
Either wrapper can also re-tag a user type that already
implements Point, so a MyPoint from
Path 1 can be reused as a geographic point by writing
WithCs::<MyPoint, Geographic<Degree>>::new(p) instead of
defining a second adapter.
Container adaptation — the register_*! macros
Coherence also forbids a blanket impl on foreign sequence types
(impl<P: Point, C: AsRef<[P]>> Linestring for C). For that case,
geometry-adapt ships declarative macros register_linestring!,
register_ring!, and register_polygon!, mirroring
BOOST_GEOMETRY_REGISTER_LINESTRING and siblings
(boost/geometry/geometries/register/linestring.hpp and co.).
Module layout:
- [
Adapt<T>] — shape-only wrapper. Forwards coordinate access into a foreign storage layout (array, tuple, third-party point). Defaults toCartesian; layer [WithCs] on top for other systems. - [
WithCs<T, Cs>] — coordinate-system re-tagging wrapper.
Mirrors the role of boost/geometry/geometries/adapted/*.hpp
(c_array.hpp, std_array.hpp, boost_tuple.hpp,
boost_polygon.hpp, …).
License
BSL-1.0 — see LICENSE.