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
15impl<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
139fn 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
147fn 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
160fn 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
168fn 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
179fn 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
192fn 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}