1#![no_std]
2#![forbid(unsafe_code)]
3#![deny(missing_docs)]
4#![cfg_attr(docsrs, feature(doc_cfg))]
5
6extern crate alloc;
13
14pub mod geometry;
16pub mod impls;
18pub mod map;
20pub mod shape;
22pub mod value;
24
25use alloc::{collections::BTreeSet, string::String, vec::Vec};
26pub use geometry::*;
27pub use impls::*;
28pub use map::*;
29use serde::{Deserialize, Serialize};
30pub use shape::*;
31pub use value::*;
32
33#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
35pub enum Projection {
36 #[default]
38 S2,
39 WG,
41}
42
43#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Default)]
47pub enum Face {
48 #[default]
50 Face0 = 0,
51 Face1 = 1,
53 Face2 = 2,
55 Face3 = 3,
57 Face4 = 4,
59 Face5 = 5,
61 WM = 6,
63}
64impl From<Face> for u8 {
65 fn from(face: Face) -> Self {
66 face as u8
67 }
68}
69impl From<u8> for Face {
70 fn from(face: u8) -> Self {
71 match face {
72 1 => Face::Face1,
73 2 => Face::Face2,
74 3 => Face::Face3,
75 4 => Face::Face4,
76 5 => Face::Face5,
77 6 => Face::WM,
78 _ => Face::Face0,
79 }
80 }
81}
82impl serde::Serialize for Face {
83 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
84 where
85 S: serde::Serializer,
86 {
87 serializer.serialize_u8(*self as u8)
88 }
89}
90
91impl<'de> serde::Deserialize<'de> for Face {
92 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
93 where
94 D: serde::Deserializer<'de>,
95 {
96 let value = u8::deserialize(deserializer)?;
97 match value {
98 0 => Ok(Face::Face0),
99 1 => Ok(Face::Face1),
100 2 => Ok(Face::Face2),
101 3 => Ok(Face::Face3),
102 4 => Ok(Face::Face4),
103 5 => Ok(Face::Face5),
104 6 => Ok(Face::WM),
105 _ => Err(serde::de::Error::custom("Invalid face value")),
106 }
107 }
108}
109
110#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
112pub enum FeatureCollectionType {
113 #[default]
115 FeatureCollection,
116}
117impl From<&str> for FeatureCollectionType {
118 fn from(_: &str) -> Self {
119 FeatureCollectionType::FeatureCollection
120 }
121}
122
123#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
125pub enum S2FeatureCollectionType {
126 #[default]
128 S2FeatureCollection,
129}
130impl From<&str> for S2FeatureCollectionType {
131 fn from(_: &str) -> Self {
132 S2FeatureCollectionType::S2FeatureCollection
133 }
134}
135
136#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
140pub struct FeatureCollection<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
141 #[serde(rename = "type")]
143 pub _type: FeatureCollectionType,
144 pub features: Vec<Features<M, P, D>>,
146 #[serde(skip_serializing_if = "Option::is_none")]
148 pub attributions: Option<Attributions>,
149 #[serde(skip_serializing_if = "Option::is_none")]
151 pub bbox: Option<BBox>,
152}
153impl<M, P: Clone + Default, D: Clone + Default> FeatureCollection<M, P, D> {
154 pub fn new(attributions: Option<Attributions>) -> Self {
156 Self { _type: "FeatureCollection".into(), features: Vec::new(), attributions, bbox: None }
157 }
158
159 pub fn update_bbox(&mut self, bbox: BBox) {
161 let mut self_bbox = self.bbox.unwrap_or_default();
162 self_bbox = self_bbox.merge(&bbox);
163 self.bbox = Some(self_bbox);
164 }
165}
166impl<M, P: Clone + Default, D: Clone + Default> From<Vec<VectorFeature<M, P, D>>>
167 for FeatureCollection<M, P, D>
168{
169 fn from(mut features: Vec<VectorFeature<M, P, D>>) -> Self {
170 let mut bbox = BBox::default();
171 for feature in features.iter_mut() {
172 bbox.merge_in_place(&BBox::from(feature.geometry.bbox()));
173 }
174 Self {
175 _type: FeatureCollectionType::FeatureCollection,
176 features: features.into_iter().map(Features::VectorFeature).collect(),
177 attributions: None,
178 bbox: Some(bbox),
179 }
180 }
181}
182impl<M, P: Clone + Default, D: Clone + Default> From<Vec<Feature<M, P, D>>>
183 for FeatureCollection<M, P, D>
184{
185 fn from(mut features: Vec<Feature<M, P, D>>) -> Self {
186 let mut bbox: BBox = BBox::default();
187 for feature in features.iter_mut() {
188 bbox.merge_in_place(&BBox::from(feature.geometry.bbox()));
189 }
190 Self {
191 _type: FeatureCollectionType::FeatureCollection,
192 features: features.into_iter().map(Features::Feature).collect(),
193 attributions: None,
194 bbox: Some(bbox),
195 }
196 }
197}
198impl<M, P: Clone + Default, D: Clone + Default> From<Vec<Features<M, P, D>>>
199 for FeatureCollection<M, P, D>
200{
201 fn from(mut features: Vec<Features<M, P, D>>) -> Self {
202 let mut bbox: BBox = BBox::default();
203 for feature in features.iter_mut() {
204 match feature {
205 Features::Feature(f) => {
206 bbox.merge_in_place(&BBox::from(f.geometry.bbox()));
207 }
208 Features::VectorFeature(f) => {
209 bbox.merge_in_place(&BBox::from(f.geometry.bbox()));
210 }
211 }
212 }
213 Self {
214 _type: FeatureCollectionType::FeatureCollection,
215 features,
216 attributions: None,
217 bbox: Some(bbox),
218 }
219 }
220}
221
222#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
224pub struct S2FeatureCollection<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue>
225{
226 #[serde(rename = "type")]
228 pub _type: S2FeatureCollectionType,
229 pub features: Vec<VectorFeature<M, P, D>>,
231 pub faces: Vec<Face>,
233 #[serde(skip_serializing_if = "Option::is_none")]
235 pub attributions: Option<Attributions>,
236 #[serde(skip_serializing_if = "Option::is_none")]
238 pub bbox: Option<BBox>,
239}
240impl<M, P: Clone + Default, D: Clone + Default> S2FeatureCollection<M, P, D> {
241 pub fn new(attributions: Option<Attributions>) -> Self {
243 Self {
244 _type: "S2FeatureCollection".into(),
245 features: Vec::new(),
246 faces: Vec::new(),
247 attributions,
248 bbox: None,
249 }
250 }
251
252 pub fn update_bbox(&mut self, bbox: BBox) {
254 let mut self_bbox = self.bbox.unwrap_or_default();
255 self_bbox = self_bbox.merge(&bbox);
256 self.bbox = Some(self_bbox);
257 }
258
259 pub fn add_face(&mut self, face: Face) {
261 if !self.faces.contains(&face) {
262 self.faces.push(face);
263 }
264 }
265}
266impl<M, P: Clone + Default, D: Clone + Default> From<Vec<VectorFeature<M, P, D>>>
267 for S2FeatureCollection<M, P, D>
268{
269 fn from(mut features: Vec<VectorFeature<M, P, D>>) -> Self {
270 let mut bbox = BBox::default();
271 let mut faces: BTreeSet<Face> = BTreeSet::new();
272 for feature in features.iter_mut() {
273 bbox.merge_in_place(&BBox::from(feature.geometry.bbox()));
274 faces.insert(feature.face);
275 }
276 Self {
277 _type: S2FeatureCollectionType::S2FeatureCollection,
278 features,
279 attributions: None,
280 faces: faces.into_iter().collect(),
281 bbox: Some(bbox),
282 }
283 }
284}
285
286#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
290pub enum FeatureType {
291 #[default]
293 Feature,
294}
295impl From<&str> for FeatureType {
296 fn from(_: &str) -> Self {
297 FeatureType::Feature
298 }
299}
300
301#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
303pub struct Feature<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
304 #[serde(rename = "type")]
306 pub _type: FeatureType,
307 #[serde(skip_serializing_if = "Option::is_none")]
309 pub id: Option<u64>,
310 #[serde(default)]
312 pub properties: P,
313 pub geometry: Geometry<D>,
315 #[serde(skip_serializing_if = "Option::is_none")]
317 pub metadata: Option<M>,
318}
319impl<M, P: Clone + Default, D: Clone + Default> Feature<M, P, D> {
320 pub fn new(id: Option<u64>, properties: P, geometry: Geometry<D>, metadata: Option<M>) -> Self {
322 Self { _type: "Feature".into(), id, properties, geometry, metadata }
323 }
324}
325impl<M, P: Clone + Default, D: Clone + Default> Default for Feature<M, P, D> {
326 fn default() -> Self {
327 Self {
328 _type: "Feature".into(),
329 id: None,
330 properties: Default::default(),
331 geometry: Default::default(),
332 metadata: None,
333 }
334 }
335}
336
337#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Default)]
339pub enum VectorFeatureType {
340 #[default]
342 VectorFeature,
343 S2Feature,
345}
346impl From<&str> for VectorFeatureType {
347 fn from(s: &str) -> Self {
348 match s {
349 "S2Feature" => VectorFeatureType::S2Feature,
350 _ => VectorFeatureType::VectorFeature,
351 }
352 }
353}
354
355#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
357pub struct VectorFeature<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
358 #[serde(rename = "type")]
360 pub _type: VectorFeatureType,
361 #[serde(skip_serializing_if = "Option::is_none")]
363 pub id: Option<u64>,
364 #[serde(default)]
366 pub face: Face,
367 #[serde(default)]
369 pub properties: P,
370 pub geometry: VectorGeometry<D>,
372 #[serde(skip_serializing_if = "Option::is_none")]
374 pub metadata: Option<M>,
375}
376impl<M, P: Clone + Default, D: Clone + Default> Default for VectorFeature<M, P, D> {
377 fn default() -> Self {
378 Self {
379 _type: "VectorFeature".into(),
380 face: Face::WM,
381 id: None,
382 properties: Default::default(),
383 geometry: Default::default(),
384 metadata: None,
385 }
386 }
387}
388impl<M, P: Clone + Default, D: Clone + Default> VectorFeature<M, P, D> {
389 pub fn new_wm(
391 id: Option<u64>,
392 properties: P,
393 geometry: VectorGeometry<D>,
394 metadata: Option<M>,
395 ) -> Self {
396 Self { _type: "VectorFeature".into(), face: Face::WM, id, properties, geometry, metadata }
397 }
398
399 pub fn new_s2(
401 id: Option<u64>,
402 face: Face,
403 properties: P,
404 geometry: VectorGeometry<D>,
405 metadata: Option<M>,
406 ) -> Self {
407 Self { _type: "S2Feature".into(), face, id, properties, geometry, metadata }
408 }
409
410 pub fn from_vector_feature(
412 feature: &VectorFeature<M, P, D>,
413 geometry: Option<VectorGeometry<D>>,
414 ) -> Self
415 where
416 M: Clone,
417 {
418 Self {
419 _type: feature._type.clone(),
420 id: feature.id,
421 face: feature.face,
422 properties: feature.properties.clone(),
423 geometry: geometry.unwrap_or(feature.geometry.clone()),
424 metadata: feature.metadata.clone(),
425 }
426 }
427
428 pub fn to_m_vector_feature<M2>(
431 &self,
432 to_meta: impl FnOnce(Option<&M>) -> Option<M2>,
433 ) -> VectorFeature<M2, Properties, MValue>
434 where
435 M: Clone,
436 P: MValueCompatible,
437 D: MValueCompatible,
438 {
439 VectorFeature {
440 _type: self._type.clone(),
441 id: self.id,
442 face: self.face,
443 properties: self.properties.clone().into(),
444 geometry: self.geometry.to_m_geometry(),
445 metadata: to_meta(self.metadata.as_ref()),
446 }
447 }
448}
449
450pub type Attributions = Map<String, String>;
456
457#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
459#[serde(untagged)]
460pub enum FeatureCollections<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
461 FeatureCollection(FeatureCollection<M, P, D>),
463 S2FeatureCollection(S2FeatureCollection<M, P, D>),
465}
466impl<M, P: Clone + Default, D: Clone + Default> From<FeatureCollection<M, P, D>>
467 for FeatureCollections<M, P, D>
468{
469 fn from(f: FeatureCollection<M, P, D>) -> Self {
470 FeatureCollections::FeatureCollection(f)
471 }
472}
473impl<M, P: Clone + Default, D: Clone + Default> From<S2FeatureCollection<M, P, D>>
474 for FeatureCollections<M, P, D>
475{
476 fn from(f: S2FeatureCollection<M, P, D>) -> Self {
477 FeatureCollections::S2FeatureCollection(f)
478 }
479}
480
481#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
483#[serde(untagged)]
484pub enum Features<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
485 Feature(Feature<M, P, D>),
487 VectorFeature(VectorFeature<M, P, D>),
489}
490impl<M, P: Clone + Default, D: Clone + Default> From<Feature<M, P, D>> for Features<M, P, D> {
491 fn from(f: Feature<M, P, D>) -> Self {
492 Features::Feature(f)
493 }
494}
495impl<M, P: Clone + Default, D: Clone + Default> From<VectorFeature<M, P, D>> for Features<M, P, D> {
496 fn from(f: VectorFeature<M, P, D>) -> Self {
497 Features::VectorFeature(f)
498 }
499}
500
501#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
503#[serde(untagged)]
504pub enum JSONCollection<M = (), P: Clone + Default = Properties, D: Clone + Default = MValue> {
505 FeatureCollection(FeatureCollection<M, P, D>),
507 S2FeatureCollection(S2FeatureCollection<M, P, D>),
509 Feature(Feature<M, P, D>),
511 VectorFeature(VectorFeature<M, P, D>),
513}
514impl<M, P: Clone + Default, D: Clone + Default> From<FeatureCollection<M, P, D>>
515 for JSONCollection<M, P, D>
516{
517 fn from(f: FeatureCollection<M, P, D>) -> Self {
518 JSONCollection::FeatureCollection(f)
519 }
520}
521impl<M, P: Clone + Default, D: Clone + Default> From<S2FeatureCollection<M, P, D>>
522 for JSONCollection<M, P, D>
523{
524 fn from(f: S2FeatureCollection<M, P, D>) -> Self {
525 JSONCollection::S2FeatureCollection(f)
526 }
527}
528impl<M, P: Clone + Default, D: Clone + Default> From<Feature<M, P, D>> for JSONCollection<M, P, D> {
529 fn from(f: Feature<M, P, D>) -> Self {
530 JSONCollection::Feature(f)
531 }
532}
533impl<M, P: Clone + Default, D: Clone + Default> From<VectorFeature<M, P, D>>
534 for JSONCollection<M, P, D>
535{
536 fn from(f: VectorFeature<M, P, D>) -> Self {
537 JSONCollection::VectorFeature(f)
538 }
539}