geometry_strategy/spherical/
distance_cross_track.rs1use geometry_cs::{CoordinateSystem, SphericalFamily};
7use geometry_model::Segment;
8use geometry_tag::SameAs;
9use geometry_trait::{Point, PointMut};
10
11use crate::distance::DistanceStrategy;
12use crate::normalise::HasAngularUnits;
13
14use super::great_circle;
15
16#[derive(Debug, Clone, Copy)]
18pub struct CrossTrack {
19 pub radius: f64,
21}
22
23impl CrossTrack {
24 pub const EARTH: Self = Self {
26 radius: 6_372_795.0,
27 };
28 pub const UNIT: Self = Self { radius: 1.0 };
30}
31
32impl Default for CrossTrack {
33 fn default() -> Self {
34 Self::EARTH
35 }
36}
37
38impl<P> DistanceStrategy<P, Segment<P>> for CrossTrack
39where
40 P: Point<Scalar = f64> + PointMut + Default + Copy,
41 P::Cs: HasAngularUnits,
42 <P::Cs as CoordinateSystem>::Family: SameAs<SphericalFamily>,
43{
44 type Out = f64;
45 type Comparable = Self;
46
47 fn distance(&self, point: &P, segment: &Segment<P>) -> Self::Out {
48 great_circle::project(point, segment.start(), segment.end()).angular_distance * self.radius
49 }
50
51 fn comparable(&self) -> Self::Comparable {
52 *self
53 }
54}
55
56impl<P> DistanceStrategy<Segment<P>, P> for CrossTrack
57where
58 P: Point<Scalar = f64> + PointMut + Default + Copy,
59 P::Cs: HasAngularUnits,
60 <P::Cs as CoordinateSystem>::Family: SameAs<SphericalFamily>,
61{
62 type Out = f64;
63 type Comparable = Self;
64
65 fn distance(&self, segment: &Segment<P>, point: &P) -> Self::Out {
66 <Self as DistanceStrategy<P, Segment<P>>>::distance(self, point, segment)
67 }
68
69 fn comparable(&self) -> Self::Comparable {
70 *self
71 }
72}