1use crate::*;
2use alloc::vec::Vec;
3use serde::{Deserialize, Serialize};
4
5#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Default)]
7pub enum VectorGeometryType {
8 #[default]
10 Point,
11 MultiPoint,
13 LineString,
15 MultiLineString,
17 Polygon,
19 MultiPolygon,
21}
22impl From<&str> for VectorGeometryType {
23 fn from(s: &str) -> Self {
24 match s {
25 "Point" => VectorGeometryType::Point,
26 "MultiPoint" => VectorGeometryType::MultiPoint,
27 "LineString" => VectorGeometryType::LineString,
28 "MultiLineString" => VectorGeometryType::MultiLineString,
29 "Polygon" => VectorGeometryType::Polygon,
30 "MultiPolygon" => VectorGeometryType::MultiPolygon,
31 _ => panic!("Invalid vector geometry type: {}", s),
32 }
33 }
34}
35
36pub type VectorMultiPoint<M = MValue> = Vec<VectorPoint<M>>;
38pub type VectorLineString<M = MValue> = Vec<VectorPoint<M>>;
40pub type VectorMultiLineString<M = MValue> = Vec<VectorLineString<M>>;
42pub type VectorPolygon<M = MValue> = Vec<VectorLineString<M>>;
44pub type VectorMultiPolygon<M = MValue> = Vec<VectorPolygon<M>>;
46
47#[derive(Clone, Serialize, Debug, PartialEq)]
49#[serde(untagged)]
50pub enum VectorGeometry<M: Clone + Default = MValue> {
51 Point(VectorPointGeometry<M>),
53 MultiPoint(VectorMultiPointGeometry<M>),
55 LineString(VectorLineStringGeometry<M>),
57 MultiLineString(VectorMultiLineStringGeometry<M>),
59 Polygon(VectorPolygonGeometry<M>),
61 MultiPolygon(VectorMultiPolygonGeometry<M>),
63}
64impl<M: Clone + Default> VectorGeometry<M> {
65 pub fn bbox(&self) -> &Option<BBox3D> {
67 match self {
68 VectorGeometry::Point(g) => &g.bbox,
69 VectorGeometry::MultiPoint(g) => &g.bbox,
70 VectorGeometry::LineString(g) => &g.bbox,
71 VectorGeometry::MultiLineString(g) => &g.bbox,
72 VectorGeometry::Polygon(g) => &g.bbox,
73 VectorGeometry::MultiPolygon(g) => &g.bbox,
74 }
75 }
76
77 pub fn vec_bbox(&self) -> &Option<BBox3D> {
79 match self {
80 VectorGeometry::Point(g) => &g.vec_bbox,
81 VectorGeometry::MultiPoint(g) => &g.vec_bbox,
82 VectorGeometry::LineString(g) => &g.vec_bbox,
83 VectorGeometry::MultiLineString(g) => &g.vec_bbox,
84 VectorGeometry::Polygon(g) => &g.vec_bbox,
85 VectorGeometry::MultiPolygon(g) => &g.vec_bbox,
86 }
87 }
88
89 pub fn point(&self) -> Option<&VectorPoint<M>> {
91 match self {
92 VectorGeometry::Point(g) => Some(&g.coordinates),
93 _ => None,
94 }
95 }
96
97 pub fn new_point(coordinates: VectorPoint<M>, bbox: Option<BBox3D>) -> Self {
99 VectorGeometry::Point(VectorPointGeometry {
100 _type: VectorGeometryType::Point,
101 is_3d: coordinates.z.is_some(),
102 coordinates,
103 bbox,
104 ..Default::default()
105 })
106 }
107
108 pub fn multipoint(&self) -> Option<&VectorMultiPoint<M>> {
110 match self {
111 VectorGeometry::MultiPoint(g) => Some(&g.coordinates),
112 _ => None,
113 }
114 }
115
116 pub fn new_multipoint(coordinates: VectorMultiPoint<M>, bbox: Option<BBox3D>) -> Self {
118 VectorGeometry::MultiPoint(VectorMultiPointGeometry {
119 _type: VectorGeometryType::MultiPoint,
120 is_3d: coordinates.iter().any(|point| point.z.is_some()),
121 coordinates,
122 bbox,
123 ..Default::default()
124 })
125 }
126
127 pub fn linestring(&self) -> Option<&VectorLineString<M>> {
129 match self {
130 VectorGeometry::LineString(g) => Some(&g.coordinates),
131 _ => None,
132 }
133 }
134
135 pub fn new_linestring(coordinates: VectorLineString<M>, bbox: Option<BBox3D>) -> Self {
137 VectorGeometry::LineString(VectorLineStringGeometry {
138 _type: VectorGeometryType::LineString,
139 is_3d: coordinates.iter().any(|point| point.z.is_some()),
140 coordinates,
141 bbox,
142 ..Default::default()
143 })
144 }
145
146 pub fn multilinestring(&self) -> Option<&VectorMultiLineString<M>> {
148 match self {
149 VectorGeometry::MultiLineString(g) => Some(&g.coordinates),
150 _ => None,
151 }
152 }
153
154 pub fn new_multilinestring(
156 coordinates: VectorMultiLineString<M>,
157 bbox: Option<BBox3D>,
158 ) -> Self {
159 VectorGeometry::MultiLineString(VectorMultiLineStringGeometry {
160 _type: VectorGeometryType::MultiLineString,
161 is_3d: coordinates.iter().any(|line| line.iter().any(|point| point.z.is_some())),
162 coordinates,
163 bbox,
164 ..Default::default()
165 })
166 }
167
168 pub fn polygon(&self) -> Option<&VectorPolygon<M>> {
170 match self {
171 VectorGeometry::Polygon(g) => Some(&g.coordinates),
172 _ => None,
173 }
174 }
175
176 pub fn new_polygon(coordinates: VectorPolygon<M>, bbox: Option<BBox3D>) -> Self {
178 VectorGeometry::Polygon(VectorPolygonGeometry {
179 _type: VectorGeometryType::Polygon,
180 is_3d: coordinates.iter().any(|ring| ring.iter().any(|point| point.z.is_some())),
181 coordinates,
182 bbox,
183 ..Default::default()
184 })
185 }
186
187 pub fn multipolygon(&self) -> Option<&VectorMultiPolygon<M>> {
189 match self {
190 VectorGeometry::MultiPolygon(g) => Some(&g.coordinates),
191 _ => None,
192 }
193 }
194
195 pub fn new_multipolygon(coordinates: VectorMultiPolygon<M>, bbox: Option<BBox3D>) -> Self {
197 VectorGeometry::MultiPolygon(VectorMultiPolygonGeometry {
198 _type: VectorGeometryType::MultiPolygon,
199 is_3d: coordinates.iter().any(|polygon| {
200 polygon.iter().any(|ring| ring.iter().any(|point| point.z.is_some()))
201 }),
202 coordinates,
203 bbox,
204 ..Default::default()
205 })
206 }
207
208 pub fn set_tess(&mut self, tessellation: Vec<f64>) {
210 match self {
211 VectorGeometry::Polygon(g) => g.tessellation = Some(tessellation),
212 VectorGeometry::MultiPolygon(g) => g.tessellation = Some(tessellation),
213 _ => {}
214 }
215 }
216
217 pub fn set_indices(&mut self, indices: Vec<u32>) {
219 match self {
220 VectorGeometry::Polygon(g) => g.indices = Some(indices),
221 VectorGeometry::MultiPolygon(g) => g.indices = Some(indices),
222 _ => {}
223 }
224 }
225
226 pub fn to_m_geometry(&self) -> VectorGeometry<MValue>
228 where
229 M: MValueCompatible,
230 {
231 match self {
232 VectorGeometry::Point(g) => VectorGeometry::Point(VectorPointGeometry {
233 _type: g._type,
234 is_3d: g.is_3d,
235 coordinates: g.coordinates.to_m_value(),
236 offset: g.offset.clone(),
237 bbox: g.bbox,
238 vec_bbox: g.vec_bbox,
239 ..Default::default()
240 }),
241 VectorGeometry::MultiPoint(g) => VectorGeometry::MultiPoint(VectorMultiPointGeometry {
242 _type: g._type,
243 is_3d: g.is_3d,
244 coordinates: g.coordinates.iter().map(|point| point.to_m_value()).collect(),
245 offset: g.offset,
246 bbox: g.bbox,
247 vec_bbox: g.vec_bbox,
248 ..Default::default()
249 }),
250 VectorGeometry::LineString(g) => VectorGeometry::LineString(VectorLineStringGeometry {
251 _type: g._type,
252 is_3d: g.is_3d,
253 coordinates: g.coordinates.iter().map(|point| point.to_m_value()).collect(),
254 offset: g.offset,
255 bbox: g.bbox,
256 vec_bbox: g.vec_bbox,
257 ..Default::default()
258 }),
259 VectorGeometry::MultiLineString(g) => {
260 VectorGeometry::MultiLineString(VectorMultiLineStringGeometry {
261 _type: g._type,
262 is_3d: g.is_3d,
263 coordinates: g
264 .coordinates
265 .iter()
266 .map(|line| line.iter().map(|point| point.to_m_value()).collect())
267 .collect(),
268 offset: g.offset.clone(),
269 bbox: g.bbox,
270 vec_bbox: g.vec_bbox,
271 ..Default::default()
272 })
273 }
274 VectorGeometry::Polygon(g) => VectorGeometry::Polygon(VectorPolygonGeometry {
275 _type: g._type,
276 is_3d: g.is_3d,
277 coordinates: g
278 .coordinates
279 .iter()
280 .map(|ring| ring.iter().map(|point| point.to_m_value()).collect())
281 .collect(),
282 offset: g.offset.clone(),
283 bbox: g.bbox,
284 vec_bbox: g.vec_bbox,
285 ..Default::default()
286 }),
287 VectorGeometry::MultiPolygon(g) => {
288 VectorGeometry::MultiPolygon(VectorMultiPolygonGeometry {
289 _type: g._type,
290 is_3d: g.is_3d,
291 coordinates: g
292 .coordinates
293 .iter()
294 .map(|polygon| {
295 polygon
296 .iter()
297 .map(|ring| ring.iter().map(|point| point.to_m_value()).collect())
298 .collect()
299 })
300 .collect(),
301 offset: g.offset.clone(),
302 bbox: g.bbox,
303 vec_bbox: g.vec_bbox,
304 ..Default::default()
305 })
306 }
307 }
308 }
309}
310impl<M: Clone + Default> Default for VectorGeometry<M> {
311 fn default() -> Self {
312 VectorGeometry::Point(VectorPointGeometry::default())
313 }
314}
315
316#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
318pub struct VectorBaseGeometry<G = VectorGeometry, O = VectorOffsets> {
319 #[serde(rename = "type")]
321 pub _type: VectorGeometryType,
322 #[serde(rename = "is3D")]
324 pub is_3d: bool,
325 pub coordinates: G,
327 #[serde(skip_serializing_if = "Option::is_none")]
329 pub offset: Option<O>,
330 #[serde(skip_serializing_if = "Option::is_none")]
332 pub bbox: Option<BBox3D>,
333 #[serde(skip)]
335 pub vec_bbox: Option<BBox3D>,
336 #[serde(skip_serializing_if = "Option::is_none")]
338 pub indices: Option<Vec<u32>>,
339 #[serde(skip_serializing_if = "Option::is_none")]
341 pub tessellation: Option<Vec<f64>>,
342}
343
344#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
346pub enum VectorOffsets {
347 LineOffset(VectorLineOffset),
349 MultiLineOffset(VectorMultiLineOffset),
351 PolygonOffset(VectorPolygonOffset),
353 MultiPolygonOffset(VectorMultiPolygonOffset),
355}
356impl Default for VectorOffsets {
357 fn default() -> Self {
358 VectorOffsets::LineOffset(0.0)
359 }
360}
361pub type VectorLineOffset = f64;
363pub type VectorMultiLineOffset = Vec<VectorLineOffset>;
365pub type VectorPolygonOffset = VectorMultiLineOffset;
367pub type VectorMultiPolygonOffset = Vec<VectorPolygonOffset>;
369
370pub type VectorPointGeometry<M = MValue> = VectorBaseGeometry<VectorPoint<M>>;
372pub type VectorMultiPointGeometry<M = MValue> =
374 VectorBaseGeometry<VectorMultiPoint<M>, VectorLineOffset>;
375pub type VectorLineStringGeometry<M = MValue> =
377 VectorBaseGeometry<VectorLineString<M>, VectorLineOffset>;
378pub type VectorMultiLineStringGeometry<M = MValue> =
380 VectorBaseGeometry<VectorMultiLineString<M>, VectorMultiLineOffset>;
381pub type VectorPolygonGeometry<M = MValue> =
383 VectorBaseGeometry<VectorPolygon<M>, VectorPolygonOffset>;
384pub type VectorMultiPolygonGeometry<M = MValue> =
386 VectorBaseGeometry<VectorMultiPolygon<M>, VectorMultiPolygonOffset>;