1use serde::{Deserialize, Serialize};
2
3#[derive(Serialize, Debug, Clone, Copy, PartialEq, Eq)]
5pub enum ShapeFormat {
6 #[serde(rename = "polyline6")]
7 Polyline6,
9
10 #[serde(rename = "polyline5")]
11 Polyline5,
13
14 #[serde(rename = "geojson")]
15 GeoJSON,
17
18 #[serde(rename = "no_shape")]
19 NoShape,
21}
22
23#[derive(Serialize, Deserialize, Debug, Clone, PartialEq)]
24pub struct ShapePoint {
26 pub lon: f64,
28
29 pub lat: f64,
31}
32
33impl From<&ShapePoint> for geo_types::Point {
34 fn from(p: &ShapePoint) -> Self {
35 debug_assert!((-90.0..90.0).contains(&p.lat));
36 debug_assert!((-180.0..180.0).contains(&p.lon));
37 Self::new(p.lon, p.lat)
38 }
39}
40
41impl From<ShapePoint> for super::Coordinate {
42 fn from(p: ShapePoint) -> Self {
43 debug_assert!((-90.0..90.0).contains(&p.lat));
44 debug_assert!((-180.0..180.0).contains(&p.lon));
45 (p.lon as f32, p.lat as f32)
46 }
47}
48
49fn decode_shape_polyline6(encoded: &str) -> Vec<ShapePoint> {
53 debug_assert!(encoded.is_ascii());
54 debug_assert!(!encoded.is_empty());
55 let inv = 1.0 / 1e6;
57 let estimated_points = encoded.len() / 8;
59 let mut decoded = Vec::with_capacity(estimated_points);
60 let mut previous = [0, 0];
61 let mut i = 0;
62
63 while i < encoded.len() {
64 let mut ll = [0, 0];
66 for j in [0, 1] {
67 let mut shift = 0;
68 let mut byte = 0x20;
69 while byte >= 0x20 {
71 byte = i32::from(encoded.as_bytes()[i]) - 63;
72 i += 1;
73 ll[j] |= (byte & 0x1f) << shift;
74 shift += 5;
75 }
76 ll[j] = previous[j]
78 + if (ll[j] & 1) != 0 {
79 !(ll[j] >> 1)
80 } else {
81 ll[j] >> 1
82 };
83 previous[j] = ll[j];
84 }
85 let lon = f64::from(ll[1]) * inv;
87 let lat = f64::from(ll[0]) * inv;
88 debug_assert!((-90.0..90.0).contains(&lat));
89 debug_assert!((-180.0..180.0).contains(&lon));
90 decoded.push(ShapePoint { lon, lat });
91 }
92
93 decoded
94}
95pub(crate) fn deserialize_shape<'de, D>(deserializer: D) -> Result<Vec<ShapePoint>, D::Error>
96where
97 D: serde::Deserializer<'de>,
98{
99 let s = String::deserialize(deserializer)?;
100 Ok(decode_shape_polyline6(&s))
101}
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn shapepoint_to_geo_types_point() {
108 let sp = ShapePoint {
109 lon: 11.670365,
110 lat: 48.268722,
111 };
112 let pt: geo_types::Point = (&sp).into();
113 assert_eq!(pt.x(), 11.670365);
114 assert_eq!(pt.y(), 48.268722);
115 }
116
117 #[test]
118 fn shapepoint_to_coordinate() {
119 let sp = ShapePoint {
120 lon: 11.670365,
121 lat: 48.268722,
122 };
123 let coord: super::super::Coordinate = sp.into();
124 assert_eq!(coord.0, 11.670365_f32);
125 assert_eq!(coord.1, 48.268722_f32);
126 }
127
128 #[test]
129 fn decode_shape_works_america() {
130 let shape = decode_shape_polyline6("}c|gkAlvkmqCkg@zf@_IbJaP`XoXq^aCwDyByGkAyGI}H?iFZeH`AuFfB}HxBaG~xAiaBtFgHtPqWfCeDpMsNva@px@rRp_@|s@vvAd{@tbBpiAfzBjNuw@lGo`@bAwHz@}I|@cQ^gNf@_OB_NJ}[BeJH{c@X{[SaK_@{S]}Q_@cJUgLAgJ?iUBoB^eMFoA`BsXbLgxAzK_{CpD}oA`@wUlBegAvAmh@fGcr@lGur@zGu]jGeSv@_BdNiYdCaDhHaJx^_[f^}Qre@cXjOgJtJ}HjIqKjEkHzD{HpDaIrB_GvA}EpAoFfAaGlA}H|@yHbAwK~Le{A|@yHv@{Ft@cEfBiHdCsHjCkF|ByDxQaYlE}GrCmEjR{Yp^al@nMgM|C_Fb]_j@xLwR~Ro[`DiElDsD~GmGlNmMpEwDkAwGcDwR_EkUmDuV{CmTiPwaAsc@{kCwL_t@{d@wmCqZkiB{NkcAcGwa@aAgHyJ_t@uI_q@_Kyp@aEgYqBqL}M_v@_Q{n@sVw}@gV{r@kLs\\sCeIqXmw@eFk]W{]dCic@Dw@vIsb@p@gD~Oiw@hAkGtBaLd@gFjAwc@GiGOeKs@ce@i@_HeEci@_@eFyDsh@gEsr@a@eZqAuaAo@cnAb@}JhAwpAnCq|CpCocBHcDZiNrAcp@`Biz@x@}m@bAgl@x@cWrHycAbGyi@tNe~@rAsIjDqTlDwS|G_g@vGyd@fGes@~DynAZ}nAXc~BoGeB}HsIaL}CqMeDmDbBwBe@iF}@wMkCkSuFsA_@");
132 let expected = [
134 [-76.781943, 39.991887],
135 [-76.782581, 39.992533],
136 [-76.782759, 39.992692999999996],
137 [-76.78316, 39.992965999999996],
138 [-76.78265499999999, 39.993373999999996],
139 [-76.782563, 39.993438999999995],
140 [-76.782422, 39.9935],
141 [-76.782281, 39.993538],
142 [-76.782122, 39.993542999999995],
143 [-76.782005, 39.993542999999995],
144 [-76.781858, 39.993528999999995],
145 [-76.781735, 39.993496],
146 [-76.781576, 39.993444],
147 [-76.781447, 39.993383],
148 [-76.77987399999999, 39.991943],
149 [-76.779726, 39.99182],
150 [-76.779333, 39.991537],
151 [-76.77924999999999, 39.991468999999995],
152 [-76.779, 39.991236],
153 [-76.779921, 39.99068],
154 [-76.780442, 39.990366],
155 [-76.781846, 39.989519],
156 [-76.783441, 39.988555999999996],
157 [-76.78541299999999, 39.987362999999995],
158 [-76.784506, 39.987117],
159 [-76.78397, 39.986982],
160 [-76.78381399999999, 39.986948],
161 [-76.783639, 39.986917999999996],
162 [-76.783349, 39.986886999999996],
163 [-76.78310499999999, 39.986871],
164 [-76.782849, 39.986851],
165 [-76.782609, 39.986849],
166 [-76.782146, 39.986843],
167 [-76.781967, 39.986841],
168 [-76.78137699999999, 39.986836],
169 [-76.780915, 39.986823],
170 [-76.780722, 39.986833],
171 [-76.780388, 39.986849],
172 [-76.780085, 39.986864],
173 [-76.779907, 39.98688],
174 [-76.77969499999999, 39.986891],
175 [-76.779515, 39.986892],
176 [-76.779158, 39.986892],
177 [-76.779102, 39.986889999999995],
178 [-76.778875, 39.986874],
179 [-76.778835, 39.986869999999996],
180 [-76.778425, 39.986821],
181 [-76.776997, 39.986610999999996],
182 [-76.774501, 39.986405],
183 [-76.773206, 39.986315999999995],
184 [-76.772842, 39.986298999999995],
185 [-76.771687, 39.986244],
186 [-76.771024, 39.9862],
187 [-76.770206, 39.986067999999996],
188 [-76.769379, 39.985932999999996],
189 [-76.76888799999999, 39.985791],
190 [-76.768565, 39.985656999999996],
191 [-76.768517, 39.985628999999996],
192 [-76.768096, 39.985386],
193 [-76.76801499999999, 39.985319],
194 [-76.767838, 39.98517],
195 [-76.76738999999999, 39.984660999999996],
196 [-76.767087, 39.984161],
197 [-76.766685, 39.983543],
198 [-76.766505, 39.983281],
199 [-76.766346, 39.983094],
200 [-76.766145, 39.982928],
201 [-76.76599499999999, 39.982825999999996],
202 [-76.76583699999999, 39.982732],
203 [-76.765676, 39.982642999999996],
204 [-76.765548, 39.982585],
205 [-76.76543699999999, 39.982541],
206 [-76.765317, 39.9825],
207 [-76.765188, 39.982464],
208 [-76.765029, 39.982425],
209 [-76.764872, 39.982394],
210 [-76.764668, 39.98236],
211 [-76.763193, 39.982136],
212 [-76.763036, 39.982105],
213 [-76.76290999999999, 39.982077],
214 [-76.762812, 39.98205],
215 [-76.762663, 39.981998],
216 [-76.762509, 39.981930999999996],
217 [-76.762391, 39.981860999999995],
218 [-76.762298, 39.981798],
219 [-76.761881, 39.981497],
220 [-76.761738, 39.981394],
221 [-76.761635, 39.98132],
222 [-76.76120499999999, 39.98101],
223 [-76.76048399999999, 39.980505],
224 [-76.760256, 39.980273],
225 [-76.760144, 39.980194],
226 [-76.759456, 39.979712],
227 [-76.75914, 39.979490999999996],
228 [-76.758684, 39.979171],
229 [-76.758583, 39.97909],
230 [-76.758493, 39.979003],
231 [-76.758358, 39.978859],
232 [-76.758127, 39.978612],
233 [-76.75803499999999, 39.978507],
234 [-76.75789499999999, 39.978545],
235 [-76.75757899999999, 39.978626999999996],
236 [-76.757221, 39.978722999999995],
237 [-76.75684199999999, 39.978809999999996],
238 [-76.75649899999999, 39.978888],
239 [-76.755431, 39.979164999999995],
240 [-76.753177, 39.979751],
241 [-76.752329, 39.979971],
242 [-76.750045, 39.980577],
243 [-76.74834299999999, 39.981018],
244 [-76.747249, 39.981272],
245 [-76.746693, 39.981401999999996],
246 [-76.746545, 39.981435],
247 [-76.74569699999999, 39.981624],
248 [-76.744897, 39.981795],
249 [-76.7441, 39.981987],
250 [-76.74368, 39.982084],
251 [-76.74346299999999, 39.982141],
252 [-76.742583, 39.98238],
253 [-76.741817, 39.982668],
254 [-76.740813, 39.983046],
255 [-76.739983, 39.983418],
256 [-76.739509, 39.983632],
257 [-76.739346, 39.983706],
258 [-76.73844299999999, 39.984114999999996],
259 [-76.737957, 39.98423],
260 [-76.73746299999999, 39.984241999999995],
261 [-76.736882, 39.984175],
262 [-76.736854, 39.984172],
263 [-76.736284, 39.983999999999995],
264 [-76.7362, 39.983975],
265 [-76.735299, 39.983703],
266 [-76.735165, 39.983666],
267 [-76.734956, 39.983607],
268 [-76.73483999999999, 39.983588],
269 [-76.734252, 39.98355],
270 [-76.73411899999999, 39.983554],
271 [-76.733924, 39.983562],
272 [-76.733314, 39.983588],
273 [-76.73317, 39.983609],
274 [-76.732496, 39.983708],
275 [-76.73238099999999, 39.983723999999995],
276 [-76.731715, 39.983816999999995],
277 [-76.73088899999999, 39.983917],
278 [-76.730454, 39.983934],
279 [-76.729387, 39.983975],
280 [-76.728121, 39.983999],
281 [-76.72793, 39.983981],
282 [-76.72662199999999, 39.983944],
283 [-76.72410099999999, 39.983872],
284 [-76.722493, 39.983799],
285 [-76.722411, 39.983793999999996],
286 [-76.722166, 39.983779999999996],
287 [-76.72138, 39.983737999999995],
288 [-76.72043099999999, 39.983689],
289 [-76.71968, 39.98366],
290 [-76.71895599999999, 39.983626],
291 [-76.71857, 39.983596999999996],
292 [-76.717469, 39.983443],
293 [-76.71678399999999, 39.983312999999995],
294 [-76.715773, 39.983062],
295 [-76.715603, 39.983019999999996],
296 [-76.71525799999999, 39.982934],
297 [-76.71492599999999, 39.982847],
298 [-76.714286, 39.982704],
299 [-76.713681, 39.982563999999996],
300 [-76.712846, 39.982431999999996],
301 [-76.711569, 39.982336],
302 [-76.71029, 39.982321999999996],
303 [-76.70825599999999, 39.982309],
304 [-76.70820499999999, 39.982445],
305 [-76.708035, 39.982603999999995],
306 [-76.707956, 39.982813],
307 [-76.70787299999999, 39.983046],
308 [-76.707923, 39.983132999999995],
309 [-76.707904, 39.983193],
310 [-76.70787299999999, 39.983309999999996],
311 [-76.707803, 39.983546],
312 [-76.70768, 39.983872],
313 [-76.707664, 39.983914],
314 ];
315 let expected = expected
316 .into_iter()
317 .map(|[lon, lat]| ShapePoint { lat, lon })
318 .collect::<Vec<_>>();
319 assert_eq!(shape, expected);
320 }
321 #[test]
322 fn decode_shape_works_germany() {
323 let shape = decode_shape_polyline6("czaa{AythgU}K_CgFeAiB]mDq@uRoD_Ca@|@aOb@uHd@eIb@gHh@wI`@cHNmChBa[|Cih@fA_RzB^fm@fK~AVbLlBpHnAvMfCvDt@hMzBrOjCtGfArEz@dJvAdC^bC@jH~B^bBXjARvZnFzV|EpNjCrRnDpS~D`Dd@bK`BjEp@lCd@jLxBlI~A~F|QT`Ag@~Ga@pEYrCa@fExA`@~IfCzIjCj{@|Up}@hWlTpHpAbB^`C}Czh@}FgBmCy@sOqEwEjb@o@rFoAdLeAa@yIaDcFiBYdC");
324 let expected = [
326 [11.670365, 48.268722],
327 [11.670428999999999, 48.268929],
328 [11.670463999999999, 48.269045],
329 [11.670479, 48.269098],
330 [11.670504, 48.269185],
331 [11.670592, 48.2695],
332 [11.670608999999999, 48.269563999999995],
333 [11.670866, 48.269532999999996],
334 [11.671021, 48.269515],
335 [11.671184, 48.269496],
336 [11.671332, 48.269478],
337 [11.671503999999999, 48.269456999999996],
338 [11.67165, 48.269439999999996],
339 [11.671721, 48.269431999999995],
340 [11.67217, 48.269379],
341 [11.672830999999999, 48.2693],
342 [11.673135, 48.269264],
343 [11.673119, 48.269202],
344 [11.672922999999999, 48.268462],
345 [11.672911, 48.268414],
346 [11.672856, 48.268204],
347 [11.672816, 48.268051],
348 [11.672748, 48.267815],
349 [11.672721, 48.267723],
350 [11.672659, 48.267494],
351 [11.672589, 48.267227999999996],
352 [11.672552999999999, 48.267089],
353 [11.672523, 48.266982999999996],
354 [11.672479, 48.266804],
355 [11.672462999999999, 48.266737],
356 [11.672467, 48.266670999999995],
357 [11.672317, 48.26667],
358 [11.672301, 48.266605999999996],
359 [11.672288, 48.266556],
360 [11.672277999999999, 48.266518],
361 [11.672158, 48.266073999999996],
362 [11.672047, 48.265691999999994],
363 [11.671977, 48.265443],
364 [11.671889, 48.265128999999995],
365 [11.671793, 48.2648],
366 [11.671774, 48.264719],
367 [11.671725, 48.264525],
368 [11.6717, 48.264423],
369 [11.671681, 48.264351999999995],
370 [11.671619999999999, 48.264137999999996],
371 [11.671572, 48.263971],
372 [11.671268999999999, 48.263842999999994],
373 [11.671235999999999, 48.263832],
374 [11.671092, 48.263852],
375 [11.670987, 48.263869],
376 [11.670912999999999, 48.263881999999995],
377 [11.670812999999999, 48.263898999999995],
378 [11.670796, 48.263853999999995],
379 [11.670727999999999, 48.263678],
380 [11.670658, 48.263504],
381 [11.670290999999999, 48.262538],
382 [11.669901999999999, 48.261537],
383 [11.669749, 48.261193999999996],
384 [11.669699, 48.261153],
385 [11.669634, 48.261137],
386 [11.668963999999999, 48.261216],
387 [11.669016, 48.261343],
388 [11.669044999999999, 48.261413999999995],
389 [11.66915, 48.26168],
390 [11.668584, 48.261787999999996],
391 [11.668462, 48.261812],
392 [11.668251, 48.261852],
393 [11.668268, 48.261886999999994],
394 [11.668349, 48.26206],
395 [11.668401999999999, 48.262173999999995],
396 [11.668334999999999, 48.262187],
397 ];
398 let expected = expected
399 .into_iter()
400 .map(|[lon, lat]| ShapePoint { lat, lon })
401 .collect::<Vec<_>>();
402 assert_eq!(shape, expected);
403 }
404}