geo/algorithm/geodesic_distance.rs
1use crate::Point;
2use geographiclib_rs::{Geodesic, InverseGeodesic};
3
4/// Determine the distance between two geometries on an ellipsoidal model of the earth.
5///
6/// This uses the geodesic measurement methods given by [Karney (2013)]. As opposed to older methods
7/// like Vincenty, this method is accurate to a few nanometers and always converges.
8///
9/// [Karney (2013)]: https://arxiv.org/pdf/1109.4448.pdf
10pub trait GeodesicDistance<T, Rhs = Self> {
11 /// Determine the distance between two geometries on an ellipsoidal model of the earth.
12 ///
13 /// This uses the geodesic measurement methods given by [Karney (2013)]. As opposed to older methods
14 /// like Vincenty, this method is accurate to a few nanometers and always converges.
15 ///
16 /// # Units
17 ///
18 /// - return value: meters
19 ///
20 /// # Examples
21 /// ```rust
22 /// use geo::prelude::*;
23 /// use geo::point;
24 ///
25 /// // New York City
26 /// let p1 = point!(x: -74.006, y: 40.7128);
27 ///
28 /// // London
29 /// let p2 = point!(x: -0.1278, y: 51.5074);
30 ///
31 /// let distance = p1.geodesic_distance(&p2);
32 ///
33 /// assert_eq!(
34 /// 5_585_234., // meters
35 /// distance.round()
36 /// );
37 /// ```
38 /// [Karney (2013)]: https://arxiv.org/pdf/1109.4448.pdf
39 fn geodesic_distance(&self, rhs: &Rhs) -> T;
40}
41
42impl GeodesicDistance<f64> for Point {
43 fn geodesic_distance(&self, rhs: &Point) -> f64 {
44 Geodesic::wgs84().inverse(self.y(), self.x(), rhs.y(), rhs.x())
45 }
46}