gistools/geometry/tools/
convert.rs

1use crate::geometry::{ConvertFeature, ConvertVectorFeatureS2, ConvertVectorFeatureWM};
2use alloc::{vec, vec::Vec};
3use s2json::{Feature, Features, JSONCollection, Projection, VectorFeature};
4
5/// Given an input data, convert it to a vector of VectorFeature
6pub fn convert<M: Clone, P: Clone + Default, D: Clone + Default>(
7    projection: Projection,
8    data: &JSONCollection<M, P, D>,
9    build_bbox: Option<bool>,
10    to_unit_scale: Option<bool>,
11) -> Vec<VectorFeature<M, P, D>>
12where
13    VectorFeature<M, P, D>: ConvertVectorFeatureWM<M, P, D> + ConvertVectorFeatureS2<M, P, D>,
14    Feature<M, P, D>: ConvertFeature<M, P, D>,
15{
16    let to_unit_scale = to_unit_scale.unwrap_or(false);
17    let mut res: Vec<VectorFeature<M, P, D>> = vec![];
18
19    match data {
20        JSONCollection::FeatureCollection(feature_collection) => {
21            for feature in &feature_collection.features {
22                match &feature {
23                    Features::Feature(feature) => {
24                        res.extend(convert_feature(projection, feature, to_unit_scale, build_bbox));
25                    }
26                    Features::VectorFeature(feature) => {
27                        res.extend(convert_vector_feature(projection, feature, to_unit_scale))
28                    }
29                }
30            }
31        }
32        JSONCollection::S2FeatureCollection(feature_collection) => {
33            for feature in &feature_collection.features {
34                res.extend(convert_vector_feature(projection, feature, to_unit_scale));
35            }
36        }
37        JSONCollection::Feature(feature) => {
38            res.extend(convert_feature(projection, feature, to_unit_scale, build_bbox));
39        }
40        JSONCollection::VectorFeature(feature) => {
41            res.extend(convert_vector_feature(projection, feature, to_unit_scale));
42        }
43    }
44
45    res
46}
47
48/// Convert a GeoJSON Feature to the appropriate VectorFeature
49fn convert_feature<M: Clone, P: Clone + Default, D: Clone + Default>(
50    projection: Projection,
51    data: &Feature<M, P, D>,
52    to_unit_scale: bool,
53    build_bbox: Option<bool>,
54) -> Vec<VectorFeature<M, P, D>>
55where
56    VectorFeature<M, P, D>: ConvertVectorFeatureWM<M, P, D> + ConvertVectorFeatureS2<M, P, D>,
57    Feature<M, P, D>: ConvertFeature<M, P, D>,
58{
59    let mut vf: VectorFeature<M, P, D> = Feature::to_vector(data, build_bbox);
60    match projection {
61        Projection::S2 => vf.to_s2(),
62        Projection::WG => {
63            if to_unit_scale {
64                vf.to_unit_scale();
65            }
66            vec![vf]
67        }
68    }
69}
70
71/// Convert a GeoJSON VectorFeature to the appropriate VectorFeature
72fn convert_vector_feature<M: Clone, P: Clone + Default, D: Clone + Default>(
73    projection: Projection,
74    data: &VectorFeature<M, P, D>,
75    to_unit_scale: bool,
76) -> Vec<VectorFeature<M, P, D>>
77where
78    VectorFeature<M, P, D>: ConvertVectorFeatureWM<M, P, D>,
79{
80    match projection {
81        Projection::S2 => data.to_s2(),
82        Projection::WG => {
83            let mut vf = data.to_wm();
84            if to_unit_scale {
85                vf.to_unit_scale();
86            }
87            vec![vf]
88        }
89    }
90}