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 NewXYZ for Point3D {
162 fn new_xyz(x: f64, y: f64, z: f64) -> Self {
163 Self(x, y, z)
164 }
165}
166impl NewXYZ for PointOrPoint3D {
167 fn new_xyz(x: f64, y: f64, z: f64) -> Self {
168 Self(x, y, Some(z))
169 }
170}
171
172impl Eq for Point {}
175impl Ord for Point {
176 fn cmp(&self, other: &Point) -> Ordering {
177 match self.0.partial_cmp(&other.0) {
178 Some(Ordering::Equal) => {}
179 other => return other.unwrap_or(Ordering::Greater), }
181 match self.1.partial_cmp(&other.1) {
182 Some(Ordering::Equal) => Ordering::Equal,
183 other => other.unwrap_or(Ordering::Greater), }
185 }
186}
187impl PartialOrd for Point {
188 fn partial_cmp(&self, other: &Point) -> Option<Ordering> {
189 Some(self.cmp(other))
190 }
191}
192
193impl Eq for Point3D {}
194impl Ord for Point3D {
195 fn cmp(&self, other: &Point3D) -> Ordering {
196 match self.0.partial_cmp(&other.0) {
197 Some(Ordering::Equal) => {}
198 other => return other.unwrap_or(Ordering::Greater), }
200 match self.1.partial_cmp(&other.1) {
201 Some(Ordering::Equal) => {}
202 other => return other.unwrap_or(Ordering::Greater), }
204 match self.2.partial_cmp(&other.2) {
205 Some(order) => order,
206 None => Ordering::Equal, }
208 }
209}
210impl PartialOrd for Point3D {
211 fn partial_cmp(&self, other: &Point3D) -> Option<Ordering> {
212 Some(self.cmp(other))
213 }
214}
215
216impl Eq for PointOrPoint3D {}
217impl Ord for PointOrPoint3D {
218 fn cmp(&self, other: &PointOrPoint3D) -> Ordering {
219 match self.0.partial_cmp(&other.0) {
220 Some(Ordering::Equal) => {}
221 other => return other.unwrap_or(Ordering::Greater), }
223 match self.1.partial_cmp(&other.1) {
224 Some(Ordering::Equal) => {}
225 other => return other.unwrap_or(Ordering::Greater), }
227 match self.2.partial_cmp(&other.2) {
228 Some(order) => order,
229 None => Ordering::Equal, }
231 }
232}
233impl PartialOrd for PointOrPoint3D {
234 fn partial_cmp(&self, other: &PointOrPoint3D) -> Option<Ordering> {
235 Some(self.cmp(other))
236 }
237}
238
239#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)]
241pub enum GeometryType {
242 #[default]
244 Point,
245 MultiPoint,
247 LineString,
249 MultiLineString,
251 Polygon,
253 MultiPolygon,
255 Point3D,
257 MultiPoint3D,
259 LineString3D,
261 MultiLineString3D,
263 Polygon3D,
265 MultiPolygon3D,
267}
268impl From<&str> for GeometryType {
269 fn from(s: &str) -> Self {
270 match s {
271 "Point" => GeometryType::Point,
272 "MultiPoint" => GeometryType::MultiPoint,
273 "LineString" => GeometryType::LineString,
274 "MultiLineString" => GeometryType::MultiLineString,
275 "Polygon" => GeometryType::Polygon,
276 "MultiPolygon" => GeometryType::MultiPolygon,
277 "Point3D" => GeometryType::Point3D,
278 "MultiPoint3D" => GeometryType::MultiPoint3D,
279 "LineString3D" => GeometryType::LineString3D,
280 "MultiLineString3D" => GeometryType::MultiLineString3D,
281 "Polygon3D" => GeometryType::Polygon3D,
282 "MultiPolygon3D" => GeometryType::MultiPolygon3D,
283 _ => panic!("Invalid geometry type: {}", s),
284 }
285 }
286}
287
288#[derive(Clone, Serialize, Debug, PartialEq)]
290#[serde(untagged)]
291pub enum Geometry<M: Clone + Default = MValue> {
292 Point(PointGeometry<M>),
294 MultiPoint(MultiPointGeometry<M>),
296 LineString(LineStringGeometry<M>),
298 MultiLineString(MultiLineStringGeometry<M>),
300 Polygon(PolygonGeometry<M>),
302 MultiPolygon(MultiPolygonGeometry<M>),
304 Point3D(Point3DGeometry<M>),
306 MultiPoint3D(MultiPoint3DGeometry<M>),
308 LineString3D(LineString3DGeometry<M>),
310 MultiLineString3D(MultiLineString3DGeometry<M>),
312 Polygon3D(Polygon3DGeometry<M>),
314 MultiPolygon3D(MultiPolygon3DGeometry<M>),
316}
317impl<M: Clone + Default> Default for Geometry<M> {
318 fn default() -> Self {
319 Geometry::Point(PointGeometry::<M>::default())
320 }
321}
322
323#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)]
325pub struct BaseGeometry<M = MValue, G = Geometry<M>, B = BBOX> {
326 #[serde(rename = "type")]
328 pub _type: GeometryType,
329 pub coordinates: G,
331 #[serde(rename = "mValues", skip_serializing_if = "Option::is_none")]
333 pub m_values: Option<M>,
334 #[serde(skip_serializing_if = "Option::is_none")]
336 pub bbox: Option<B>,
337}
338
339pub type PointGeometry<M = MValue> = BaseGeometry<M, Point, BBox>;
341pub type MultiPointGeometry<M = MValue> = BaseGeometry<LineStringMValues<M>, MultiPoint, BBox>;
343pub type LineStringGeometry<M = MValue> = BaseGeometry<LineStringMValues<M>, LineString, BBox>;
345pub type MultiLineStringGeometry<M = MValue> =
347 BaseGeometry<MultiLineStringMValues<M>, MultiLineString, BBox>;
348pub type PolygonGeometry<M = MValue> = BaseGeometry<PolygonMValues<M>, Polygon, BBox>;
350pub type MultiPolygonGeometry<M = MValue> =
352 BaseGeometry<MultiPolygonMValues<M>, MultiPolygon, BBox>;
353pub type Point3DGeometry<M = MValue> = BaseGeometry<M, Point3D, BBox3D>;
355pub type MultiPoint3DGeometry<M = MValue> =
357 BaseGeometry<LineStringMValues<M>, MultiPoint3D, BBox3D>;
358pub type LineString3DGeometry<M = MValue> =
360 BaseGeometry<LineStringMValues<M>, LineString3D, BBox3D>;
361pub type MultiLineString3DGeometry<M = MValue> =
363 BaseGeometry<MultiLineStringMValues<M>, MultiLineString3D, BBox3D>;
364pub type Polygon3DGeometry<M = MValue> = BaseGeometry<PolygonMValues<M>, Polygon3D, BBox3D>;
366pub type MultiPolygon3DGeometry<M = MValue> =
368 BaseGeometry<MultiPolygonMValues<M>, MultiPolygon3D, BBox3D>;