s2json_core/geometry/
primitive.rs

1use crate::*;
2use alloc::vec::Vec;
3use serde::{Deserialize, Serialize};
4
5/// Definition of a Point. May represent WebMercator Lon-Lat or S2Geometry S-T
6#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Default)]
7pub struct Point(pub f64, pub f64);
8/// Definition of a MultiPoint
9pub type MultiPoint = Vec<Point>;
10/// Definition of a LineString
11pub type LineString = Vec<Point>;
12/// Definition of a MultiLineString
13pub type MultiLineString = Vec<LineString>;
14/// Definition of a Polygon
15pub type Polygon = Vec<Vec<Point>>;
16/// Definition of a MultiPolygon
17pub type MultiPolygon = Vec<Polygon>;
18/// Definition of a 3D Point. May represent WebMercator Lon-Lat or S2Geometry S-T with a z-value
19#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Default)]
20pub struct Point3D(pub f64, pub f64, pub f64);
21/// Definition of a 3D MultiPoint
22pub type MultiPoint3D = Vec<Point3D>;
23/// Definition of a 3D LineString
24pub type LineString3D = Vec<Point3D>;
25/// Definition of a 3D MultiLineString
26pub type MultiLineString3D = Vec<LineString3D>;
27/// Definition of a 3D Polygon
28pub type Polygon3D = Vec<Vec<Point3D>>;
29/// Definition of a 3D MultiPolygon
30pub type MultiPolygon3D = Vec<Polygon3D>;
31/// Define a Point or Point3D
32#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Default)]
33pub struct PointOrPoint3D(pub f64, pub f64, pub Option<f64>);
34
35impl From<Point> for PointOrPoint3D {
36    fn from(p: Point) -> Self {
37        PointOrPoint3D(p.0, p.1, None)
38    }
39}
40
41impl From<Point3D> for PointOrPoint3D {
42    fn from(p: Point3D) -> Self {
43        PointOrPoint3D(p.0, p.1, Some(p.2))
44    }
45}
46
47/// Enum to represent specific geometry types as strings
48#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)]
49pub enum GeometryType {
50    /// Point
51    #[default]
52    Point,
53    /// MultiPoint
54    MultiPoint,
55    /// LineString
56    LineString,
57    /// MultiLineString
58    MultiLineString,
59    /// Polygon
60    Polygon,
61    /// MultiPolygon
62    MultiPolygon,
63    /// 3D Point
64    Point3D,
65    /// 3D MultiPoint
66    MultiPoint3D,
67    /// 3D LineString
68    LineString3D,
69    /// 3D MultiLineString
70    MultiLineString3D,
71    /// 3D Polygon
72    Polygon3D,
73    /// 3D MultiPolygon
74    MultiPolygon3D,
75}
76impl From<&str> for GeometryType {
77    fn from(s: &str) -> Self {
78        match s {
79            "Point" => GeometryType::Point,
80            "MultiPoint" => GeometryType::MultiPoint,
81            "LineString" => GeometryType::LineString,
82            "MultiLineString" => GeometryType::MultiLineString,
83            "Polygon" => GeometryType::Polygon,
84            "MultiPolygon" => GeometryType::MultiPolygon,
85            "Point3D" => GeometryType::Point3D,
86            "MultiPoint3D" => GeometryType::MultiPoint3D,
87            "LineString3D" => GeometryType::LineString3D,
88            "MultiLineString3D" => GeometryType::MultiLineString3D,
89            "Polygon3D" => GeometryType::Polygon3D,
90            "MultiPolygon3D" => GeometryType::MultiPolygon3D,
91            _ => unreachable!(),
92        }
93    }
94}
95
96/// All possible geometry shapes
97#[derive(Clone, Serialize, Debug, PartialEq)]
98#[serde(untagged)]
99pub enum Geometry<M: MValueCompatible = MValue> {
100    /// Point Shape
101    Point(PointGeometry<M>),
102    /// MultiPoint Shape
103    MultiPoint(MultiPointGeometry<M>),
104    /// LineString Shape
105    LineString(LineStringGeometry<M>),
106    /// MultiLineString Shape
107    MultiLineString(MultiLineStringGeometry<M>),
108    /// Polygon Shape
109    Polygon(PolygonGeometry<M>),
110    /// MultiPolygon Shape
111    MultiPolygon(MultiPolygonGeometry<M>),
112    /// Point3D Shape
113    Point3D(Point3DGeometry<M>),
114    /// MultiPoint3D Shape
115    MultiPoint3D(MultiPoint3DGeometry<M>),
116    /// LineString3D Shape
117    LineString3D(LineString3DGeometry<M>),
118    /// MultiLineString3D Shape
119    MultiLineString3D(MultiLineString3DGeometry<M>),
120    /// Polygon3D Shape
121    Polygon3D(Polygon3DGeometry<M>),
122    /// MultiPolygon3D Shape
123    MultiPolygon3D(MultiPolygon3DGeometry<M>),
124}
125// We have to manually implement the Deserialize trait to fix a compilation error
126#[doc(hidden)]
127#[allow(unused_extern_crates, clippy::useless_attribute)]
128extern crate serde as _serde;
129#[automatically_derived]
130#[coverage(off)]
131impl<'de, M: MValueCompatible> _serde::Deserialize<'de> for Geometry<M>
132where
133    M: _serde::Deserialize<'de>,
134{
135    fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
136    where
137        __D: _serde::Deserializer<'de>,
138    {
139        let __content =
140            <_serde::__private::de::Content as _serde::Deserialize>::deserialize(__deserializer)?;
141        let __deserializer =
142            _serde::__private::de::ContentRefDeserializer::<__D::Error>::new(&__content);
143        if let _serde::__private::Ok(__ok) = _serde::__private::Result::map(
144            <PointGeometry<M> as _serde::Deserialize>::deserialize(__deserializer),
145            Geometry::Point,
146        ) {
147            return _serde::__private::Ok(__ok);
148        }
149        // Attempt to deserialize as MultiPoint then check for LineString
150        if let _serde::__private::Ok(__ok) = _serde::__private::Result::map(
151            <MultiPointGeometry<M> as _serde::Deserialize>::deserialize(__deserializer),
152            Geometry::MultiPoint,
153        ) {
154            // pull out the MultiPoint variant
155            if let Geometry::MultiPoint(multipoint) = &__ok {
156                if multipoint._type == GeometryType::LineString {
157                    // If deserialization succeeds as MultiPoint, check if content is LineString
158                    if let _serde::__private::Ok(__ok2) = _serde::__private::Result::map(
159                        <LineStringGeometry<M> as _serde::Deserialize>::deserialize(__deserializer),
160                        Geometry::LineString,
161                    ) {
162                        // If LineString is found, return LineString variant
163                        return _serde::__private::Ok(__ok2);
164                    }
165                }
166            }
167            return _serde::__private::Ok(__ok);
168        }
169        if let _serde::__private::Ok(__ok) = _serde::__private::Result::map(
170            <MultiLineStringGeometry<M> as _serde::Deserialize>::deserialize(__deserializer),
171            Geometry::MultiLineString,
172        ) {
173            // pull out the MultiLineString variant
174            if let Geometry::MultiLineString(multilinestring) = &__ok {
175                if multilinestring._type == GeometryType::Polygon {
176                    if let _serde::__private::Ok(__ok2) = _serde::__private::Result::map(
177                        <PolygonGeometry<M> as _serde::Deserialize>::deserialize(__deserializer),
178                        Geometry::Polygon,
179                    ) {
180                        return _serde::__private::Ok(__ok2);
181                    }
182                }
183            }
184            return _serde::__private::Ok(__ok);
185        }
186        if let _serde::__private::Ok(__ok) = _serde::__private::Result::map(
187            <MultiPolygonGeometry<M> as _serde::Deserialize>::deserialize(__deserializer),
188            Geometry::MultiPolygon,
189        ) {
190            return _serde::__private::Ok(__ok);
191        }
192        if let _serde::__private::Ok(__ok) = _serde::__private::Result::map(
193            <Point3DGeometry<M> as _serde::Deserialize>::deserialize(__deserializer),
194            Geometry::Point3D,
195        ) {
196            return _serde::__private::Ok(__ok);
197        }
198        if let _serde::__private::Ok(__ok) = _serde::__private::Result::map(
199            <MultiPoint3DGeometry<M> as _serde::Deserialize>::deserialize(__deserializer),
200            Geometry::MultiPoint3D,
201        ) {
202            // pull out the MultiPoint3D variant
203            if let Geometry::MultiPoint3D(multipoint3d) = &__ok {
204                if multipoint3d._type == GeometryType::LineString3D {
205                    if let _serde::__private::Ok(__ok2) = _serde::__private::Result::map(
206                        <LineString3DGeometry<M> as _serde::Deserialize>::deserialize(
207                            __deserializer,
208                        ),
209                        Geometry::LineString3D,
210                    ) {
211                        return _serde::__private::Ok(__ok2);
212                    }
213                }
214            }
215            return _serde::__private::Ok(__ok);
216        }
217        if let _serde::__private::Ok(__ok) = _serde::__private::Result::map(
218            <MultiLineString3DGeometry<M> as _serde::Deserialize>::deserialize(__deserializer),
219            Geometry::MultiLineString3D,
220        ) {
221            // pull out the MultiLineString3D variant
222            if let Geometry::MultiLineString3D(multilinestring3d) = &__ok {
223                if multilinestring3d._type == GeometryType::Polygon3D {
224                    if let _serde::__private::Ok(__ok2) = _serde::__private::Result::map(
225                        <Polygon3DGeometry<M> as _serde::Deserialize>::deserialize(__deserializer),
226                        Geometry::Polygon3D,
227                    ) {
228                        return _serde::__private::Ok(__ok2);
229                    }
230                }
231            }
232            return _serde::__private::Ok(__ok);
233        }
234        if let _serde::__private::Ok(__ok) = _serde::__private::Result::map(
235            <MultiPolygon3DGeometry<M> as _serde::Deserialize>::deserialize(__deserializer),
236            Geometry::MultiPolygon3D,
237        ) {
238            return _serde::__private::Ok(__ok);
239        }
240        _serde::__private::Err(_serde::de::Error::custom(
241            "data did not match any variant of untagged enum Geometry",
242        ))
243    }
244}
245impl<M: MValueCompatible> Default for Geometry<M> {
246    fn default() -> Self {
247        Geometry::Point(PointGeometry::<M>::default())
248    }
249}
250
251/// BaseGeometry is the a generic geometry type
252#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)]
253pub struct BaseGeometry<M = MValue, G = Geometry<M>, B = BBOX> {
254    /// The geometry type
255    #[serde(rename = "type")]
256    pub _type: GeometryType,
257    /// The geometry shape
258    pub coordinates: G,
259    /// The M-Values shape
260    #[serde(rename = "mValues", skip_serializing_if = "Option::is_none")]
261    pub m_values: Option<M>,
262    /// The BBox shape
263    #[serde(skip_serializing_if = "Option::is_none")]
264    pub bbox: Option<B>,
265}
266
267/// PointGeometry is a point
268pub type PointGeometry<M = MValue> = BaseGeometry<M, Point, BBox>;
269/// MultiPointGeometry contains multiple points
270pub type MultiPointGeometry<M = MValue> = BaseGeometry<LineStringMValues<M>, MultiPoint, BBox>;
271/// LineStringGeometry is a line
272pub type LineStringGeometry<M = MValue> = BaseGeometry<LineStringMValues<M>, LineString, BBox>;
273/// MultiLineStringGeometry contains multiple lines
274pub type MultiLineStringGeometry<M = MValue> =
275    BaseGeometry<MultiLineStringMValues<M>, MultiLineString, BBox>;
276/// PolygonGeometry is a polygon with potential holes
277pub type PolygonGeometry<M = MValue> = BaseGeometry<PolygonMValues<M>, Polygon, BBox>;
278/// MultiPolygonGeometry is a polygon with multiple polygons with their own potential holes
279pub type MultiPolygonGeometry<M = MValue> =
280    BaseGeometry<MultiPolygonMValues<M>, MultiPolygon, BBox>;
281/// Point3DGeometry is a 3D point
282pub type Point3DGeometry<M = MValue> = BaseGeometry<M, Point3D, BBox3D>;
283/// MultiPoint3DGeometry contains multiple 3D points
284pub type MultiPoint3DGeometry<M = MValue> =
285    BaseGeometry<LineStringMValues<M>, MultiPoint3D, BBox3D>;
286/// LineString3DGeometry is a 3D line
287pub type LineString3DGeometry<M = MValue> =
288    BaseGeometry<LineStringMValues<M>, LineString3D, BBox3D>;
289/// MultiLineString3DGeometry contains multiple 3D lines
290pub type MultiLineString3DGeometry<M = MValue> =
291    BaseGeometry<MultiLineStringMValues<M>, MultiLineString3D, BBox3D>;
292/// Polygon3DGeometry is a 3D polygon with potential holes
293pub type Polygon3DGeometry<M = MValue> = BaseGeometry<PolygonMValues<M>, Polygon3D, BBox3D>;
294/// MultiPolygon3DGeometry is a 3D polygon with multiple polygons with their own potential holes
295pub type MultiPolygon3DGeometry<M = MValue> =
296    BaseGeometry<MultiPolygonMValues<M>, MultiPolygon3D, BBox3D>;