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 (f64, f64) {
64 fn x(&self) -> f64 {
65 self.0
66 }
67 fn y(&self) -> f64 {
68 self.1
69 }
70}
71impl GetXY for (f64, f64, f64) {
72 fn x(&self) -> f64 {
73 self.0
74 }
75 fn y(&self) -> f64 {
76 self.1
77 }
78}
79impl GetXY for Point {
80 fn x(&self) -> f64 {
81 self.0
82 }
83 fn y(&self) -> f64 {
84 self.1
85 }
86}
87impl GetZ for (f64, f64) {
88 fn z(&self) -> Option<f64> {
89 None
90 }
91}
92impl GetZ for (f64, f64, f64) {
93 fn z(&self) -> Option<f64> {
94 Some(self.2)
95 }
96}
97impl GetZ for Point {
98 fn z(&self) -> Option<f64> {
99 None
100 }
101}
102impl GetXY for Point3D {
103 fn x(&self) -> f64 {
104 self.0
105 }
106 fn y(&self) -> f64 {
107 self.1
108 }
109}
110impl GetXY for PointOrPoint3D {
111 fn x(&self) -> f64 {
112 self.0
113 }
114 fn y(&self) -> f64 {
115 self.1
116 }
117}
118impl GetZ for Point3D {
119 fn z(&self) -> Option<f64> {
120 Some(self.2)
121 }
122}
123impl GetZ for PointOrPoint3D {
124 fn z(&self) -> Option<f64> {
125 self.2
126 }
127}
128
129impl SetXY for (f64, f64) {
132 fn set_x(&mut self, x: f64) {
133 self.0 = x;
134 }
135 fn set_y(&mut self, y: f64) {
136 self.1 = y;
137 }
138}
139impl SetXY for (f64, f64, f64) {
140 fn set_x(&mut self, x: f64) {
141 self.0 = x;
142 }
143 fn set_y(&mut self, y: f64) {
144 self.1 = y;
145 }
146}
147impl SetXY for Point {
148 fn set_x(&mut self, x: f64) {
149 self.0 = x;
150 }
151 fn set_y(&mut self, y: f64) {
152 self.1 = y;
153 }
154}
155impl SetXY for Point3D {
156 fn set_x(&mut self, x: f64) {
157 self.0 = x;
158 }
159 fn set_y(&mut self, y: f64) {
160 self.1 = y;
161 }
162}
163impl SetZ for (f64, f64, f64) {
164 fn set_z(&mut self, z: f64) {
165 self.2 = z;
166 }
167}
168impl SetZ for Point3D {
169 fn set_z(&mut self, z: f64) {
170 self.2 = z;
171 }
172}
173impl SetXY for PointOrPoint3D {
174 fn set_x(&mut self, x: f64) {
175 self.0 = x;
176 }
177 fn set_y(&mut self, y: f64) {
178 self.1 = y;
179 }
180}
181impl SetZ for PointOrPoint3D {
182 fn set_z(&mut self, z: f64) {
183 self.2 = Some(z);
184 }
185}
186
187impl NewXY for (f64, f64) {
190 fn new_xy(x: f64, y: f64) -> Self {
191 (x, y)
192 }
193}
194impl NewXY for Point {
195 fn new_xy(x: f64, y: f64) -> Self {
196 Self(x, y)
197 }
198}
199impl NewXY for Point3D {
200 fn new_xy(x: f64, y: f64) -> Self {
201 Self(x, y, 0.0)
202 }
203}
204impl NewXY for PointOrPoint3D {
205 fn new_xy(x: f64, y: f64) -> Self {
206 Self(x, y, None)
207 }
208}
209impl<M: Clone> NewXYM<M> for Point {
210 fn new_xym(x: f64, y: f64, _m: M) -> Self {
211 Self(x, y)
212 }
213}
214impl<M: Clone> NewXYM<M> for Point3D {
215 fn new_xym(x: f64, y: f64, _m: M) -> Self {
216 Self(x, y, 0.0)
217 }
218}
219impl<M: Clone> NewXYM<M> for PointOrPoint3D {
220 fn new_xym(x: f64, y: f64, _m: M) -> Self {
221 Self(x, y, None)
222 }
223}
224impl NewXYZ for (f64, f64, f64) {
225 fn new_xyz(x: f64, y: f64, z: f64) -> Self {
226 (x, y, z)
227 }
228}
229impl NewXYZ for Point3D {
230 fn new_xyz(x: f64, y: f64, z: f64) -> Self {
231 Self(x, y, z)
232 }
233}
234impl NewXYZ for PointOrPoint3D {
235 fn new_xyz(x: f64, y: f64, z: f64) -> Self {
236 Self(x, y, Some(z))
237 }
238}
239impl<M: Clone> NewXYZM<M> for Point3D {
240 fn new_xyzm(x: f64, y: f64, z: f64, _m: M) -> Self {
241 Self(x, y, z)
242 }
243}
244impl<M: Clone> NewXYZM<M> for PointOrPoint3D {
245 fn new_xyzm(x: f64, y: f64, z: f64, _m: M) -> Self {
246 Self(x, y, Some(z))
247 }
248}
249
250impl Eq for Point {}
253impl Ord for Point {
254 fn cmp(&self, other: &Point) -> Ordering {
255 match self.0.partial_cmp(&other.0) {
256 Some(Ordering::Equal) => {}
257 other => return other.unwrap_or(Ordering::Greater), }
259 match self.1.partial_cmp(&other.1) {
260 Some(Ordering::Equal) => Ordering::Equal,
261 other => other.unwrap_or(Ordering::Greater), }
263 }
264}
265impl PartialOrd for Point {
266 fn partial_cmp(&self, other: &Point) -> Option<Ordering> {
267 Some(self.cmp(other))
268 }
269}
270
271impl Eq for Point3D {}
272impl Ord for Point3D {
273 fn cmp(&self, other: &Point3D) -> Ordering {
274 match self.0.partial_cmp(&other.0) {
275 Some(Ordering::Equal) => {}
276 other => return other.unwrap_or(Ordering::Greater), }
278 match self.1.partial_cmp(&other.1) {
279 Some(Ordering::Equal) => {}
280 other => return other.unwrap_or(Ordering::Greater), }
282 match self.2.partial_cmp(&other.2) {
283 Some(order) => order,
284 None => Ordering::Equal, }
286 }
287}
288impl PartialOrd for Point3D {
289 fn partial_cmp(&self, other: &Point3D) -> Option<Ordering> {
290 Some(self.cmp(other))
291 }
292}
293
294impl Eq for PointOrPoint3D {}
295impl Ord for PointOrPoint3D {
296 fn cmp(&self, other: &PointOrPoint3D) -> Ordering {
297 match self.0.partial_cmp(&other.0) {
298 Some(Ordering::Equal) => {}
299 other => return other.unwrap_or(Ordering::Greater), }
301 match self.1.partial_cmp(&other.1) {
302 Some(Ordering::Equal) => {}
303 other => return other.unwrap_or(Ordering::Greater), }
305 match self.2.partial_cmp(&other.2) {
306 Some(order) => order,
307 None => Ordering::Equal, }
309 }
310}
311impl PartialOrd for PointOrPoint3D {
312 fn partial_cmp(&self, other: &PointOrPoint3D) -> Option<Ordering> {
313 Some(self.cmp(other))
314 }
315}
316
317#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)]
319pub enum GeometryType {
320 #[default]
322 Point,
323 MultiPoint,
325 LineString,
327 MultiLineString,
329 Polygon,
331 MultiPolygon,
333 Point3D,
335 MultiPoint3D,
337 LineString3D,
339 MultiLineString3D,
341 Polygon3D,
343 MultiPolygon3D,
345}
346impl From<&str> for GeometryType {
347 fn from(s: &str) -> Self {
348 match s {
349 "Point" => GeometryType::Point,
350 "MultiPoint" => GeometryType::MultiPoint,
351 "LineString" => GeometryType::LineString,
352 "MultiLineString" => GeometryType::MultiLineString,
353 "Polygon" => GeometryType::Polygon,
354 "MultiPolygon" => GeometryType::MultiPolygon,
355 "Point3D" => GeometryType::Point3D,
356 "MultiPoint3D" => GeometryType::MultiPoint3D,
357 "LineString3D" => GeometryType::LineString3D,
358 "MultiLineString3D" => GeometryType::MultiLineString3D,
359 "Polygon3D" => GeometryType::Polygon3D,
360 "MultiPolygon3D" => GeometryType::MultiPolygon3D,
361 _ => panic!("Invalid geometry type: {}", s),
362 }
363 }
364}
365
366#[derive(Clone, Serialize, Debug, PartialEq)]
368#[serde(untagged)]
369pub enum Geometry<M: Clone + Default = MValue> {
370 Point(PointGeometry<M>),
372 MultiPoint(MultiPointGeometry<M>),
374 LineString(LineStringGeometry<M>),
376 MultiLineString(MultiLineStringGeometry<M>),
378 Polygon(PolygonGeometry<M>),
380 MultiPolygon(MultiPolygonGeometry<M>),
382 Point3D(Point3DGeometry<M>),
384 MultiPoint3D(MultiPoint3DGeometry<M>),
386 LineString3D(LineString3DGeometry<M>),
388 MultiLineString3D(MultiLineString3DGeometry<M>),
390 Polygon3D(Polygon3DGeometry<M>),
392 MultiPolygon3D(MultiPolygon3DGeometry<M>),
394}
395impl<M: Clone + Default> Default for Geometry<M> {
396 fn default() -> Self {
397 Geometry::Point(PointGeometry::<M>::default())
398 }
399}
400
401#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)]
403pub struct BaseGeometry<M = MValue, G = Geometry<M>, B = BBOX> {
404 #[serde(rename = "type")]
406 pub _type: GeometryType,
407 pub coordinates: G,
409 #[serde(rename = "mValues", skip_serializing_if = "Option::is_none")]
411 pub m_values: Option<M>,
412 #[serde(skip_serializing_if = "Option::is_none")]
414 pub bbox: Option<B>,
415}
416
417pub type PointGeometry<M = MValue> = BaseGeometry<M, Point, BBox>;
419pub type MultiPointGeometry<M = MValue> = BaseGeometry<LineStringMValues<M>, MultiPoint, BBox>;
421pub type LineStringGeometry<M = MValue> = BaseGeometry<LineStringMValues<M>, LineString, BBox>;
423pub type MultiLineStringGeometry<M = MValue> =
425 BaseGeometry<MultiLineStringMValues<M>, MultiLineString, BBox>;
426pub type PolygonGeometry<M = MValue> = BaseGeometry<PolygonMValues<M>, Polygon, BBox>;
428pub type MultiPolygonGeometry<M = MValue> =
430 BaseGeometry<MultiPolygonMValues<M>, MultiPolygon, BBox>;
431pub type Point3DGeometry<M = MValue> = BaseGeometry<M, Point3D, BBox3D>;
433pub type MultiPoint3DGeometry<M = MValue> =
435 BaseGeometry<LineStringMValues<M>, MultiPoint3D, BBox3D>;
436pub type LineString3DGeometry<M = MValue> =
438 BaseGeometry<LineStringMValues<M>, LineString3D, BBox3D>;
439pub type MultiLineString3DGeometry<M = MValue> =
441 BaseGeometry<MultiLineStringMValues<M>, MultiLineString3D, BBox3D>;
442pub type Polygon3DGeometry<M = MValue> = BaseGeometry<PolygonMValues<M>, Polygon3D, BBox3D>;
444pub type MultiPolygon3DGeometry<M = MValue> =
446 BaseGeometry<MultiPolygonMValues<M>, MultiPolygon3D, BBox3D>;