galileo_types/
disambig.rs

1use std::marker::PhantomData;
2
3use crate::cartesian::{CartesianPoint2d, NewCartesianPoint2d};
4use crate::contour::Contour;
5use crate::geo::{GeoPoint, NewGeoPoint};
6use crate::geometry_type::{AmbiguousSpace, CartesianSpace2d, GeoSpace2d, GeometryType};
7use crate::multi_contour::MultiContour;
8use crate::multi_point::MultiPoint;
9use crate::multi_polygon::MultiPolygon;
10use crate::polygon::Polygon;
11
12/// Wrapper type that disambiguates coordinate space for generic geometries.
13///
14/// See [`Disambiguate`] trait documentation for details.
15pub struct Disambig<T, Space> {
16    inner: T,
17    space: PhantomData<Space>,
18}
19
20impl<T, Space> Disambig<T, Space> {
21    /// Creates a new instance.
22    pub fn new(inner: T) -> Self {
23        Self {
24            inner,
25            space: Default::default(),
26        }
27    }
28}
29
30impl<T: Clone, Space> Clone for Disambig<T, Space> {
31    fn clone(&self) -> Self {
32        Self {
33            inner: self.inner.clone(),
34            space: Default::default(),
35        }
36    }
37}
38
39impl<T: GeometryType, Space> GeometryType for Disambig<T, Space> {
40    type Type = T::Type;
41    type Space = Space;
42}
43
44impl<T: CartesianPoint2d> CartesianPoint2d for Disambig<T, CartesianSpace2d> {
45    type Num = T::Num;
46
47    fn x(&self) -> Self::Num {
48        self.inner.x()
49    }
50
51    fn y(&self) -> Self::Num {
52        self.inner.y()
53    }
54}
55
56impl<T: GeoPoint> GeoPoint for Disambig<T, GeoSpace2d> {
57    type Num = T::Num;
58
59    fn lat(&self) -> Self::Num {
60        self.inner.lat()
61    }
62
63    fn lon(&self) -> Self::Num {
64        self.inner.lon()
65    }
66}
67
68impl<T: NewCartesianPoint2d> NewCartesianPoint2d for Disambig<T, CartesianSpace2d> {
69    fn new(x: f64, y: f64) -> Self {
70        Self::new(T::new(x, y))
71    }
72}
73
74impl<T: NewGeoPoint> NewGeoPoint for Disambig<T, GeoSpace2d> {
75    fn latlon(lat: f64, lon: f64) -> Self {
76        Self::new(T::latlon(lat, lon))
77    }
78}
79
80impl<T: Contour, Space> Contour for Disambig<T, Space> {
81    type Point = T::Point;
82
83    fn is_closed(&self) -> bool {
84        self.inner.is_closed()
85    }
86
87    fn iter_points(&self) -> impl Iterator<Item = Self::Point> {
88        self.inner.iter_points()
89    }
90}
91
92impl<T: Polygon, Space> Polygon for Disambig<T, Space> {
93    type Contour = T::Contour;
94
95    fn outer_contour(&self) -> &Self::Contour {
96        self.inner.outer_contour()
97    }
98
99    fn inner_contours(&self) -> impl Iterator<Item = &'_ Self::Contour> {
100        self.inner.inner_contours()
101    }
102}
103
104impl<T: MultiPoint, Space> MultiPoint for Disambig<T, Space> {
105    type Point = T::Point;
106
107    fn iter_points(&self) -> impl Iterator<Item = Self::Point> {
108        self.inner.iter_points()
109    }
110}
111
112impl<T: MultiContour, Space> MultiContour for Disambig<T, Space> {
113    type Contour = T::Contour;
114
115    fn contours(&self) -> impl Iterator<Item = &Self::Contour> {
116        self.inner.contours()
117    }
118}
119
120impl<T: MultiPolygon, Space> MultiPolygon for Disambig<T, Space> {
121    type Polygon = T::Polygon;
122
123    fn polygons(&self) -> impl Iterator<Item = &Self::Polygon> {
124        self.inner.polygons()
125    }
126}
127
128/// A trait used to convert a geometry with no specified coordinate space into one of the specific coordinate spaces.
129/// This trait is auto-implemented for all types, that implement `GeometryType<Space = AmbiguousSpace>` trait.
130pub trait Disambiguate {
131    /// Specifies that the geometry is in geographic coordinates.
132    fn to_geo2d(self) -> Disambig<Self, GeoSpace2d>
133    where
134        Self: Sized,
135    {
136        Disambig::new(self)
137    }
138
139    /// Specifies that the geometry is in cartesian coordinates.
140    fn to_cartesian2d(self) -> Disambig<Self, CartesianSpace2d>
141    where
142        Self: Sized,
143    {
144        Disambig::new(self)
145    }
146}
147
148impl<T: GeometryType<Space = AmbiguousSpace>> Disambiguate for T {}