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>);
34impl From<Point> for PointOrPoint3D {
35    fn from(p: Point) -> Self {
36        PointOrPoint3D(p.0, p.1, None)
37    }
38}
39impl From<Point3D> for PointOrPoint3D {
40    fn from(p: Point3D) -> Self {
41        PointOrPoint3D(p.0, p.1, Some(p.2))
42    }
43}
44
45// GET
46
47impl GetXY for Point {
48    fn x(&self) -> f64 {
49        self.0
50    }
51    fn y(&self) -> f64 {
52        self.1
53    }
54}
55impl GetZ for Point {
56    fn z(&self) -> Option<f64> {
57        None
58    }
59}
60impl GetXYZ for Point {}
61impl GetXY for Point3D {
62    fn x(&self) -> f64 {
63        self.0
64    }
65    fn y(&self) -> f64 {
66        self.1
67    }
68}
69impl GetXY for PointOrPoint3D {
70    fn x(&self) -> f64 {
71        self.0
72    }
73    fn y(&self) -> f64 {
74        self.1
75    }
76}
77impl GetZ for Point3D {
78    fn z(&self) -> Option<f64> {
79        Some(self.2)
80    }
81}
82impl GetXYZ for Point3D {}
83impl GetZ for PointOrPoint3D {
84    fn z(&self) -> Option<f64> {
85        self.2
86    }
87}
88impl GetXYZ for PointOrPoint3D {}
89
90// SET
91
92impl SetXY for Point {
93    fn set_x(&mut self, x: f64) {
94        self.0 = x;
95    }
96    fn set_y(&mut self, y: f64) {
97        self.1 = y;
98    }
99    fn set_xy(&mut self, x: f64, y: f64) {
100        self.0 = x;
101        self.1 = y;
102    }
103}
104impl SetXY for Point3D {
105    fn set_x(&mut self, x: f64) {
106        self.0 = x;
107    }
108    fn set_y(&mut self, y: f64) {
109        self.1 = y;
110    }
111}
112impl SetZ for Point3D {
113    fn set_z(&mut self, z: f64) {
114        self.2 = z;
115    }
116}
117impl SetXYZ for Point3D {}
118impl SetXY for PointOrPoint3D {
119    fn set_x(&mut self, x: f64) {
120        self.0 = x;
121    }
122    fn set_y(&mut self, y: f64) {
123        self.1 = y;
124    }
125}
126impl SetZ for PointOrPoint3D {
127    fn set_z(&mut self, z: f64) {
128        self.2 = Some(z);
129    }
130}
131impl SetXYZ for PointOrPoint3D {}
132
133// NEW
134
135impl NewXY for Point {
136    fn new_xy(x: f64, y: f64) -> Self {
137        Self(x, y)
138    }
139}
140impl NewXY for Point3D {
141    fn new_xy(x: f64, y: f64) -> Self {
142        Self(x, y, 0.0)
143    }
144}
145impl NewXY for PointOrPoint3D {
146    fn new_xy(x: f64, y: f64) -> Self {
147        Self(x, y, None)
148    }
149}
150impl NewXYZ for Point3D {
151    fn new_xyz(x: f64, y: f64, z: f64) -> Self {
152        Self(x, y, z)
153    }
154}
155impl NewXYZ for PointOrPoint3D {
156    fn new_xyz(x: f64, y: f64, z: f64) -> Self {
157        Self(x, y, Some(z))
158    }
159}
160
161/// Enum to represent specific geometry types as strings
162#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)]
163pub enum GeometryType {
164    /// Point
165    #[default]
166    Point,
167    /// MultiPoint
168    MultiPoint,
169    /// LineString
170    LineString,
171    /// MultiLineString
172    MultiLineString,
173    /// Polygon
174    Polygon,
175    /// MultiPolygon
176    MultiPolygon,
177    /// 3D Point
178    Point3D,
179    /// 3D MultiPoint
180    MultiPoint3D,
181    /// 3D LineString
182    LineString3D,
183    /// 3D MultiLineString
184    MultiLineString3D,
185    /// 3D Polygon
186    Polygon3D,
187    /// 3D MultiPolygon
188    MultiPolygon3D,
189}
190impl From<&str> for GeometryType {
191    fn from(s: &str) -> Self {
192        match s {
193            "Point" => GeometryType::Point,
194            "MultiPoint" => GeometryType::MultiPoint,
195            "LineString" => GeometryType::LineString,
196            "MultiLineString" => GeometryType::MultiLineString,
197            "Polygon" => GeometryType::Polygon,
198            "MultiPolygon" => GeometryType::MultiPolygon,
199            "Point3D" => GeometryType::Point3D,
200            "MultiPoint3D" => GeometryType::MultiPoint3D,
201            "LineString3D" => GeometryType::LineString3D,
202            "MultiLineString3D" => GeometryType::MultiLineString3D,
203            "Polygon3D" => GeometryType::Polygon3D,
204            "MultiPolygon3D" => GeometryType::MultiPolygon3D,
205            _ => panic!("Invalid geometry type: {}", s),
206        }
207    }
208}
209
210/// All possible geometry shapes
211#[derive(Clone, Serialize, Debug, PartialEq)]
212#[serde(untagged)]
213pub enum Geometry<M: Clone + Default = MValue> {
214    /// Point Shape
215    Point(PointGeometry<M>),
216    /// MultiPoint Shape
217    MultiPoint(MultiPointGeometry<M>),
218    /// LineString Shape
219    LineString(LineStringGeometry<M>),
220    /// MultiLineString Shape
221    MultiLineString(MultiLineStringGeometry<M>),
222    /// Polygon Shape
223    Polygon(PolygonGeometry<M>),
224    /// MultiPolygon Shape
225    MultiPolygon(MultiPolygonGeometry<M>),
226    /// Point3D Shape
227    Point3D(Point3DGeometry<M>),
228    /// MultiPoint3D Shape
229    MultiPoint3D(MultiPoint3DGeometry<M>),
230    /// LineString3D Shape
231    LineString3D(LineString3DGeometry<M>),
232    /// MultiLineString3D Shape
233    MultiLineString3D(MultiLineString3DGeometry<M>),
234    /// Polygon3D Shape
235    Polygon3D(Polygon3DGeometry<M>),
236    /// MultiPolygon3D Shape
237    MultiPolygon3D(MultiPolygon3DGeometry<M>),
238}
239impl<M: Clone + Default> Default for Geometry<M> {
240    fn default() -> Self {
241        Geometry::Point(PointGeometry::<M>::default())
242    }
243}
244
245/// BaseGeometry is the a generic geometry type
246#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)]
247pub struct BaseGeometry<M = MValue, G = Geometry<M>, B = BBOX> {
248    /// The geometry type
249    #[serde(rename = "type")]
250    pub _type: GeometryType,
251    /// The geometry shape
252    pub coordinates: G,
253    /// The M-Values shape
254    #[serde(rename = "mValues", skip_serializing_if = "Option::is_none")]
255    pub m_values: Option<M>,
256    /// The BBox shape
257    #[serde(skip_serializing_if = "Option::is_none")]
258    pub bbox: Option<B>,
259}
260
261/// PointGeometry is a point
262pub type PointGeometry<M = MValue> = BaseGeometry<M, Point, BBox>;
263/// MultiPointGeometry contains multiple points
264pub type MultiPointGeometry<M = MValue> = BaseGeometry<LineStringMValues<M>, MultiPoint, BBox>;
265/// LineStringGeometry is a line
266pub type LineStringGeometry<M = MValue> = BaseGeometry<LineStringMValues<M>, LineString, BBox>;
267/// MultiLineStringGeometry contains multiple lines
268pub type MultiLineStringGeometry<M = MValue> =
269    BaseGeometry<MultiLineStringMValues<M>, MultiLineString, BBox>;
270/// PolygonGeometry is a polygon with potential holes
271pub type PolygonGeometry<M = MValue> = BaseGeometry<PolygonMValues<M>, Polygon, BBox>;
272/// MultiPolygonGeometry is a polygon with multiple polygons with their own potential holes
273pub type MultiPolygonGeometry<M = MValue> =
274    BaseGeometry<MultiPolygonMValues<M>, MultiPolygon, BBox>;
275/// Point3DGeometry is a 3D point
276pub type Point3DGeometry<M = MValue> = BaseGeometry<M, Point3D, BBox3D>;
277/// MultiPoint3DGeometry contains multiple 3D points
278pub type MultiPoint3DGeometry<M = MValue> =
279    BaseGeometry<LineStringMValues<M>, MultiPoint3D, BBox3D>;
280/// LineString3DGeometry is a 3D line
281pub type LineString3DGeometry<M = MValue> =
282    BaseGeometry<LineStringMValues<M>, LineString3D, BBox3D>;
283/// MultiLineString3DGeometry contains multiple 3D lines
284pub type MultiLineString3DGeometry<M = MValue> =
285    BaseGeometry<MultiLineStringMValues<M>, MultiLineString3D, BBox3D>;
286/// Polygon3DGeometry is a 3D polygon with potential holes
287pub type Polygon3DGeometry<M = MValue> = BaseGeometry<PolygonMValues<M>, Polygon3D, BBox3D>;
288/// MultiPolygon3DGeometry is a 3D polygon with multiple polygons with their own potential holes
289pub type MultiPolygon3DGeometry<M = MValue> =
290    BaseGeometry<MultiPolygonMValues<M>, MultiPolygon3D, BBox3D>;