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}
226impl<M: Clone + Default> Default for VectorGeometry<M> {
227 fn default() -> Self {
228 VectorGeometry::Point(VectorPointGeometry::default())
229 }
230}
231
232#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
234pub struct VectorBaseGeometry<G = VectorGeometry, O = VectorOffsets> {
235 #[serde(rename = "type")]
237 pub _type: VectorGeometryType,
238 #[serde(rename = "is3D")]
240 pub is_3d: bool,
241 pub coordinates: G,
243 #[serde(skip_serializing_if = "Option::is_none")]
245 pub offset: Option<O>,
246 #[serde(skip_serializing_if = "Option::is_none")]
248 pub bbox: Option<BBox3D>,
249 #[serde(skip)]
251 pub vec_bbox: Option<BBox3D>,
252 #[serde(skip_serializing_if = "Option::is_none")]
254 pub indices: Option<Vec<u32>>,
255 #[serde(skip_serializing_if = "Option::is_none")]
257 pub tessellation: Option<Vec<f64>>,
258}
259
260#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
262pub enum VectorOffsets {
263 LineOffset(VectorLineOffset),
265 MultiLineOffset(VectorMultiLineOffset),
267 PolygonOffset(VectorPolygonOffset),
269 MultiPolygonOffset(VectorMultiPolygonOffset),
271}
272impl Default for VectorOffsets {
273 fn default() -> Self {
274 VectorOffsets::LineOffset(0.0)
275 }
276}
277pub type VectorLineOffset = f64;
279pub type VectorMultiLineOffset = Vec<VectorLineOffset>;
281pub type VectorPolygonOffset = VectorMultiLineOffset;
283pub type VectorMultiPolygonOffset = Vec<VectorPolygonOffset>;
285
286pub type VectorPointGeometry<M = MValue> = VectorBaseGeometry<VectorPoint<M>>;
288pub type VectorMultiPointGeometry<M = MValue> =
290 VectorBaseGeometry<VectorMultiPoint<M>, VectorLineOffset>;
291pub type VectorLineStringGeometry<M = MValue> =
293 VectorBaseGeometry<VectorLineString<M>, VectorLineOffset>;
294pub type VectorMultiLineStringGeometry<M = MValue> =
296 VectorBaseGeometry<VectorMultiLineString<M>, VectorMultiLineOffset>;
297pub type VectorPolygonGeometry<M = MValue> =
299 VectorBaseGeometry<VectorPolygon<M>, VectorPolygonOffset>;
300pub type VectorMultiPolygonGeometry<M = MValue> =
302 VectorBaseGeometry<VectorMultiPolygon<M>, VectorMultiPolygonOffset>;