geo/algorithm/
geodesic_intermediate.rs

1use crate::{CoordFloat, Geodesic, InterpolatePoint, Point};
2
3#[deprecated(
4    since = "0.29.0",
5    note = "Please use the `InterpolatePoint` trait instead"
6)]
7/// Returns a new Point along a route between two existing points on an ellipsoidal model of the earth
8pub trait GeodesicIntermediate<T: CoordFloat> {
9    #[deprecated(
10        since = "0.29.0",
11        note = "Please use `Geodesic.point_at_ratio_between` from the `InterpolatePoint` trait instead"
12    )]
13    /// Returns a new Point along a route between two existing points on an ellipsoidal model of the earth
14    ///
15    /// # Examples
16    ///
17    /// ```
18    /// # use approx::assert_relative_eq;
19    /// # #[allow(deprecated)]
20    /// use geo::GeodesicIntermediate;
21    /// use geo::Point;
22    ///
23    /// let p1 = Point::new(10.0, 20.0);
24    /// let p2 = Point::new(125.0, 25.0);
25    /// # #[allow(deprecated)]
26    /// let i20 = p1.geodesic_intermediate(&p2, 0.2);
27    /// # #[allow(deprecated)]
28    /// let i50 = p1.geodesic_intermediate(&p2, 0.5);
29    /// # #[allow(deprecated)]
30    /// let i80 = p1.geodesic_intermediate(&p2, 0.8);
31    /// let i20_should = Point::new(29.842907, 29.951445);
32    /// let i50_should = Point::new(65.879360, 37.722253);
33    /// let i80_should = Point::new(103.556796, 33.506196);
34    /// assert_relative_eq!(i20, i20_should, epsilon = 1.0e-6);
35    /// assert_relative_eq!(i50, i50_should, epsilon = 1.0e-6);
36    /// assert_relative_eq!(i80, i80_should, epsilon = 1.0e-6);
37    /// ```
38    fn geodesic_intermediate(&self, other: &Point<T>, f: T) -> Point<T>;
39
40    #[deprecated(
41        since = "0.29.0",
42        note = "Please use `Geodesic.points_along_line` from the `InterpolatePoint` trait instead"
43    )]
44    fn geodesic_intermediate_fill(
45        &self,
46        other: &Point<T>,
47        max_dist: T,
48        include_ends: bool,
49    ) -> Vec<Point<T>>;
50}
51
52#[allow(deprecated)]
53impl GeodesicIntermediate<f64> for Point {
54    fn geodesic_intermediate(&self, other: &Point, f: f64) -> Point {
55        Geodesic.point_at_ratio_between(*self, *other, f)
56    }
57
58    fn geodesic_intermediate_fill(
59        &self,
60        other: &Point,
61        max_dist: f64,
62        include_ends: bool,
63    ) -> Vec<Point> {
64        Geodesic
65            .points_along_line(*self, *other, max_dist, include_ends)
66            .collect()
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73    use approx::assert_relative_eq;
74
75    #[test]
76    fn f_is_zero_or_one_test() {
77        let p1 = Point::new(10.0, 20.0);
78        let p2 = Point::new(15.0, 25.0);
79        #[allow(deprecated)]
80        let i0 = p1.geodesic_intermediate(&p2, 0.0);
81        #[allow(deprecated)]
82        let i100 = p1.geodesic_intermediate(&p2, 1.0);
83        assert_relative_eq!(i0, p1, epsilon = 1.0e-6);
84        assert_relative_eq!(i100, p2, epsilon = 1.0e-6);
85    }
86
87    #[test]
88    fn various_f_values_test() {
89        let p1 = Point::new(10.0, 20.0);
90        let p2 = Point::new(125.0, 25.0);
91        #[allow(deprecated)]
92        let i20 = p1.geodesic_intermediate(&p2, 0.2);
93        #[allow(deprecated)]
94        let i50 = p1.geodesic_intermediate(&p2, 0.5);
95        #[allow(deprecated)]
96        let i80 = p1.geodesic_intermediate(&p2, 0.8);
97        let i20_should = Point::new(29.842907, 29.951445);
98        let i50_should = Point::new(65.879360, 37.722253);
99        let i80_should = Point::new(103.556796, 33.506196);
100        assert_relative_eq!(i20, i20_should, epsilon = 1.0e-6);
101        assert_relative_eq!(i50, i50_should, epsilon = 1.0e-6);
102        assert_relative_eq!(i80, i80_should, epsilon = 1.0e-6);
103    }
104
105    #[test]
106    fn should_add_i50_test() {
107        let p1 = Point::new(30.0, 40.0);
108        let p2 = Point::new(40.0, 50.0);
109        let max_dist = 1000000.0; // meters
110        let include_ends = true;
111        #[allow(deprecated)]
112        let i50 = p1.geodesic_intermediate(&p2, 0.5);
113        #[allow(deprecated)]
114        let route = p1.geodesic_intermediate_fill(&p2, max_dist, include_ends);
115        assert_eq!(route, vec![p1, i50, p2]);
116    }
117}