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 mut decoded = Vec::new();
58 let mut previous = [0, 0];
59 let mut i = 0;
60
61 while i < encoded.len() {
62 let mut ll = [0, 0];
64 for j in [0, 1] {
65 let mut shift = 0;
66 let mut byte = 0x20;
67 while byte >= 0x20 {
69 byte = i32::from(encoded.as_bytes()[i]) - 63;
70 i += 1;
71 ll[j] |= (byte & 0x1f) << shift;
72 shift += 5;
73 }
74 ll[j] = previous[j]
76 + if (ll[j] & 1) != 0 {
77 !(ll[j] >> 1)
78 } else {
79 ll[j] >> 1
80 };
81 previous[j] = ll[j];
82 }
83 let lon = f64::from(ll[1]) * inv;
85 let lat = f64::from(ll[0]) * inv;
86 debug_assert!((-90.0..90.0).contains(&lat));
87 debug_assert!((-180.0..180.0).contains(&lon));
88 decoded.push(ShapePoint { lon, lat });
89 }
90
91 decoded
92}
93pub(crate) fn deserialize_shape<'de, D>(deserializer: D) -> Result<Vec<ShapePoint>, D::Error>
94where
95 D: serde::Deserializer<'de>,
96{
97 let s = String::deserialize(deserializer)?;
98 Ok(decode_shape_polyline6(s.as_str()))
99}
100#[cfg(test)]
101mod tests {
102 use super::*;
103 #[test]
104 fn decode_shape_works_america() {
105 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_@");
107 let expected = [
109 [-76.781943, 39.991887],
110 [-76.782581, 39.992533],
111 [-76.782759, 39.992692999999996],
112 [-76.78316, 39.992965999999996],
113 [-76.78265499999999, 39.993373999999996],
114 [-76.782563, 39.993438999999995],
115 [-76.782422, 39.9935],
116 [-76.782281, 39.993538],
117 [-76.782122, 39.993542999999995],
118 [-76.782005, 39.993542999999995],
119 [-76.781858, 39.993528999999995],
120 [-76.781735, 39.993496],
121 [-76.781576, 39.993444],
122 [-76.781447, 39.993383],
123 [-76.77987399999999, 39.991943],
124 [-76.779726, 39.99182],
125 [-76.779333, 39.991537],
126 [-76.77924999999999, 39.991468999999995],
127 [-76.779, 39.991236],
128 [-76.779921, 39.99068],
129 [-76.780442, 39.990366],
130 [-76.781846, 39.989519],
131 [-76.783441, 39.988555999999996],
132 [-76.78541299999999, 39.987362999999995],
133 [-76.784506, 39.987117],
134 [-76.78397, 39.986982],
135 [-76.78381399999999, 39.986948],
136 [-76.783639, 39.986917999999996],
137 [-76.783349, 39.986886999999996],
138 [-76.78310499999999, 39.986871],
139 [-76.782849, 39.986851],
140 [-76.782609, 39.986849],
141 [-76.782146, 39.986843],
142 [-76.781967, 39.986841],
143 [-76.78137699999999, 39.986836],
144 [-76.780915, 39.986823],
145 [-76.780722, 39.986833],
146 [-76.780388, 39.986849],
147 [-76.780085, 39.986864],
148 [-76.779907, 39.98688],
149 [-76.77969499999999, 39.986891],
150 [-76.779515, 39.986892],
151 [-76.779158, 39.986892],
152 [-76.779102, 39.986889999999995],
153 [-76.778875, 39.986874],
154 [-76.778835, 39.986869999999996],
155 [-76.778425, 39.986821],
156 [-76.776997, 39.986610999999996],
157 [-76.774501, 39.986405],
158 [-76.773206, 39.986315999999995],
159 [-76.772842, 39.986298999999995],
160 [-76.771687, 39.986244],
161 [-76.771024, 39.9862],
162 [-76.770206, 39.986067999999996],
163 [-76.769379, 39.985932999999996],
164 [-76.76888799999999, 39.985791],
165 [-76.768565, 39.985656999999996],
166 [-76.768517, 39.985628999999996],
167 [-76.768096, 39.985386],
168 [-76.76801499999999, 39.985319],
169 [-76.767838, 39.98517],
170 [-76.76738999999999, 39.984660999999996],
171 [-76.767087, 39.984161],
172 [-76.766685, 39.983543],
173 [-76.766505, 39.983281],
174 [-76.766346, 39.983094],
175 [-76.766145, 39.982928],
176 [-76.76599499999999, 39.982825999999996],
177 [-76.76583699999999, 39.982732],
178 [-76.765676, 39.982642999999996],
179 [-76.765548, 39.982585],
180 [-76.76543699999999, 39.982541],
181 [-76.765317, 39.9825],
182 [-76.765188, 39.982464],
183 [-76.765029, 39.982425],
184 [-76.764872, 39.982394],
185 [-76.764668, 39.98236],
186 [-76.763193, 39.982136],
187 [-76.763036, 39.982105],
188 [-76.76290999999999, 39.982077],
189 [-76.762812, 39.98205],
190 [-76.762663, 39.981998],
191 [-76.762509, 39.981930999999996],
192 [-76.762391, 39.981860999999995],
193 [-76.762298, 39.981798],
194 [-76.761881, 39.981497],
195 [-76.761738, 39.981394],
196 [-76.761635, 39.98132],
197 [-76.76120499999999, 39.98101],
198 [-76.76048399999999, 39.980505],
199 [-76.760256, 39.980273],
200 [-76.760144, 39.980194],
201 [-76.759456, 39.979712],
202 [-76.75914, 39.979490999999996],
203 [-76.758684, 39.979171],
204 [-76.758583, 39.97909],
205 [-76.758493, 39.979003],
206 [-76.758358, 39.978859],
207 [-76.758127, 39.978612],
208 [-76.75803499999999, 39.978507],
209 [-76.75789499999999, 39.978545],
210 [-76.75757899999999, 39.978626999999996],
211 [-76.757221, 39.978722999999995],
212 [-76.75684199999999, 39.978809999999996],
213 [-76.75649899999999, 39.978888],
214 [-76.755431, 39.979164999999995],
215 [-76.753177, 39.979751],
216 [-76.752329, 39.979971],
217 [-76.750045, 39.980577],
218 [-76.74834299999999, 39.981018],
219 [-76.747249, 39.981272],
220 [-76.746693, 39.981401999999996],
221 [-76.746545, 39.981435],
222 [-76.74569699999999, 39.981624],
223 [-76.744897, 39.981795],
224 [-76.7441, 39.981987],
225 [-76.74368, 39.982084],
226 [-76.74346299999999, 39.982141],
227 [-76.742583, 39.98238],
228 [-76.741817, 39.982668],
229 [-76.740813, 39.983046],
230 [-76.739983, 39.983418],
231 [-76.739509, 39.983632],
232 [-76.739346, 39.983706],
233 [-76.73844299999999, 39.984114999999996],
234 [-76.737957, 39.98423],
235 [-76.73746299999999, 39.984241999999995],
236 [-76.736882, 39.984175],
237 [-76.736854, 39.984172],
238 [-76.736284, 39.983999999999995],
239 [-76.7362, 39.983975],
240 [-76.735299, 39.983703],
241 [-76.735165, 39.983666],
242 [-76.734956, 39.983607],
243 [-76.73483999999999, 39.983588],
244 [-76.734252, 39.98355],
245 [-76.73411899999999, 39.983554],
246 [-76.733924, 39.983562],
247 [-76.733314, 39.983588],
248 [-76.73317, 39.983609],
249 [-76.732496, 39.983708],
250 [-76.73238099999999, 39.983723999999995],
251 [-76.731715, 39.983816999999995],
252 [-76.73088899999999, 39.983917],
253 [-76.730454, 39.983934],
254 [-76.729387, 39.983975],
255 [-76.728121, 39.983999],
256 [-76.72793, 39.983981],
257 [-76.72662199999999, 39.983944],
258 [-76.72410099999999, 39.983872],
259 [-76.722493, 39.983799],
260 [-76.722411, 39.983793999999996],
261 [-76.722166, 39.983779999999996],
262 [-76.72138, 39.983737999999995],
263 [-76.72043099999999, 39.983689],
264 [-76.71968, 39.98366],
265 [-76.71895599999999, 39.983626],
266 [-76.71857, 39.983596999999996],
267 [-76.717469, 39.983443],
268 [-76.71678399999999, 39.983312999999995],
269 [-76.715773, 39.983062],
270 [-76.715603, 39.983019999999996],
271 [-76.71525799999999, 39.982934],
272 [-76.71492599999999, 39.982847],
273 [-76.714286, 39.982704],
274 [-76.713681, 39.982563999999996],
275 [-76.712846, 39.982431999999996],
276 [-76.711569, 39.982336],
277 [-76.71029, 39.982321999999996],
278 [-76.70825599999999, 39.982309],
279 [-76.70820499999999, 39.982445],
280 [-76.708035, 39.982603999999995],
281 [-76.707956, 39.982813],
282 [-76.70787299999999, 39.983046],
283 [-76.707923, 39.983132999999995],
284 [-76.707904, 39.983193],
285 [-76.70787299999999, 39.983309999999996],
286 [-76.707803, 39.983546],
287 [-76.70768, 39.983872],
288 [-76.707664, 39.983914],
289 ];
290 let expected = expected
291 .into_iter()
292 .map(|[lon, lat]| ShapePoint { lat, lon })
293 .collect::<Vec<_>>();
294 assert_eq!(shape, expected);
295 }
296 #[test]
297 fn decode_shape_works_germany() {
298 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");
299 let expected = [
301 [11.670365, 48.268722],
302 [11.670428999999999, 48.268929],
303 [11.670463999999999, 48.269045],
304 [11.670479, 48.269098],
305 [11.670504, 48.269185],
306 [11.670592, 48.2695],
307 [11.670608999999999, 48.269563999999995],
308 [11.670866, 48.269532999999996],
309 [11.671021, 48.269515],
310 [11.671184, 48.269496],
311 [11.671332, 48.269478],
312 [11.671503999999999, 48.269456999999996],
313 [11.67165, 48.269439999999996],
314 [11.671721, 48.269431999999995],
315 [11.67217, 48.269379],
316 [11.672830999999999, 48.2693],
317 [11.673135, 48.269264],
318 [11.673119, 48.269202],
319 [11.672922999999999, 48.268462],
320 [11.672911, 48.268414],
321 [11.672856, 48.268204],
322 [11.672816, 48.268051],
323 [11.672748, 48.267815],
324 [11.672721, 48.267723],
325 [11.672659, 48.267494],
326 [11.672589, 48.267227999999996],
327 [11.672552999999999, 48.267089],
328 [11.672523, 48.266982999999996],
329 [11.672479, 48.266804],
330 [11.672462999999999, 48.266737],
331 [11.672467, 48.266670999999995],
332 [11.672317, 48.26667],
333 [11.672301, 48.266605999999996],
334 [11.672288, 48.266556],
335 [11.672277999999999, 48.266518],
336 [11.672158, 48.266073999999996],
337 [11.672047, 48.265691999999994],
338 [11.671977, 48.265443],
339 [11.671889, 48.265128999999995],
340 [11.671793, 48.2648],
341 [11.671774, 48.264719],
342 [11.671725, 48.264525],
343 [11.6717, 48.264423],
344 [11.671681, 48.264351999999995],
345 [11.671619999999999, 48.264137999999996],
346 [11.671572, 48.263971],
347 [11.671268999999999, 48.263842999999994],
348 [11.671235999999999, 48.263832],
349 [11.671092, 48.263852],
350 [11.670987, 48.263869],
351 [11.670912999999999, 48.263881999999995],
352 [11.670812999999999, 48.263898999999995],
353 [11.670796, 48.263853999999995],
354 [11.670727999999999, 48.263678],
355 [11.670658, 48.263504],
356 [11.670290999999999, 48.262538],
357 [11.669901999999999, 48.261537],
358 [11.669749, 48.261193999999996],
359 [11.669699, 48.261153],
360 [11.669634, 48.261137],
361 [11.668963999999999, 48.261216],
362 [11.669016, 48.261343],
363 [11.669044999999999, 48.261413999999995],
364 [11.66915, 48.26168],
365 [11.668584, 48.261787999999996],
366 [11.668462, 48.261812],
367 [11.668251, 48.261852],
368 [11.668268, 48.261886999999994],
369 [11.668349, 48.26206],
370 [11.668401999999999, 48.262173999999995],
371 [11.668334999999999, 48.262187],
372 ];
373 let expected = expected
374 .into_iter()
375 .map(|[lon, lat]| ShapePoint { lat, lon })
376 .collect::<Vec<_>>();
377 assert_eq!(shape, expected);
378 }
379}