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)]
71#[serde(untagged)]
72pub enum VectorGeometry<M: Clone + Default = MValue> {
73 Point(VectorPointGeometry<M>),
75 MultiPoint(VectorMultiPointGeometry<M>),
77 LineString(VectorLineStringGeometry<M>),
79 MultiLineString(VectorMultiLineStringGeometry<M>),
81 Polygon(VectorPolygonGeometry<M>),
83 MultiPolygon(VectorMultiPolygonGeometry<M>),
85}
86impl<M: Clone + Default> VectorGeometry<M> {
87 pub fn bbox(&self) -> &Option<BBox3D> {
89 match self {
90 VectorGeometry::Point(g) => &g.bbox,
91 VectorGeometry::MultiPoint(g) => &g.bbox,
92 VectorGeometry::LineString(g) => &g.bbox,
93 VectorGeometry::MultiLineString(g) => &g.bbox,
94 VectorGeometry::Polygon(g) => &g.bbox,
95 VectorGeometry::MultiPolygon(g) => &g.bbox,
96 }
97 }
98
99 pub fn vec_bbox(&self) -> &Option<BBox3D> {
101 match self {
102 VectorGeometry::Point(g) => &g.vec_bbox,
103 VectorGeometry::MultiPoint(g) => &g.vec_bbox,
104 VectorGeometry::LineString(g) => &g.vec_bbox,
105 VectorGeometry::MultiLineString(g) => &g.vec_bbox,
106 VectorGeometry::Polygon(g) => &g.vec_bbox,
107 VectorGeometry::MultiPolygon(g) => &g.vec_bbox,
108 }
109 }
110
111 pub fn point(&self) -> Option<&VectorPoint<M>> {
113 match self {
114 VectorGeometry::Point(g) => Some(&g.coordinates),
115 _ => None,
116 }
117 }
118
119 pub fn new_point(coordinates: VectorPoint<M>, bbox: Option<BBox3D>) -> Self {
121 VectorGeometry::Point(VectorPointGeometry {
122 _type: VectorGeometryType::Point,
123 is_3d: coordinates.z.is_some(),
124 coordinates,
125 bbox,
126 ..Default::default()
127 })
128 }
129
130 pub fn multipoint(&self) -> Option<&VectorMultiPoint<M>> {
132 match self {
133 VectorGeometry::MultiPoint(g) => Some(&g.coordinates),
134 _ => None,
135 }
136 }
137
138 pub fn new_multipoint(coordinates: VectorMultiPoint<M>, bbox: Option<BBox3D>) -> Self {
140 VectorGeometry::MultiPoint(VectorMultiPointGeometry {
141 _type: VectorGeometryType::MultiPoint,
142 is_3d: coordinates.iter().any(|point| point.z.is_some()),
143 coordinates,
144 bbox,
145 ..Default::default()
146 })
147 }
148
149 pub fn linestring(&self) -> Option<&VectorLineString<M>> {
151 match self {
152 VectorGeometry::LineString(g) => Some(&g.coordinates),
153 _ => None,
154 }
155 }
156
157 pub fn new_linestring(coordinates: VectorLineString<M>, bbox: Option<BBox3D>) -> Self {
159 VectorGeometry::LineString(VectorLineStringGeometry {
160 _type: VectorGeometryType::LineString,
161 is_3d: coordinates.iter().any(|point| point.z.is_some()),
162 coordinates,
163 bbox,
164 ..Default::default()
165 })
166 }
167
168 pub fn multilinestring(&self) -> Option<&VectorMultiLineString<M>> {
170 match self {
171 VectorGeometry::MultiLineString(g) => Some(&g.coordinates),
172 _ => None,
173 }
174 }
175
176 pub fn new_multilinestring(
178 coordinates: VectorMultiLineString<M>,
179 bbox: Option<BBox3D>,
180 ) -> Self {
181 VectorGeometry::MultiLineString(VectorMultiLineStringGeometry {
182 _type: VectorGeometryType::MultiLineString,
183 is_3d: coordinates.iter().any(|line| line.iter().any(|point| point.z.is_some())),
184 coordinates,
185 bbox,
186 ..Default::default()
187 })
188 }
189
190 pub fn polygon(&self) -> Option<&VectorPolygon<M>> {
192 match self {
193 VectorGeometry::Polygon(g) => Some(&g.coordinates),
194 _ => None,
195 }
196 }
197
198 pub fn new_polygon(coordinates: VectorPolygon<M>, bbox: Option<BBox3D>) -> Self {
200 VectorGeometry::Polygon(VectorPolygonGeometry {
201 _type: VectorGeometryType::Polygon,
202 is_3d: coordinates.iter().any(|ring| ring.iter().any(|point| point.z.is_some())),
203 coordinates,
204 bbox,
205 ..Default::default()
206 })
207 }
208
209 pub fn multipolygon(&self) -> Option<&VectorMultiPolygon<M>> {
211 match self {
212 VectorGeometry::MultiPolygon(g) => Some(&g.coordinates),
213 _ => None,
214 }
215 }
216
217 pub fn new_multipolygon(coordinates: VectorMultiPolygon<M>, bbox: Option<BBox3D>) -> Self {
219 VectorGeometry::MultiPolygon(VectorMultiPolygonGeometry {
220 _type: VectorGeometryType::MultiPolygon,
221 is_3d: coordinates.iter().any(|polygon| {
222 polygon.iter().any(|ring| ring.iter().any(|point| point.z.is_some()))
223 }),
224 coordinates,
225 bbox,
226 ..Default::default()
227 })
228 }
229
230 pub fn set_tess(&mut self, tessellation: Vec<f64>) {
232 match self {
233 VectorGeometry::Polygon(g) => g.tessellation = Some(tessellation),
234 VectorGeometry::MultiPolygon(g) => g.tessellation = Some(tessellation),
235 _ => {}
236 }
237 }
238
239 pub fn set_indices(&mut self, indices: Vec<u32>) {
241 match self {
242 VectorGeometry::Polygon(g) => g.indices = Some(indices),
243 VectorGeometry::MultiPolygon(g) => g.indices = Some(indices),
244 _ => {}
245 }
246 }
247
248 pub fn to_m_geometry(&self) -> VectorGeometry<MValue>
250 where
251 M: MValueCompatible,
252 {
253 match self {
254 VectorGeometry::Point(g) => VectorGeometry::Point(VectorPointGeometry {
255 _type: g._type,
256 is_3d: g.is_3d,
257 coordinates: g.coordinates.to_m_value(),
258 offset: g.offset.clone(),
259 bbox: g.bbox,
260 vec_bbox: g.vec_bbox,
261 ..Default::default()
262 }),
263 VectorGeometry::MultiPoint(g) => VectorGeometry::MultiPoint(VectorMultiPointGeometry {
264 _type: g._type,
265 is_3d: g.is_3d,
266 coordinates: g.coordinates.iter().map(|point| point.to_m_value()).collect(),
267 offset: g.offset,
268 bbox: g.bbox,
269 vec_bbox: g.vec_bbox,
270 ..Default::default()
271 }),
272 VectorGeometry::LineString(g) => VectorGeometry::LineString(VectorLineStringGeometry {
273 _type: g._type,
274 is_3d: g.is_3d,
275 coordinates: g.coordinates.iter().map(|point| point.to_m_value()).collect(),
276 offset: g.offset,
277 bbox: g.bbox,
278 vec_bbox: g.vec_bbox,
279 ..Default::default()
280 }),
281 VectorGeometry::MultiLineString(g) => {
282 VectorGeometry::MultiLineString(VectorMultiLineStringGeometry {
283 _type: g._type,
284 is_3d: g.is_3d,
285 coordinates: g
286 .coordinates
287 .iter()
288 .map(|line| line.iter().map(|point| point.to_m_value()).collect())
289 .collect(),
290 offset: g.offset.clone(),
291 bbox: g.bbox,
292 vec_bbox: g.vec_bbox,
293 ..Default::default()
294 })
295 }
296 VectorGeometry::Polygon(g) => VectorGeometry::Polygon(VectorPolygonGeometry {
297 _type: g._type,
298 is_3d: g.is_3d,
299 coordinates: g
300 .coordinates
301 .iter()
302 .map(|ring| ring.iter().map(|point| point.to_m_value()).collect())
303 .collect(),
304 offset: g.offset.clone(),
305 bbox: g.bbox,
306 vec_bbox: g.vec_bbox,
307 ..Default::default()
308 }),
309 VectorGeometry::MultiPolygon(g) => {
310 VectorGeometry::MultiPolygon(VectorMultiPolygonGeometry {
311 _type: g._type,
312 is_3d: g.is_3d,
313 coordinates: g
314 .coordinates
315 .iter()
316 .map(|polygon| {
317 polygon
318 .iter()
319 .map(|ring| ring.iter().map(|point| point.to_m_value()).collect())
320 .collect()
321 })
322 .collect(),
323 offset: g.offset.clone(),
324 bbox: g.bbox,
325 vec_bbox: g.vec_bbox,
326 ..Default::default()
327 })
328 }
329 }
330 }
331}
332impl<M: Clone + Default> Default for VectorGeometry<M> {
333 fn default() -> Self {
334 VectorGeometry::Point(VectorPointGeometry::default())
335 }
336}
337
338#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
340pub struct VectorBaseGeometry<G = VectorGeometry, O = VectorOffsets> {
341 #[serde(rename = "type")]
343 pub _type: VectorGeometryType,
344 #[serde(rename = "is3D", default)]
346 pub is_3d: bool,
347 pub coordinates: G,
349 #[serde(skip_serializing_if = "Option::is_none")]
351 pub offset: Option<O>,
352 #[serde(skip_serializing_if = "Option::is_none")]
354 pub bbox: Option<BBox3D>,
355 #[serde(skip)]
357 pub vec_bbox: Option<BBox3D>,
358 #[serde(skip_serializing_if = "Option::is_none")]
360 pub indices: Option<Vec<u32>>,
361 #[serde(skip_serializing_if = "Option::is_none")]
363 pub tessellation: Option<Vec<f64>>,
364}
365
366#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
368pub enum VectorOffsets {
369 LineOffset(VectorLineOffset),
371 MultiLineOffset(VectorMultiLineOffset),
373 PolygonOffset(VectorPolygonOffset),
375 MultiPolygonOffset(VectorMultiPolygonOffset),
377}
378impl Default for VectorOffsets {
379 fn default() -> Self {
380 VectorOffsets::LineOffset(0.0)
381 }
382}
383pub type VectorLineOffset = f64;
385pub type VectorMultiLineOffset = Vec<VectorLineOffset>;
387pub type VectorPolygonOffset = VectorMultiLineOffset;
389pub type VectorMultiPolygonOffset = Vec<VectorPolygonOffset>;
391
392pub type VectorPointGeometry<M = MValue> = VectorBaseGeometry<VectorPoint<M>>;
394pub type VectorMultiPointGeometry<M = MValue> =
396 VectorBaseGeometry<VectorMultiPoint<M>, VectorLineOffset>;
397pub type VectorLineStringGeometry<M = MValue> =
399 VectorBaseGeometry<VectorLineString<M>, VectorLineOffset>;
400pub type VectorMultiLineStringGeometry<M = MValue> =
402 VectorBaseGeometry<VectorMultiLineString<M>, VectorMultiLineOffset>;
403pub type VectorPolygonGeometry<M = MValue> =
405 VectorBaseGeometry<VectorPolygon<M>, VectorPolygonOffset>;
406pub type VectorMultiPolygonGeometry<M = MValue> =
408 VectorBaseGeometry<VectorMultiPolygon<M>, VectorMultiPolygonOffset>;