geo/algorithm/rhumb/
distance.rs

1use crate::{CoordFloat, Distance, Point, Rhumb};
2use num_traits::FromPrimitive;
3
4#[deprecated(
5    since = "0.29.0",
6    note = "Please use the `Rhumb.distance` method from the `Distance` trait instead"
7)]
8/// Determine the distance between two geometries along a [rhumb line].
9///
10/// [rhumb line]: https://en.wikipedia.org/wiki/Rhumb_line
11///
12/// *Note*: this implementation uses a mean earth radius of 6371.088 km, based on the [recommendation of
13/// the IUGG](ftp://athena.fsv.cvut.cz/ZFG/grs80-Moritz.pdf)
14pub trait RhumbDistance<T, Rhs = Self> {
15    /// Determine the distance between along the [rhumb line] between two geometries.
16    ///
17    /// # Units
18    ///
19    /// - return value: meters
20    ///
21    /// # Examples
22    ///
23    /// ```rust
24    /// use geo::prelude::*;
25    /// use geo::point;
26    ///
27    /// // New York City
28    /// let p1 = point!(x: -74.006f64, y: 40.7128f64);
29    ///
30    /// // London
31    /// let p2 = point!(x: -0.1278f64, y: 51.5074f64);
32    ///
33    /// # #[allow(deprecated)]
34    /// let distance = p1.rhumb_distance(&p2);
35    ///
36    /// assert_eq!(
37    ///     5_794_129., // meters
38    ///     distance.round()
39    /// );
40    /// ```
41    ///
42    /// [rhumb line]: https://en.wikipedia.org/wiki/Rhumb_line
43    fn rhumb_distance(&self, rhs: &Rhs) -> T;
44}
45
46#[allow(deprecated)]
47impl<T> RhumbDistance<T, Point<T>> for Point<T>
48where
49    T: CoordFloat + FromPrimitive,
50{
51    fn rhumb_distance(&self, rhs: &Point<T>) -> T {
52        Rhumb.distance(*self, *rhs)
53    }
54}
55
56#[cfg(test)]
57mod test {
58    use crate::Point;
59    #[allow(deprecated)]
60    use crate::RhumbDistance;
61
62    #[test]
63    fn distance1_test() {
64        let a = Point::new(0., 0.);
65        let b = Point::new(1., 0.);
66        #[allow(deprecated)]
67        let distance = a.rhumb_distance(&b);
68        assert_relative_eq!(distance, 111195.0802335329_f64, epsilon = 1.0e-6);
69    }
70
71    #[test]
72    fn distance2_test() {
73        let a = Point::new(-72.1235, 42.3521);
74        let b = Point::new(72.1260, 70.612);
75        #[allow(deprecated)]
76        let distance = a.rhumb_distance(&b);
77        assert_relative_eq!(distance, 8903668.508603323_f64, epsilon = 1.0e-6);
78    }
79
80    #[test]
81    fn distance3_test() {
82        // this input comes from issue #100
83        let a = Point::new(-77.036585, 38.897448);
84        let b = Point::new(-77.009080, 38.889825);
85        #[allow(deprecated)]
86        let distance = a.rhumb_distance(&b);
87        assert_relative_eq!(distance, 2526.823513863995_f64, epsilon = 1.0e-6);
88    }
89
90    #[test]
91    fn distance3_test_f32() {
92        // this input comes from issue #100
93        let a = Point::<f32>::new(-77.03658, 38.89745);
94        let b = Point::<f32>::new(-77.00908, 38.889825);
95        #[allow(deprecated)]
96        let distance = a.rhumb_distance(&b);
97        assert_relative_eq!(distance, 2527.4585_f32, epsilon = 1.0e-6);
98    }
99}