1use crate::*;
2use alloc::vec::Vec;
3use core::cmp::Ordering;
4use serde::{Deserialize, Serialize};
5
6#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Default)]
8pub struct Point(pub f64, pub f64);
9impl<P: GetXY> From<&P> for Point {
10 fn from(p: &P) -> Self {
11 Point(p.x(), p.y())
12 }
13}
14pub type MultiPoint = Vec<Point>;
16pub type LineString = Vec<Point>;
18pub type MultiLineString = Vec<LineString>;
20pub type Polygon = Vec<Vec<Point>>;
22pub type MultiPolygon = Vec<Polygon>;
24#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Default)]
26pub struct Point3D(pub f64, pub f64, pub f64);
27impl<P: GetXYZ> From<&P> for Point3D {
28 fn from(p: &P) -> Self {
29 Point3D(p.x(), p.y(), p.z().unwrap_or_default())
30 }
31}
32pub type MultiPoint3D = Vec<Point3D>;
34pub type LineString3D = Vec<Point3D>;
36pub type MultiLineString3D = Vec<LineString3D>;
38pub type Polygon3D = Vec<Vec<Point3D>>;
40pub type MultiPolygon3D = Vec<Polygon3D>;
42#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Default)]
44pub struct PointOrPoint3D(pub f64, pub f64, pub Option<f64>);
45impl From<Point> for PointOrPoint3D {
46 fn from(p: Point) -> Self {
47 PointOrPoint3D(p.0, p.1, None)
48 }
49}
50impl From<Point3D> for PointOrPoint3D {
51 fn from(p: Point3D) -> Self {
52 PointOrPoint3D(p.0, p.1, Some(p.2))
53 }
54}
55impl<P: GetXYZ> From<&P> for PointOrPoint3D {
56 fn from(p: &P) -> Self {
57 PointOrPoint3D(p.x(), p.y(), p.z())
58 }
59}
60
61impl GetXY for Point {
64 fn x(&self) -> f64 {
65 self.0
66 }
67 fn y(&self) -> f64 {
68 self.1
69 }
70}
71impl GetZ for Point {
72 fn z(&self) -> Option<f64> {
73 None
74 }
75}
76impl GetXY for Point3D {
77 fn x(&self) -> f64 {
78 self.0
79 }
80 fn y(&self) -> f64 {
81 self.1
82 }
83}
84impl GetXY for PointOrPoint3D {
85 fn x(&self) -> f64 {
86 self.0
87 }
88 fn y(&self) -> f64 {
89 self.1
90 }
91}
92impl GetZ for Point3D {
93 fn z(&self) -> Option<f64> {
94 Some(self.2)
95 }
96}
97impl GetZ for PointOrPoint3D {
98 fn z(&self) -> Option<f64> {
99 self.2
100 }
101}
102
103impl SetXY for Point {
106 fn set_x(&mut self, x: f64) {
107 self.0 = x;
108 }
109 fn set_y(&mut self, y: f64) {
110 self.1 = y;
111 }
112 fn set_xy(&mut self, x: f64, y: f64) {
113 self.0 = x;
114 self.1 = y;
115 }
116}
117impl SetXY for Point3D {
118 fn set_x(&mut self, x: f64) {
119 self.0 = x;
120 }
121 fn set_y(&mut self, y: f64) {
122 self.1 = y;
123 }
124}
125impl SetZ for Point3D {
126 fn set_z(&mut self, z: f64) {
127 self.2 = z;
128 }
129}
130impl SetXY for PointOrPoint3D {
131 fn set_x(&mut self, x: f64) {
132 self.0 = x;
133 }
134 fn set_y(&mut self, y: f64) {
135 self.1 = y;
136 }
137}
138impl SetZ for PointOrPoint3D {
139 fn set_z(&mut self, z: f64) {
140 self.2 = Some(z);
141 }
142}
143
144impl NewXY for Point {
147 fn new_xy(x: f64, y: f64) -> Self {
148 Self(x, y)
149 }
150}
151impl NewXY for Point3D {
152 fn new_xy(x: f64, y: f64) -> Self {
153 Self(x, y, 0.0)
154 }
155}
156impl NewXY for PointOrPoint3D {
157 fn new_xy(x: f64, y: f64) -> Self {
158 Self(x, y, None)
159 }
160}
161impl<M: Clone> NewXYM<M> for Point {
162 fn new_xym(x: f64, y: f64, _m: M) -> Self {
163 Self(x, y)
164 }
165}
166impl<M: Clone> NewXYM<M> for Point3D {
167 fn new_xym(x: f64, y: f64, _m: M) -> Self {
168 Self(x, y, 0.0)
169 }
170}
171impl<M: Clone> NewXYM<M> for PointOrPoint3D {
172 fn new_xym(x: f64, y: f64, _m: M) -> Self {
173 Self(x, y, None)
174 }
175}
176impl NewXYZ for Point3D {
177 fn new_xyz(x: f64, y: f64, z: f64) -> Self {
178 Self(x, y, z)
179 }
180}
181impl NewXYZ for PointOrPoint3D {
182 fn new_xyz(x: f64, y: f64, z: f64) -> Self {
183 Self(x, y, Some(z))
184 }
185}
186impl<M: Clone> NewXYZM<M> for Point3D {
187 fn new_xyzm(x: f64, y: f64, z: f64, _m: M) -> Self {
188 Self(x, y, z)
189 }
190}
191impl<M: Clone> NewXYZM<M> for PointOrPoint3D {
192 fn new_xyzm(x: f64, y: f64, z: f64, _m: M) -> Self {
193 Self(x, y, Some(z))
194 }
195}
196
197impl Eq for Point {}
200impl Ord for Point {
201 fn cmp(&self, other: &Point) -> Ordering {
202 match self.0.partial_cmp(&other.0) {
203 Some(Ordering::Equal) => {}
204 other => return other.unwrap_or(Ordering::Greater), }
206 match self.1.partial_cmp(&other.1) {
207 Some(Ordering::Equal) => Ordering::Equal,
208 other => other.unwrap_or(Ordering::Greater), }
210 }
211}
212impl PartialOrd for Point {
213 fn partial_cmp(&self, other: &Point) -> Option<Ordering> {
214 Some(self.cmp(other))
215 }
216}
217
218impl Eq for Point3D {}
219impl Ord for Point3D {
220 fn cmp(&self, other: &Point3D) -> Ordering {
221 match self.0.partial_cmp(&other.0) {
222 Some(Ordering::Equal) => {}
223 other => return other.unwrap_or(Ordering::Greater), }
225 match self.1.partial_cmp(&other.1) {
226 Some(Ordering::Equal) => {}
227 other => return other.unwrap_or(Ordering::Greater), }
229 match self.2.partial_cmp(&other.2) {
230 Some(order) => order,
231 None => Ordering::Equal, }
233 }
234}
235impl PartialOrd for Point3D {
236 fn partial_cmp(&self, other: &Point3D) -> Option<Ordering> {
237 Some(self.cmp(other))
238 }
239}
240
241impl Eq for PointOrPoint3D {}
242impl Ord for PointOrPoint3D {
243 fn cmp(&self, other: &PointOrPoint3D) -> Ordering {
244 match self.0.partial_cmp(&other.0) {
245 Some(Ordering::Equal) => {}
246 other => return other.unwrap_or(Ordering::Greater), }
248 match self.1.partial_cmp(&other.1) {
249 Some(Ordering::Equal) => {}
250 other => return other.unwrap_or(Ordering::Greater), }
252 match self.2.partial_cmp(&other.2) {
253 Some(order) => order,
254 None => Ordering::Equal, }
256 }
257}
258impl PartialOrd for PointOrPoint3D {
259 fn partial_cmp(&self, other: &PointOrPoint3D) -> Option<Ordering> {
260 Some(self.cmp(other))
261 }
262}
263
264#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)]
266pub enum GeometryType {
267 #[default]
269 Point,
270 MultiPoint,
272 LineString,
274 MultiLineString,
276 Polygon,
278 MultiPolygon,
280 Point3D,
282 MultiPoint3D,
284 LineString3D,
286 MultiLineString3D,
288 Polygon3D,
290 MultiPolygon3D,
292}
293impl From<&str> for GeometryType {
294 fn from(s: &str) -> Self {
295 match s {
296 "Point" => GeometryType::Point,
297 "MultiPoint" => GeometryType::MultiPoint,
298 "LineString" => GeometryType::LineString,
299 "MultiLineString" => GeometryType::MultiLineString,
300 "Polygon" => GeometryType::Polygon,
301 "MultiPolygon" => GeometryType::MultiPolygon,
302 "Point3D" => GeometryType::Point3D,
303 "MultiPoint3D" => GeometryType::MultiPoint3D,
304 "LineString3D" => GeometryType::LineString3D,
305 "MultiLineString3D" => GeometryType::MultiLineString3D,
306 "Polygon3D" => GeometryType::Polygon3D,
307 "MultiPolygon3D" => GeometryType::MultiPolygon3D,
308 _ => panic!("Invalid geometry type: {}", s),
309 }
310 }
311}
312
313#[derive(Clone, Serialize, Debug, PartialEq)]
315#[serde(untagged)]
316pub enum Geometry<M: Clone + Default = MValue> {
317 Point(PointGeometry<M>),
319 MultiPoint(MultiPointGeometry<M>),
321 LineString(LineStringGeometry<M>),
323 MultiLineString(MultiLineStringGeometry<M>),
325 Polygon(PolygonGeometry<M>),
327 MultiPolygon(MultiPolygonGeometry<M>),
329 Point3D(Point3DGeometry<M>),
331 MultiPoint3D(MultiPoint3DGeometry<M>),
333 LineString3D(LineString3DGeometry<M>),
335 MultiLineString3D(MultiLineString3DGeometry<M>),
337 Polygon3D(Polygon3DGeometry<M>),
339 MultiPolygon3D(MultiPolygon3DGeometry<M>),
341}
342impl<M: Clone + Default> Default for Geometry<M> {
343 fn default() -> Self {
344 Geometry::Point(PointGeometry::<M>::default())
345 }
346}
347
348#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)]
350pub struct BaseGeometry<M = MValue, G = Geometry<M>, B = BBOX> {
351 #[serde(rename = "type")]
353 pub _type: GeometryType,
354 pub coordinates: G,
356 #[serde(rename = "mValues", skip_serializing_if = "Option::is_none")]
358 pub m_values: Option<M>,
359 #[serde(skip_serializing_if = "Option::is_none")]
361 pub bbox: Option<B>,
362}
363
364pub type PointGeometry<M = MValue> = BaseGeometry<M, Point, BBox>;
366pub type MultiPointGeometry<M = MValue> = BaseGeometry<LineStringMValues<M>, MultiPoint, BBox>;
368pub type LineStringGeometry<M = MValue> = BaseGeometry<LineStringMValues<M>, LineString, BBox>;
370pub type MultiLineStringGeometry<M = MValue> =
372 BaseGeometry<MultiLineStringMValues<M>, MultiLineString, BBox>;
373pub type PolygonGeometry<M = MValue> = BaseGeometry<PolygonMValues<M>, Polygon, BBox>;
375pub type MultiPolygonGeometry<M = MValue> =
377 BaseGeometry<MultiPolygonMValues<M>, MultiPolygon, BBox>;
378pub type Point3DGeometry<M = MValue> = BaseGeometry<M, Point3D, BBox3D>;
380pub type MultiPoint3DGeometry<M = MValue> =
382 BaseGeometry<LineStringMValues<M>, MultiPoint3D, BBox3D>;
383pub type LineString3DGeometry<M = MValue> =
385 BaseGeometry<LineStringMValues<M>, LineString3D, BBox3D>;
386pub type MultiLineString3DGeometry<M = MValue> =
388 BaseGeometry<MultiLineStringMValues<M>, MultiLineString3D, BBox3D>;
389pub type Polygon3DGeometry<M = MValue> = BaseGeometry<PolygonMValues<M>, Polygon3D, BBox3D>;
391pub type MultiPolygon3DGeometry<M = MValue> =
393 BaseGeometry<MultiPolygonMValues<M>, MultiPolygon3D, BBox3D>;