From 124d209be1713d639c71873ecd9062de08a35c6d Mon Sep 17 00:00:00 2001 From: nic Date: Wed, 10 Jan 2024 16:54:18 -0800 Subject: [PATCH 1/5] renaming cross_track_distance += haversine --- ...e.rs => cross_track_distance_haversine.rs} | 28 +++++++++---------- geo/src/algorithm/mod.rs | 6 ++-- 2 files changed, 18 insertions(+), 16 deletions(-) rename geo/src/algorithm/{cross_track_distance.rs => cross_track_distance_haversine.rs} (71%) diff --git a/geo/src/algorithm/cross_track_distance.rs b/geo/src/algorithm/cross_track_distance_haversine.rs similarity index 71% rename from geo/src/algorithm/cross_track_distance.rs rename to geo/src/algorithm/cross_track_distance_haversine.rs index 37cfb8bc1..0ef84a112 100644 --- a/geo/src/algorithm/cross_track_distance.rs +++ b/geo/src/algorithm/cross_track_distance_haversine.rs @@ -2,9 +2,9 @@ use crate::{HaversineBearing, HaversineDistance, MEAN_EARTH_RADIUS}; use geo_types::{CoordFloat, Point}; use num_traits::FromPrimitive; -/// Determine the cross track distance (also known as the cross track error) which is the shortest +/// Determine the cross track distance (Haversine) (also known as the cross track error) which is the shortest /// distance between a point and a continuous line. -pub trait CrossTrackDistance { +pub trait CrossTrackDistanceHaversine { /// Determine the cross track distance between this point and a line /// which passes through line_point_a and line_point_b /// @@ -27,21 +27,21 @@ pub trait CrossTrackDistance { /// // Washington /// let line_point_b = point!(x: -120.7401, y: 47.7511f64); /// - /// let distance = p1.cross_track_distance(&line_point_a, &line_point_b); + /// let distance = p1.cross_track_distance_haversine(&line_point_a, &line_point_b); /// /// assert_eq!( /// 1_547_104., // meters /// distance.round() /// ); /// ``` - fn cross_track_distance(&self, line_point_a: &Rhs, line_point_b: &Rhs) -> T; + fn cross_track_distance_haversine(&self, line_point_a: &Rhs, line_point_b: &Rhs) -> T; } -impl CrossTrackDistance> for Point +impl CrossTrackDistanceHaversine> for Point where T: CoordFloat + FromPrimitive, { - fn cross_track_distance(&self, line_point_a: &Point, line_point_b: &Point) -> T { + fn cross_track_distance_haversine(&self, line_point_a: &Point, line_point_b: &Point) -> T { let mean_earth_radius = T::from(MEAN_EARTH_RADIUS).unwrap(); let l_delta_13: T = line_point_a.haversine_distance(self) / mean_earth_radius; let theta_13: T = line_point_a.haversine_bearing(*self).to_radians(); @@ -53,7 +53,7 @@ where #[cfg(test)] mod test { - use crate::CrossTrackDistance; + use crate::CrossTrackDistanceHaversine; use crate::HaversineDistance; use crate::Point; @@ -63,39 +63,39 @@ 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_haversine(&line_point_a, &line_point_b), 307.549995, epsilon = 1.0e-6 ); } #[test] - fn cross_track_distance_to_line_passing_through_point() { + fn cross_track_distance_haversine_to_line_passing_through_point() { let p = Point::new(0., 0.); let line_point_a = Point::new(1., 0.); 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_haversine(&line_point_a, &line_point_b), 0., epsilon = 1.0e-6 ); } #[test] - fn cross_track_distance_to_line_orthogonal_to_point() { + fn cross_track_distance_haversine_to_line_orthogonal_to_point() { let p = Point::new(0., 0.); let line_point_a = Point::new(1., -1.); 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_haversine(&line_point_a, &line_point_b), p.haversine_distance(&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_haversine(&line_point_b, &line_point_a), p.haversine_distance(&Point::new(1., 0.)), epsilon = 1.0e-6 ); @@ -108,7 +108,7 @@ mod test { let line_point_b = Point::new(-120.7401f64, 47.7511f64); assert_relative_eq!( - p1.cross_track_distance(&line_point_a, &line_point_b), + p1.cross_track_distance_haversine(&line_point_a, &line_point_b), 1_547_104., epsilon = 1.0 ); diff --git a/geo/src/algorithm/mod.rs b/geo/src/algorithm/mod.rs index 3fbec4109..68770d788 100644 --- a/geo/src/algorithm/mod.rs +++ b/geo/src/algorithm/mod.rs @@ -65,8 +65,10 @@ pub mod convex_hull; pub use convex_hull::ConvexHull; /// Cross track distance -pub mod cross_track_distance; -pub use cross_track_distance::CrossTrackDistance; +// pub mod cross_track_distance_geodesic; +// pub use cross_track_distance_geodesic::CrossTrackDistanceGeodesic; +pub mod cross_track_distance_haversine; +pub use cross_track_distance_haversine::CrossTrackDistanceHaversine; /// Determine whether a `Coord` lies inside, outside, or on the boundary of a geometry. pub mod coordinate_position; From 382f1b0c23088c4878ad401e1e2a2d2f455871dc Mon Sep 17 00:00:00 2001 From: nic Date: Mon, 15 Jan 2024 20:08:21 -0800 Subject: [PATCH 2/5] changing cross_track_distance to cross_track_distance_haversine and adding cross_track_distance_geodesic --- .../cross_track_distance_geodesic.rs | 149 ++++++++++++++++++ .../cross_track_distance_haversine.rs | 120 ++++++++++++++ geo/src/algorithm/mod.rs | 10 +- 3 files changed, 276 insertions(+), 3 deletions(-) create mode 100644 geo/src/algorithm/cross_track_distance_geodesic.rs create mode 100644 geo/src/algorithm/cross_track_distance_haversine.rs diff --git a/geo/src/algorithm/cross_track_distance_geodesic.rs b/geo/src/algorithm/cross_track_distance_geodesic.rs new file mode 100644 index 000000000..23b63f1e8 --- /dev/null +++ b/geo/src/algorithm/cross_track_distance_geodesic.rs @@ -0,0 +1,149 @@ +use crate::EQUATORIAL_EARTH_RADIUS; +use geo_types::Point; +use geographiclib_rs::{DirectGeodesic, Geodesic, InverseGeodesic}; + +/// Determine the cross track distance (also known as the cross track error), +/// which is the shortest distance between a point and a line on an ellipsoid. +pub trait CrossTrackDistanceGeodesic { + /// Determine the cross track distance on an ellipsoid between this point + /// and a line which passes through line_point_a and link_point_b + /// + /// # Units + /// + /// - return value: meters + /// + /// # Example + /// + /// ```rust + /// use geo::prelude::*; + /// use geo::point; + /// + /// // New York City + /// let p1 = point!(x: -74.006f64, y: 40.7128f64); + /// + /// // Miami + /// let line_point_a = point!(x: -80.1918f64, y: 25.7617f64); + /// + /// // Washington + /// let line_point_b = point!(x: -120.7401, y: 47.7511f64); + /// + /// let distance = p1.cross_track_distance_geodesic(&line_point_a, &line_point_b); + /// + /// assert_eq!( + /// 1_546_716., // meters + /// distance.round() + /// ); + /// ``` + fn cross_track_distance_geodesic(&self, line_point_a: &Rhs, line_point_b: &Rhs) -> T; +} + +impl CrossTrackDistanceGeodesic for Point { + fn cross_track_distance_geodesic( + &self, + line_point_a: &Point, + line_point_b: &Point, + ) -> f64 { + let geod = Geodesic::wgs84(); + let mut iter = 0; + + // Earth constants + let a: f64 = EQUATORIAL_EARTH_RADIUS; + let mut s_ax: f64; + + let mut line_point_a = *line_point_a; + + loop { + // Get the lat/lon values of each point so that it is easier to read + let (pp_x, pp_y) = (self.x(), self.y()); + let (lpa_x, lpa_y, lpb_x, lpb_y) = ( + line_point_a.x(), + line_point_a.y(), + line_point_b.x(), + line_point_b.y(), + ); + let (s_ap, azi1_ap, _, m_ap, mm_ap, _, _) = geod.inverse(lpa_y, lpa_x, pp_y, pp_x); + let (azi1_ab, _, _) = geod.inverse(lpa_y, lpa_x, lpb_y, lpb_x); + let azi1 = azi1_ap - azi1_ab; + + s_ax = m_ap * azi1.to_radians().cos() + / ((m_ap / s_ap) * azi1.to_radians().cos().powi(2) + + mm_ap * azi1.to_radians().sin().powi(2)); + + if iter == 0 { + s_ax = a * ((s_ap / a).sin() * azi1.to_radians().cos()).atan2((s_ap / a).cos()); + } + + let (pa2_y, pa2_x) = geod.direct(lpa_y, lpa_x, azi1_ab, s_ax); + + if s_ax.abs() < 1e-2 { + return s_ap; + } + + line_point_a = Point::new(pa2_x, pa2_y); + iter += 1 + } + } +} + +#[cfg(test)] +mod test { + use crate::CrossTrackDistanceGeodesic; + use crate::GeodesicDistance; + use crate::Point; + + #[test] + fn distance1_test() { + let p = Point::new(-0.7972, 53.2611); + 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_geodesic(&line_point_a, &line_point_b), + 306.8446329, + epsilon = 1.0e-6 + ); + } + + #[test] + fn cross_track_distance_geodesic_to_line_passing_through_point() { + let p = Point::new(0., 0.); + let line_point_a = Point::new(1., 0.); + let line_point_b = Point::new(2., 0.); + + assert_relative_eq!( + p.cross_track_distance_geodesic(&line_point_a, &line_point_b), + 0., + epsilon = 1.0e-6 + ); + } + #[test] + fn cross_track_distance_geodesic_to_line_orthogonal_to_point() { + let p = Point::new(0., 0.); + let line_point_a = Point::new(1., -1.); + let line_point_b = Point::new(1., 1.); + + assert_relative_eq!( + p.cross_track_distance_geodesic(&line_point_a, &line_point_b), + p.geodesic_distance(&Point::new(1., 0.)), + epsilon = 1.0e-6 + ); + + assert_relative_eq!( + p.cross_track_distance_geodesic(&line_point_b, &line_point_a), + p.geodesic_distance(&Point::new(1., 0.)), + epsilon = 1.0e-6 + ); + } + + #[test] + fn new_york_to_line_between_miami_and_washington() { + let p1 = Point::new(-74.006f64, 40.7128f64); + let line_point_a = Point::new(-80.1918f64, 25.7617f64); + let line_point_b = Point::new(-120.7401f64, 47.7511f64); + + assert_relative_eq!( + p1.cross_track_distance_geodesic(&line_point_a, &line_point_b), + 1_546_716., + epsilon = 1.0 + ); + } +} diff --git a/geo/src/algorithm/cross_track_distance_haversine.rs b/geo/src/algorithm/cross_track_distance_haversine.rs new file mode 100644 index 000000000..a9bbb0129 --- /dev/null +++ b/geo/src/algorithm/cross_track_distance_haversine.rs @@ -0,0 +1,120 @@ +use crate::{HaversineBearing, HaversineDistance, MEAN_EARTH_RADIUS}; +use geo_types::{CoordFloat, Point}; +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. +pub trait CrossTrackDistanceHaversine { + /// Determine the cross track distance between this point and a line + /// which passes through line_point_a and line_point_b + /// + /// # Units + /// + /// - return value: meters + /// + /// # Example + /// + /// ```rust + /// use geo::prelude::*; + /// use geo::point; + /// + /// // New York City + /// let p1 = point!(x: -74.006f64, y: 40.7128f64); + /// + /// // Miami + /// let line_point_a = point!(x: -80.1918f64, y: 25.7617f64); + /// + /// // Washington + /// let line_point_b = point!(x: -120.7401, y: 47.7511f64); + /// + /// let distance = p1.cross_track_distance_haversine(&line_point_a, &line_point_b); + /// + /// assert_eq!( + /// 1_547_104., // meters + /// distance.round() + /// ); + /// ``` + fn cross_track_distance_haversine(&self, line_point_a: &Rhs, line_point_b: &Rhs) -> T; +} + +impl CrossTrackDistanceHaversine> for Point +where + T: CoordFloat + FromPrimitive, +{ + fn cross_track_distance_haversine( + &self, + line_point_a: &Point, + line_point_b: &Point, + ) -> T { + let mean_earth_radius = T::from(MEAN_EARTH_RADIUS).unwrap(); + let l_delta_13: T = line_point_a.haversine_distance(self) / mean_earth_radius; + let theta_13: T = line_point_a.haversine_bearing(*self).to_radians(); + let theta_12: T = line_point_a.haversine_bearing(*line_point_b).to_radians(); + let l_delta_xt: T = (l_delta_13.sin() * (theta_12 - theta_13).sin()).asin(); + mean_earth_radius * l_delta_xt.abs() + } +} + +#[cfg(test)] +mod test { + use crate::CrossTrackDistanceHaversine; + use crate::HaversineDistance; + use crate::Point; + + #[test] + fn distance1_test() { + let p = Point::new(-0.7972, 53.2611); + 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_haversine(&line_point_a, &line_point_b), + 307.549995, + epsilon = 1.0e-6 + ); + } + + #[test] + fn cross_track_distance_haversine_to_line_passing_through_point() { + let p = Point::new(0., 0.); + let line_point_a = Point::new(1., 0.); + let line_point_b = Point::new(2., 0.); + + assert_relative_eq!( + p.cross_track_distance_haversine(&line_point_a, &line_point_b), + 0., + epsilon = 1.0e-6 + ); + } + + #[test] + fn cross_track_distance_haversine_to_line_orthogonal_to_point() { + let p = Point::new(0., 0.); + let line_point_a = Point::new(1., -1.); + let line_point_b = Point::new(1., 1.); + + assert_relative_eq!( + p.cross_track_distance_haversine(&line_point_a, &line_point_b), + p.haversine_distance(&Point::new(1., 0.)), + epsilon = 1.0e-6 + ); + + assert_relative_eq!( + p.cross_track_distance_haversine(&line_point_b, &line_point_a), + p.haversine_distance(&Point::new(1., 0.)), + epsilon = 1.0e-6 + ); + } + + #[test] + fn new_york_to_line_between_miami_and_washington() { + let p1 = Point::new(-74.006f64, 40.7128f64); + let line_point_a = Point::new(-80.1918f64, 25.7617f64); + let line_point_b = Point::new(-120.7401f64, 47.7511f64); + + assert_relative_eq!( + p1.cross_track_distance_haversine(&line_point_a, &line_point_b), + 1_547_104., + epsilon = 1.0 + ); + } +} diff --git a/geo/src/algorithm/mod.rs b/geo/src/algorithm/mod.rs index 3fbec4109..180e735af 100644 --- a/geo/src/algorithm/mod.rs +++ b/geo/src/algorithm/mod.rs @@ -64,9 +64,13 @@ pub use convert_angle_unit::{ToDegrees, ToRadians}; pub mod convex_hull; pub use convex_hull::ConvexHull; -/// Cross track distance -pub mod cross_track_distance; -pub use cross_track_distance::CrossTrackDistance; +/// Cross track distance (Geodesic) +pub mod cross_track_distance_geodesic; +pub use cross_track_distance_geodesic::CrossTrackDistanceGeodesic; + +/// Cross track distance (Haversine) +pub mod cross_track_distance_haversine; +pub use cross_track_distance_haversine::CrossTrackDistanceHaversine; /// Determine whether a `Coord` lies inside, outside, or on the boundary of a geometry. pub mod coordinate_position; From 1ef1a76ed2a29059a3499270aab201ea3cc552fb Mon Sep 17 00:00:00 2001 From: nic Date: Mon, 15 Jan 2024 20:08:34 -0800 Subject: [PATCH 3/5] removing old cross_track_distance file --- geo/src/algorithm/cross_track_distance.rs | 116 ---------------------- 1 file changed, 116 deletions(-) delete mode 100644 geo/src/algorithm/cross_track_distance.rs diff --git a/geo/src/algorithm/cross_track_distance.rs b/geo/src/algorithm/cross_track_distance.rs deleted file mode 100644 index 37cfb8bc1..000000000 --- a/geo/src/algorithm/cross_track_distance.rs +++ /dev/null @@ -1,116 +0,0 @@ -use crate::{HaversineBearing, HaversineDistance, MEAN_EARTH_RADIUS}; -use geo_types::{CoordFloat, Point}; -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. -pub trait CrossTrackDistance { - /// Determine the cross track distance between this point and a line - /// which passes through line_point_a and line_point_b - /// - /// # Units - /// - /// - return value: meters - /// - /// # Example - /// - /// ```rust - /// use geo::prelude::*; - /// use geo::point; - /// - /// // New York City - /// let p1 = point!(x: -74.006f64, y: 40.7128f64); - /// - /// // Miami - /// let line_point_a = point!(x: -80.1918f64, y: 25.7617f64); - /// - /// // Washington - /// let line_point_b = point!(x: -120.7401, y: 47.7511f64); - /// - /// let distance = p1.cross_track_distance(&line_point_a, &line_point_b); - /// - /// assert_eq!( - /// 1_547_104., // meters - /// distance.round() - /// ); - /// ``` - 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 { - let mean_earth_radius = T::from(MEAN_EARTH_RADIUS).unwrap(); - let l_delta_13: T = line_point_a.haversine_distance(self) / mean_earth_radius; - let theta_13: T = line_point_a.haversine_bearing(*self).to_radians(); - let theta_12: T = line_point_a.haversine_bearing(*line_point_b).to_radians(); - let l_delta_xt: T = (l_delta_13.sin() * (theta_12 - theta_13).sin()).asin(); - mean_earth_radius * l_delta_xt.abs() - } -} - -#[cfg(test)] -mod test { - use crate::CrossTrackDistance; - use crate::HaversineDistance; - use crate::Point; - - #[test] - fn distance1_test() { - let p = Point::new(-0.7972, 53.2611); - 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), - 307.549995, - epsilon = 1.0e-6 - ); - } - - #[test] - fn cross_track_distance_to_line_passing_through_point() { - let p = Point::new(0., 0.); - let line_point_a = Point::new(1., 0.); - let line_point_b = Point::new(2., 0.); - - assert_relative_eq!( - p.cross_track_distance(&line_point_a, &line_point_b), - 0., - epsilon = 1.0e-6 - ); - } - - #[test] - fn cross_track_distance_to_line_orthogonal_to_point() { - let p = Point::new(0., 0.); - let line_point_a = Point::new(1., -1.); - let line_point_b = Point::new(1., 1.); - - assert_relative_eq!( - p.cross_track_distance(&line_point_a, &line_point_b), - p.haversine_distance(&Point::new(1., 0.)), - epsilon = 1.0e-6 - ); - - assert_relative_eq!( - p.cross_track_distance(&line_point_b, &line_point_a), - p.haversine_distance(&Point::new(1., 0.)), - epsilon = 1.0e-6 - ); - } - - #[test] - fn new_york_to_line_between_miami_and_washington() { - let p1 = Point::new(-74.006f64, 40.7128f64); - let line_point_a = Point::new(-80.1918f64, 25.7617f64); - let line_point_b = Point::new(-120.7401f64, 47.7511f64); - - assert_relative_eq!( - p1.cross_track_distance(&line_point_a, &line_point_b), - 1_547_104., - epsilon = 1.0 - ); - } -} From d16226079ffdb2cfaaf1d0fc4713de1555ec538c Mon Sep 17 00:00:00 2001 From: nic Date: Wed, 31 Jan 2024 14:56:21 -0800 Subject: [PATCH 4/5] fixing error in doctest --- geo/src/algorithm/cross_track_distance_geodesic.rs | 2 +- geo/src/algorithm/cross_track_distance_haversine.rs | 13 ------------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/geo/src/algorithm/cross_track_distance_geodesic.rs b/geo/src/algorithm/cross_track_distance_geodesic.rs index 23b63f1e8..e1f4ecf8a 100644 --- a/geo/src/algorithm/cross_track_distance_geodesic.rs +++ b/geo/src/algorithm/cross_track_distance_geodesic.rs @@ -30,7 +30,7 @@ pub trait CrossTrackDistanceGeodesic { /// let distance = p1.cross_track_distance_geodesic(&line_point_a, &line_point_b); /// /// assert_eq!( - /// 1_546_716., // meters + /// 1_546_717., // meters /// distance.round() /// ); /// ``` diff --git a/geo/src/algorithm/cross_track_distance_haversine.rs b/geo/src/algorithm/cross_track_distance_haversine.rs index 616d009b2..c767fc8b1 100644 --- a/geo/src/algorithm/cross_track_distance_haversine.rs +++ b/geo/src/algorithm/cross_track_distance_haversine.rs @@ -57,7 +57,6 @@ where #[cfg(test)] mod test { - use crate::CrossTrackDistanceHaversine; use crate::CrossTrackDistanceHaversine; use crate::HaversineDistance; use crate::Point; @@ -68,7 +67,6 @@ 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_haversine(&line_point_a, &line_point_b), p.cross_track_distance_haversine(&line_point_a, &line_point_b), 307.549995, epsilon = 1.0e-6 @@ -76,14 +74,12 @@ mod test { } #[test] - fn cross_track_distance_haversine_to_line_passing_through_point() { fn cross_track_distance_haversine_to_line_passing_through_point() { let p = Point::new(0., 0.); let line_point_a = Point::new(1., 0.); let line_point_b = Point::new(2., 0.); assert_relative_eq!( - p.cross_track_distance_haversine(&line_point_a, &line_point_b), p.cross_track_distance_haversine(&line_point_a, &line_point_b), 0., epsilon = 1.0e-6 @@ -91,7 +87,6 @@ mod test { } #[test] - fn cross_track_distance_haversine_to_line_orthogonal_to_point() { fn cross_track_distance_haversine_to_line_orthogonal_to_point() { let p = Point::new(0., 0.); let line_point_a = Point::new(1., -1.); @@ -99,14 +94,6 @@ mod test { assert_relative_eq!( p.cross_track_distance_haversine(&line_point_a, &line_point_b), - p.cross_track_distance_haversine(&line_point_a, &line_point_b), - p.haversine_distance(&Point::new(1., 0.)), - epsilon = 1.0e-6 - ); - - assert_relative_eq!( - p.cross_track_distance_haversine(&line_point_b, &line_point_a), - p.cross_track_distance_haversine(&line_point_b, &line_point_a), p.haversine_distance(&Point::new(1., 0.)), epsilon = 1.0e-6 ); From 51e9b3410cedeed9c44122b27c42e0d2ed718e79 Mon Sep 17 00:00:00 2001 From: nic Date: Wed, 31 Jan 2024 14:59:55 -0800 Subject: [PATCH 5/5] changing precision to 1e-4 --- geo/src/algorithm/cross_track_distance_geodesic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/geo/src/algorithm/cross_track_distance_geodesic.rs b/geo/src/algorithm/cross_track_distance_geodesic.rs index e1f4ecf8a..95ac8e3f7 100644 --- a/geo/src/algorithm/cross_track_distance_geodesic.rs +++ b/geo/src/algorithm/cross_track_distance_geodesic.rs @@ -75,7 +75,7 @@ impl CrossTrackDistanceGeodesic for Point { let (pa2_y, pa2_x) = geod.direct(lpa_y, lpa_x, azi1_ab, s_ax); - if s_ax.abs() < 1e-2 { + if s_ax.abs() < 1e-4 { return s_ap; }