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);
9pub type MultiPoint = Vec<Point>;
11pub type LineString = Vec<Point>;
13pub type MultiLineString = Vec<LineString>;
15pub type Polygon = Vec<Vec<Point>>;
17pub type MultiPolygon = Vec<Polygon>;
19#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Default)]
21pub struct Point3D(pub f64, pub f64, pub f64);
22pub type MultiPoint3D = Vec<Point3D>;
24pub type LineString3D = Vec<Point3D>;
26pub type MultiLineString3D = Vec<LineString3D>;
28pub type Polygon3D = Vec<Vec<Point3D>>;
30pub type MultiPolygon3D = Vec<Polygon3D>;
32#[derive(Copy, Clone, Serialize, Deserialize, Debug, PartialEq, Default)]
34pub struct PointOrPoint3D(pub f64, pub f64, pub Option<f64>);
35impl From<Point> for PointOrPoint3D {
36 fn from(p: Point) -> Self {
37 PointOrPoint3D(p.0, p.1, None)
38 }
39}
40impl From<Point3D> for PointOrPoint3D {
41 fn from(p: Point3D) -> Self {
42 PointOrPoint3D(p.0, p.1, Some(p.2))
43 }
44}
45
46impl GetXY for Point {
49 fn x(&self) -> f64 {
50 self.0
51 }
52 fn y(&self) -> f64 {
53 self.1
54 }
55}
56impl GetZ for Point {
57 fn z(&self) -> Option<f64> {
58 None
59 }
60}
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 GetZ for PointOrPoint3D {
83 fn z(&self) -> Option<f64> {
84 self.2
85 }
86}
87
88impl SetXY for Point {
91 fn set_x(&mut self, x: f64) {
92 self.0 = x;
93 }
94 fn set_y(&mut self, y: f64) {
95 self.1 = y;
96 }
97 fn set_xy(&mut self, x: f64, y: f64) {
98 self.0 = x;
99 self.1 = y;
100 }
101}
102impl SetXY for Point3D {
103 fn set_x(&mut self, x: f64) {
104 self.0 = x;
105 }
106 fn set_y(&mut self, y: f64) {
107 self.1 = y;
108 }
109}
110impl SetZ for Point3D {
111 fn set_z(&mut self, z: f64) {
112 self.2 = z;
113 }
114}
115impl SetXY for PointOrPoint3D {
116 fn set_x(&mut self, x: f64) {
117 self.0 = x;
118 }
119 fn set_y(&mut self, y: f64) {
120 self.1 = y;
121 }
122}
123impl SetZ for PointOrPoint3D {
124 fn set_z(&mut self, z: f64) {
125 self.2 = Some(z);
126 }
127}
128
129impl NewXY for Point {
132 fn new_xy(x: f64, y: f64) -> Self {
133 Self(x, y)
134 }
135}
136impl NewXY for Point3D {
137 fn new_xy(x: f64, y: f64) -> Self {
138 Self(x, y, 0.0)
139 }
140}
141impl NewXY for PointOrPoint3D {
142 fn new_xy(x: f64, y: f64) -> Self {
143 Self(x, y, None)
144 }
145}
146impl NewXYZ for Point3D {
147 fn new_xyz(x: f64, y: f64, z: f64) -> Self {
148 Self(x, y, z)
149 }
150}
151impl NewXYZ for PointOrPoint3D {
152 fn new_xyz(x: f64, y: f64, z: f64) -> Self {
153 Self(x, y, Some(z))
154 }
155}
156
157impl Eq for Point {}
160impl Ord for Point {
161 fn cmp(&self, other: &Point) -> Ordering {
162 match self.0.partial_cmp(&other.0) {
163 Some(Ordering::Equal) => {}
164 other => return other.unwrap_or(Ordering::Greater), }
166 match self.1.partial_cmp(&other.1) {
167 Some(Ordering::Equal) => Ordering::Equal,
168 other => other.unwrap_or(Ordering::Greater), }
170 }
171}
172impl PartialOrd for Point {
173 fn partial_cmp(&self, other: &Point) -> Option<Ordering> {
174 Some(self.cmp(other))
175 }
176}
177
178impl Eq for Point3D {}
179impl Ord for Point3D {
180 fn cmp(&self, other: &Point3D) -> Ordering {
181 match self.0.partial_cmp(&other.0) {
182 Some(Ordering::Equal) => {}
183 other => return other.unwrap_or(Ordering::Greater), }
185 match self.1.partial_cmp(&other.1) {
186 Some(Ordering::Equal) => {}
187 other => return other.unwrap_or(Ordering::Greater), }
189 match self.2.partial_cmp(&other.2) {
190 Some(order) => order,
191 None => Ordering::Equal, }
193 }
194}
195impl PartialOrd for Point3D {
196 fn partial_cmp(&self, other: &Point3D) -> Option<Ordering> {
197 Some(self.cmp(other))
198 }
199}
200
201impl Eq for PointOrPoint3D {}
202impl Ord for PointOrPoint3D {
203 fn cmp(&self, other: &PointOrPoint3D) -> Ordering {
204 match self.0.partial_cmp(&other.0) {
205 Some(Ordering::Equal) => {}
206 other => return other.unwrap_or(Ordering::Greater), }
208 match self.1.partial_cmp(&other.1) {
209 Some(Ordering::Equal) => {}
210 other => return other.unwrap_or(Ordering::Greater), }
212 match self.2.partial_cmp(&other.2) {
213 Some(order) => order,
214 None => Ordering::Equal, }
216 }
217}
218impl PartialOrd for PointOrPoint3D {
219 fn partial_cmp(&self, other: &PointOrPoint3D) -> Option<Ordering> {
220 Some(self.cmp(other))
221 }
222}
223
224#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)]
226pub enum GeometryType {
227 #[default]
229 Point,
230 MultiPoint,
232 LineString,
234 MultiLineString,
236 Polygon,
238 MultiPolygon,
240 Point3D,
242 MultiPoint3D,
244 LineString3D,
246 MultiLineString3D,
248 Polygon3D,
250 MultiPolygon3D,
252}
253impl From<&str> for GeometryType {
254 fn from(s: &str) -> Self {
255 match s {
256 "Point" => GeometryType::Point,
257 "MultiPoint" => GeometryType::MultiPoint,
258 "LineString" => GeometryType::LineString,
259 "MultiLineString" => GeometryType::MultiLineString,
260 "Polygon" => GeometryType::Polygon,
261 "MultiPolygon" => GeometryType::MultiPolygon,
262 "Point3D" => GeometryType::Point3D,
263 "MultiPoint3D" => GeometryType::MultiPoint3D,
264 "LineString3D" => GeometryType::LineString3D,
265 "MultiLineString3D" => GeometryType::MultiLineString3D,
266 "Polygon3D" => GeometryType::Polygon3D,
267 "MultiPolygon3D" => GeometryType::MultiPolygon3D,
268 _ => panic!("Invalid geometry type: {}", s),
269 }
270 }
271}
272
273#[derive(Clone, Serialize, Debug, PartialEq)]
275#[serde(untagged)]
276pub enum Geometry<M: Clone + Default = MValue> {
277 Point(PointGeometry<M>),
279 MultiPoint(MultiPointGeometry<M>),
281 LineString(LineStringGeometry<M>),
283 MultiLineString(MultiLineStringGeometry<M>),
285 Polygon(PolygonGeometry<M>),
287 MultiPolygon(MultiPolygonGeometry<M>),
289 Point3D(Point3DGeometry<M>),
291 MultiPoint3D(MultiPoint3DGeometry<M>),
293 LineString3D(LineString3DGeometry<M>),
295 MultiLineString3D(MultiLineString3DGeometry<M>),
297 Polygon3D(Polygon3DGeometry<M>),
299 MultiPolygon3D(MultiPolygon3DGeometry<M>),
301}
302impl<M: Clone + Default> Default for Geometry<M> {
303 fn default() -> Self {
304 Geometry::Point(PointGeometry::<M>::default())
305 }
306}
307
308#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)]
310pub struct BaseGeometry<M = MValue, G = Geometry<M>, B = BBOX> {
311 #[serde(rename = "type")]
313 pub _type: GeometryType,
314 pub coordinates: G,
316 #[serde(rename = "mValues", skip_serializing_if = "Option::is_none")]
318 pub m_values: Option<M>,
319 #[serde(skip_serializing_if = "Option::is_none")]
321 pub bbox: Option<B>,
322}
323
324pub type PointGeometry<M = MValue> = BaseGeometry<M, Point, BBox>;
326pub type MultiPointGeometry<M = MValue> = BaseGeometry<LineStringMValues<M>, MultiPoint, BBox>;
328pub type LineStringGeometry<M = MValue> = BaseGeometry<LineStringMValues<M>, LineString, BBox>;
330pub type MultiLineStringGeometry<M = MValue> =
332 BaseGeometry<MultiLineStringMValues<M>, MultiLineString, BBox>;
333pub type PolygonGeometry<M = MValue> = BaseGeometry<PolygonMValues<M>, Polygon, BBox>;
335pub type MultiPolygonGeometry<M = MValue> =
337 BaseGeometry<MultiPolygonMValues<M>, MultiPolygon, BBox>;
338pub type Point3DGeometry<M = MValue> = BaseGeometry<M, Point3D, BBox3D>;
340pub type MultiPoint3DGeometry<M = MValue> =
342 BaseGeometry<LineStringMValues<M>, MultiPoint3D, BBox3D>;
343pub type LineString3DGeometry<M = MValue> =
345 BaseGeometry<LineStringMValues<M>, LineString3D, BBox3D>;
346pub type MultiLineString3DGeometry<M = MValue> =
348 BaseGeometry<MultiLineStringMValues<M>, MultiLineString3D, BBox3D>;
349pub type Polygon3DGeometry<M = MValue> = BaseGeometry<PolygonMValues<M>, Polygon3D, BBox3D>;
351pub type MultiPolygon3DGeometry<M = MValue> =
353 BaseGeometry<MultiPolygonMValues<M>, MultiPolygon3D, BBox3D>;