geo/algorithm/vincenty_length.rs
1use num_traits::FromPrimitive;
2
3use crate::vincenty_distance::{FailedToConvergeError, VincentyDistance};
4use crate::{CoordFloat, Line, LineString, MultiLineString};
5
6/// Determine the length of a geometry using [Vincenty’s formulae].
7///
8/// [Vincenty’s formulae]: https://en.wikipedia.org/wiki/Vincenty%27s_formulae
9pub trait VincentyLength<T, RHS = Self> {
10 /// Determine the length of a geometry using [Vincenty’s formulae].
11 ///
12 /// # Units
13 ///
14 /// - return value: meters
15 ///
16 /// # Examples
17 ///
18 /// ```
19 /// use geo::prelude::*;
20 /// use geo::LineString;
21 ///
22 /// let linestring = LineString::<f64>::from(vec![
23 /// // New York City
24 /// (-74.006, 40.7128),
25 /// // London
26 /// (-0.1278, 51.5074),
27 /// // Osaka
28 /// (135.5244559, 34.687455)
29 /// ]);
30 ///
31 /// let length = linestring.vincenty_length().unwrap();
32 ///
33 /// assert_eq!(
34 /// 15_109_158., // meters
35 /// length.round()
36 /// );
37 /// ```
38 ///
39 /// [Vincenty’s formulae]: https://en.wikipedia.org/wiki/Vincenty%27s_formulae
40 fn vincenty_length(&self) -> Result<T, FailedToConvergeError>;
41}
42
43impl<T> VincentyLength<T> for Line<T>
44where
45 T: CoordFloat + FromPrimitive,
46{
47 /// The units of the returned value is meters.
48 fn vincenty_length(&self) -> Result<T, FailedToConvergeError> {
49 let (start, end) = self.points();
50 start.vincenty_distance(&end)
51 }
52}
53
54impl<T> VincentyLength<T> for LineString<T>
55where
56 T: CoordFloat + FromPrimitive,
57{
58 fn vincenty_length(&self) -> Result<T, FailedToConvergeError> {
59 let mut length = T::zero();
60 for line in self.lines() {
61 length = length + line.vincenty_length()?;
62 }
63 Ok(length)
64 }
65}
66
67impl<T> VincentyLength<T> for MultiLineString<T>
68where
69 T: CoordFloat + FromPrimitive,
70{
71 fn vincenty_length(&self) -> Result<T, FailedToConvergeError> {
72 let mut length = T::zero();
73 for line_string in &self.0 {
74 length = length + line_string.vincenty_length()?;
75 }
76 Ok(length)
77 }
78}