From 9f1de768ab16194354dbd46fd4fb338a88e50eb0 Mon Sep 17 00:00:00 2001 From: Michael Kirk Date: Wed, 30 Oct 2024 17:11:00 -0700 Subject: [PATCH] un-genericify CrossTrackDistance to avoid the breaking change for now --- geo/CHANGES.md | 2 +- geo/src/algorithm/cross_track_distance.rs | 35 +++++++---------------- 2 files changed, 11 insertions(+), 26 deletions(-) diff --git a/geo/CHANGES.md b/geo/CHANGES.md index 5e6745ed8..1d691a662 100644 --- a/geo/CHANGES.md +++ b/geo/CHANGES.md @@ -2,7 +2,7 @@ ## Unreleased -* BREAKING: Make `CrossTrackDistance` generic both to clarify when it is using Haversine, but also implement it for Euclidean. +* Add `Haversine:distance` for Line vs. Point (same as CrossTrackDistance) ## 0.29.0 - 2024.10.30 diff --git a/geo/src/algorithm/cross_track_distance.rs b/geo/src/algorithm/cross_track_distance.rs index 86b240350..4ba369880 100644 --- a/geo/src/algorithm/cross_track_distance.rs +++ b/geo/src/algorithm/cross_track_distance.rs @@ -4,6 +4,8 @@ use num_traits::FromPrimitive; /// Determine the cross track distance (also known as the cross track error) which is the shortest /// distance between a point and a continuous line. +/// +/// Distance is measured in meters, using the Haversine formula. pub trait CrossTrackDistance where T: CoordFloat + FromPrimitive, @@ -37,24 +39,15 @@ where /// distance.round() /// ); /// ``` - fn cross_track_distance(&self, line_point_a: &Rhs, line_point_b: &Rhs) -> T - where - MetricSpace: for<'a> Distance, &'a Point>; + fn cross_track_distance(&self, line_point_a: &Rhs, line_point_b: &Rhs) -> T; } impl CrossTrackDistance> for Point where T: CoordFloat + FromPrimitive, { - fn cross_track_distance( - &self, - line_point_a: &Point, - line_point_b: &Point, - ) -> T - where - MetricSpace: for<'a> Distance, &'a Point>, - { - MetricSpace::distance(&Line::new(*line_point_a, *line_point_b), self) + fn cross_track_distance(&self, line_point_a: &Point, line_point_b: &Point) -> T { + crate::Haversine::distance(&Line::new(*line_point_a, *line_point_b), self) } } @@ -69,7 +62,7 @@ mod test { let line_point_a = Point::new(-1.7297, 53.3206); let line_point_b = Point::new(0.1334, 53.1887); assert_relative_eq!( - p.cross_track_distance::(&line_point_a, &line_point_b), + p.cross_track_distance(&line_point_a, &line_point_b), 307.549995, epsilon = 1.0e-6 ); @@ -82,7 +75,7 @@ mod test { let line_point_b = Point::new(2., 0.); assert_relative_eq!( - p.cross_track_distance::(&line_point_a, &line_point_b), + p.cross_track_distance(&line_point_a, &line_point_b), 0., epsilon = 1.0e-6 ); @@ -95,13 +88,13 @@ mod test { let line_point_b = Point::new(1., 1.); assert_relative_eq!( - p.cross_track_distance::(&line_point_a, &line_point_b), + p.cross_track_distance(&line_point_a, &line_point_b), Haversine::distance(p, Point::new(1., 0.)), epsilon = 1.0e-6 ); assert_relative_eq!( - p.cross_track_distance::(&line_point_b, &line_point_a), + p.cross_track_distance(&line_point_b, &line_point_a), Haversine::distance(p, Point::new(1., 0.)), epsilon = 1.0e-6 ); @@ -113,15 +106,7 @@ mod test { let line_point_a = Point::new(-80.1918f64, 25.7617f64); let line_point_b = Point::new(-120.7401f64, 47.7511f64); - let haversine_distance = p1.cross_track_distance::(&line_point_a, &line_point_b); + let haversine_distance = p1.cross_track_distance(&line_point_a, &line_point_b); assert_relative_eq!(haversine_distance, 1_547_104., epsilon = 1.0); - - // Same as above, but projected to EPSG:5070 to test Euclidean - let p1 = Point::new(1826303.9422258963, 2179112.0732980534); - let line_point_a = Point::new(1594077.349564382, 434470.0414052719); - let line_point_b = Point::new(-1847681.2454118263, 2992574.0850278544); - - let euclidean_distance = p1.cross_track_distance::(&line_point_a, &line_point_b); - assert_relative_eq!(euclidean_distance, 1_538_764., epsilon = 1.0); } }