open_vector_tile/base/
s2json_impl.rs

1use super::{
2    tess_to_points, tess_to_points_3d, BaseVectorFeature, BaseVectorLines3DFeature,
3    BaseVectorLinesFeature, BaseVectorPoints3DFeature, BaseVectorPointsFeature,
4    BaseVectorPolys3DFeature, BaseVectorPolysFeature,
5};
6use crate::{
7    VectorLine3DWithOffset, VectorLineWithOffset, VectorLines3DWithOffset, VectorLinesWithOffset,
8};
9use alloc::{vec, vec::Vec};
10use s2json::{
11    MValueCompatible, Properties, VectorFeature, VectorLineString, VectorMultiLineString,
12    VectorMultiPolygon,
13};
14
15// This is a convenience function to convert an S2JSON VectorFeature to a BaseVectorFeature
16
17impl<M: Clone, P: MValueCompatible, D: MValueCompatible> From<&VectorFeature<M, P, D>>
18    for BaseVectorFeature
19{
20    fn from(vf: &VectorFeature<M, P, D>) -> Self {
21        let id = vf.id;
22        let properties: Properties = vf.properties.clone().into();
23
24        match &vf.geometry {
25            s2json::VectorGeometry::Point(p) => {
26                if !p.is_3d {
27                    BaseVectorFeature::BaseVectorPointsFeature(BaseVectorPointsFeature::new(
28                        id,
29                        vec![(&p.coordinates).into()],
30                        properties,
31                        p.bbox.map(|b| b.into()),
32                    ))
33                } else {
34                    BaseVectorFeature::BaseVectorPoints3DFeature(BaseVectorPoints3DFeature::new(
35                        id,
36                        vec![(&p.coordinates).into()],
37                        properties,
38                        p.bbox,
39                    ))
40                }
41            }
42            s2json::VectorGeometry::MultiPoint(mp) => {
43                if !mp.is_3d {
44                    BaseVectorFeature::BaseVectorPointsFeature(BaseVectorPointsFeature::new(
45                        id,
46                        mp.coordinates.iter().map(|p| p.into()).collect(),
47                        properties,
48                        mp.bbox.map(|b| b.into()),
49                    ))
50                } else {
51                    BaseVectorFeature::BaseVectorPoints3DFeature(BaseVectorPoints3DFeature::new(
52                        id,
53                        mp.coordinates.iter().map(|p| p.into()).collect(),
54                        properties,
55                        mp.bbox,
56                    ))
57                }
58            }
59            s2json::VectorGeometry::LineString(l) => {
60                if !l.is_3d {
61                    BaseVectorFeature::BaseVectorLinesFeature(BaseVectorLinesFeature::new(
62                        id,
63                        vec![vl_to_ls_w_off(l.offset.unwrap_or_default(), &l.coordinates)],
64                        properties,
65                        l.bbox.map(|b| b.into()),
66                    ))
67                } else {
68                    BaseVectorFeature::BaseVectorLines3DFeature(BaseVectorLines3DFeature::new(
69                        id,
70                        vec![vl_to_ls_w_off_3d(l.offset.unwrap_or_default(), &l.coordinates)],
71                        properties,
72                        l.bbox,
73                    ))
74                }
75            }
76            s2json::VectorGeometry::MultiLineString(ml) => {
77                if !ml.is_3d {
78                    BaseVectorFeature::BaseVectorLinesFeature(BaseVectorLinesFeature::new(
79                        id,
80                        vml_to_ls_w_off(ml.offset.as_ref(), &ml.coordinates),
81                        properties,
82                        ml.bbox.map(|b| b.into()),
83                    ))
84                } else {
85                    BaseVectorFeature::BaseVectorLines3DFeature(BaseVectorLines3DFeature::new(
86                        id,
87                        vml_to_ls_w_off_3d(ml.offset.as_ref(), &ml.coordinates),
88                        properties,
89                        ml.bbox,
90                    ))
91                }
92            }
93            s2json::VectorGeometry::Polygon(p) => {
94                if !p.is_3d {
95                    BaseVectorFeature::BaseVectorPolysFeature(BaseVectorPolysFeature::new(
96                        id,
97                        vec![vml_to_ls_w_off(p.offset.as_ref(), &p.coordinates)],
98                        properties,
99                        p.bbox.map(|b| b.into()),
100                        p.indices.clone().unwrap_or_default(),
101                        p.tessellation.clone().map(tess_to_points).unwrap_or_default(),
102                    ))
103                } else {
104                    BaseVectorFeature::BaseVectorPolys3DFeature(BaseVectorPolys3DFeature::new(
105                        id,
106                        vec![vml_to_ls_w_off_3d(p.offset.as_ref(), &p.coordinates)],
107                        properties,
108                        p.bbox,
109                        p.indices.clone().unwrap_or_default(),
110                        p.tessellation.clone().map(tess_to_points_3d).unwrap_or_default(),
111                    ))
112                }
113            }
114            s2json::VectorGeometry::MultiPolygon(mp) => {
115                if !mp.is_3d {
116                    BaseVectorFeature::BaseVectorPolysFeature(BaseVectorPolysFeature::new(
117                        id,
118                        vmp_to_ls_w_off(mp.offset.as_ref(), &mp.coordinates),
119                        properties,
120                        mp.bbox.map(|b| b.into()),
121                        mp.indices.clone().unwrap_or_default(),
122                        mp.tessellation.clone().map(tess_to_points).unwrap_or_default(),
123                    ))
124                } else {
125                    BaseVectorFeature::BaseVectorPolys3DFeature(BaseVectorPolys3DFeature::new(
126                        id,
127                        vmp_to_ls_w_off_3d(mp.offset.as_ref(), &mp.coordinates),
128                        properties,
129                        mp.bbox,
130                        mp.indices.clone().unwrap_or_default(),
131                        mp.tessellation.clone().map(tess_to_points_3d).unwrap_or_default(),
132                    ))
133                }
134            }
135        }
136    }
137}
138
139/// Vector MultiPolygon to Vec<VectorLinesWithOffset>
140fn vmp_to_ls_w_off<D: MValueCompatible>(
141    offsets: Option<&Vec<Vec<f64>>>,
142    mp: &VectorMultiPolygon<D>,
143) -> Vec<VectorLinesWithOffset> {
144    mp.iter().enumerate().map(|(i, l)| vml_to_ls_w_off(offsets.and_then(|o| o.get(i)), l)).collect()
145}
146
147/// Vector MultiLineString to VectorLinesWithOffset
148fn vml_to_ls_w_off<D: MValueCompatible>(
149    offsets: Option<&Vec<f64>>,
150    vl: &VectorMultiLineString<D>,
151) -> VectorLinesWithOffset {
152    vl.iter()
153        .enumerate()
154        .map(|(i, l)| {
155            vl_to_ls_w_off(offsets.and_then(|o| o.get(i).copied()).unwrap_or_default(), l)
156        })
157        .collect()
158}
159
160/// Vector LineString to VectorLineWithOffset
161fn vl_to_ls_w_off<D: MValueCompatible>(
162    offset: f64,
163    vl: &VectorLineString<D>,
164) -> VectorLineWithOffset {
165    VectorLineWithOffset::new(offset, vl.iter().map(|p| p.into()).collect())
166}
167
168/// Vector MultiPolygon to Vec<VectorLines3DWithOffset>
169fn vmp_to_ls_w_off_3d<D: MValueCompatible>(
170    offsets: Option<&Vec<Vec<f64>>>,
171    mp: &VectorMultiPolygon<D>,
172) -> Vec<VectorLines3DWithOffset> {
173    mp.iter()
174        .enumerate()
175        .map(|(i, l)| vml_to_ls_w_off_3d(offsets.and_then(|o| o.get(i)), l))
176        .collect()
177}
178
179/// Vector MultiLineString to VectorLines3DWithOffset
180fn vml_to_ls_w_off_3d<D: MValueCompatible>(
181    offsets: Option<&Vec<f64>>,
182    vl: &VectorMultiLineString<D>,
183) -> VectorLines3DWithOffset {
184    vl.iter()
185        .enumerate()
186        .map(|(i, l)| {
187            vl_to_ls_w_off_3d(offsets.and_then(|o| o.get(i).copied()).unwrap_or_default(), l)
188        })
189        .collect()
190}
191
192/// Vector LineString to VectorLine3DWithOffset
193fn vl_to_ls_w_off_3d<D: MValueCompatible>(
194    offset: f64,
195    vl: &VectorLineString<D>,
196) -> VectorLine3DWithOffset {
197    VectorLine3DWithOffset::new(offset, vl.iter().map(|p| p.into()).collect())
198}