galileo_types/geo/traits/
point.rs

1use num_traits::Float;
2
3use crate::geo::traits::projection::Projection;
4use crate::geometry::{Geom, GeometrySpecialization};
5use crate::geometry_type::{GeoSpace2d, GeometryType, PointGeometryType};
6
7/// 2d point on the surface of a celestial body.
8pub trait GeoPoint {
9    /// Numeric type used to represent coordinates.
10    type Num: Float;
11
12    /// Latitude in degrees.
13    fn lat(&self) -> Self::Num;
14    /// Longitude in degrees.
15    fn lon(&self) -> Self::Num;
16
17    /// Latitude in radians.
18    fn lat_rad(&self) -> Self::Num {
19        self.lat().to_radians()
20    }
21
22    /// Longitude in radians.
23    fn lon_rad(&self) -> Self::Num {
24        self.lon().to_radians()
25    }
26}
27
28/// Trait for points that can be constructed by only coordinates.
29pub trait NewGeoPoint<N = f64>: GeoPoint<Num = N> + Sized {
30    /// Create a point from *latitude* and *longitude*.
31    fn latlon(lat: N, lon: N) -> Self;
32    /// Create a point from *longitude* and *latitude*.
33    fn lonlat(lon: N, lat: N) -> Self {
34        Self::latlon(lat, lon)
35    }
36}
37
38impl<P> GeometrySpecialization<PointGeometryType, GeoSpace2d> for P
39where
40    P: GeoPoint + GeometryType<Type = PointGeometryType, Space = GeoSpace2d>,
41{
42    type Point = P;
43
44    fn project_spec<Proj>(&self, projection: &Proj) -> Option<Geom<Proj::OutPoint>>
45    where
46        Proj: Projection<InPoint = Self::Point> + ?Sized,
47    {
48        Some(Geom::Point(projection.project(self)?))
49    }
50}