1#![cfg(not(tarpaulin_include))]
6
7use core::str;
8use std::{
9 borrow::Cow,
10 collections::HashMap,
11 fmt::{Display, Formatter},
12 ops::Deref,
13};
14
15use chashmap::CHashMap;
16use geo::{Coord, Geometry, Intersects, LineString, MultiPolygon, Polygon, Rect, SimplifyVw};
17use geojson::{Feature, FeatureCollection, GeoJson};
18use rayon::prelude::{IndexedParallelIterator, IntoParallelIterator, ParallelIterator};
19use serde_json::{Map, Value};
20use std::path::Path;
21
22#[cfg(feature = "self-contained")]
23use bincode::{
24 config::Configuration,
25 de::{read::BorrowReader, BorrowDecoder, Decoder},
26 enc::Encoder,
27 error::{DecodeError, EncodeError},
28 BorrowDecode, Decode, Encode,
29};
30
31use crate::base::types::Float;
32
33pub type Id = u32;
37pub type RoundDegree = i16;
39pub type RoundLngLat = (RoundDegree, RoundDegree);
41pub type IdFeaturePair = (usize, geojson::Feature);
43
44#[derive(Debug)]
48#[cfg_attr(feature = "self-contained", derive(Encode, Decode))]
49pub struct ConcreteVec<T>(Vec<T>)
50where
51 T: 'static;
52
53impl<T> Deref for ConcreteVec<T> {
54 type Target = Vec<T>;
55
56 fn deref(&self) -> &Self::Target {
57 &self.0
58 }
59}
60
61impl<T> From<geojson::FeatureCollection> for ConcreteVec<T>
62where
63 T: From<IdFeaturePair> + Send,
64{
65 fn from(value: geojson::FeatureCollection) -> ConcreteVec<T> {
66 let values = value.features.into_par_iter().enumerate().map(T::from).collect::<Vec<T>>();
67
68 ConcreteVec(values)
69 }
70}
71
72impl<T> IntoIterator for ConcreteVec<T> {
73 type IntoIter = std::vec::IntoIter<T>;
74 type Item = T;
75
76 fn into_iter(self) -> Self::IntoIter {
77 self.0.into_iter()
78 }
79}
80
81impl<'a, T> IntoIterator for &'a ConcreteVec<T> {
82 type IntoIter = std::slice::Iter<'a, T>;
83 type Item = &'a T;
84
85 fn into_iter(self) -> Self::IntoIter {
86 self.0.iter()
87 }
88}
89
90#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
94pub struct EncodableString(pub Cow<'static, str>);
95
96impl AsRef<str> for EncodableString {
97 fn as_ref(&self) -> &str {
98 self.0.as_ref()
99 }
100}
101
102impl Deref for EncodableString {
103 type Target = Cow<'static, str>;
104
105 fn deref(&self) -> &Self::Target {
106 &self.0
107 }
108}
109
110impl Display for EncodableString {
111 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
112 write!(f, "{}", self.0)
113 }
114}
115
116#[cfg(feature = "self-contained")]
117impl Encode for EncodableString {
118 fn encode<E>(&self, encoder: &mut E) -> Result<(), EncodeError>
119 where
120 E: Encoder,
121 {
122 let data = pad_string_alignment(self);
123
124 data.encode(encoder)
125 }
126}
127
128#[cfg(feature = "self-contained")]
129impl Decode for EncodableString {
130 fn decode<D>(decoder: &mut D) -> Result<Self, DecodeError>
131 where
132 D: Decoder,
133 {
134 let data = Vec::decode(decoder)?;
135
136 unpad_string_alignment(&data).map(ToString::to_string).map(Cow::Owned).map(EncodableString)
138 }
139}
140
141#[cfg(feature = "self-contained")]
142impl<'de> BorrowDecode<'de> for EncodableString {
143 fn borrow_decode<D>(decoder: &mut D) -> Result<Self, DecodeError>
144 where
145 D: BorrowDecoder<'de>,
146 {
147 let length = usize::decode(decoder)?;
148 let slice = decoder.borrow_reader().take_bytes(length * std::mem::size_of::<u8>())?;
149
150 let slice = unsafe { std::mem::transmute::<&'_ [u8], &'static [u8]>(slice) };
152
153 unpad_string_alignment(slice).map(Cow::Borrowed).map(EncodableString)
155 }
156}
157
158#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)]
160pub struct EncodableOptionString(pub Option<Cow<'static, str>>);
161
162impl EncodableOptionString {
163 pub fn as_ref(&self) -> Option<&Cow<'static, str>> {
165 self.0.as_ref()
166 }
167}
168
169impl Deref for EncodableOptionString {
170 type Target = Option<Cow<'static, str>>;
171
172 fn deref(&self) -> &Self::Target {
173 &self.0
174 }
175}
176
177impl Display for EncodableOptionString {
178 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
179 match self.as_ref() {
180 None => write!(f, "None"),
181 Some(cow) => write!(f, "{}", cow),
182 }
183 }
184}
185
186#[cfg(feature = "self-contained")]
187impl Encode for EncodableOptionString {
188 fn encode<E>(&self, encoder: &mut E) -> Result<(), EncodeError>
189 where
190 E: Encoder,
191 {
192 match self.as_ref() {
193 None => 0usize.encode(encoder),
194 Some(cow) => {
195 1usize.encode(encoder)?;
197
198 let data = pad_string_alignment(cow);
200
201 data.encode(encoder)
202 }
203 }
204 }
205}
206
207#[cfg(feature = "self-contained")]
208impl Decode for EncodableOptionString {
209 fn decode<D>(decoder: &mut D) -> Result<Self, DecodeError>
210 where
211 D: Decoder,
212 {
213 let variant = usize::decode(decoder)?;
214
215 let result = match variant {
216 0 => EncodableOptionString(None),
217 1 => {
218 let es = EncodableString::decode(decoder)?;
219
220 EncodableOptionString(Some(es.0))
221 }
222 _ => panic!("Unsupported variant."),
223 };
224
225 Ok(result)
226 }
227}
228
229#[cfg(feature = "self-contained")]
230impl<'de> BorrowDecode<'de> for EncodableOptionString {
231 fn borrow_decode<D>(decoder: &mut D) -> Result<Self, DecodeError>
232 where
233 D: BorrowDecoder<'de>,
234 {
235 let variant = usize::decode(decoder)?;
236
237 let result = match variant {
238 0 => EncodableOptionString(None),
239 1 => {
240 let es = EncodableString::borrow_decode(decoder)?;
241
242 EncodableOptionString(Some(es.0))
243 }
244 _ => panic!("Unsupported variant."),
245 };
246
247 Ok(result)
248 }
249}
250
251pub trait HasGeometry {
257 fn id(&self) -> usize;
259 fn geometry(&self) -> &Geometry<Float>;
261}
262
263pub trait HasProperties {
265 fn properties(&self) -> Map<String, Value>;
267}
268
269pub trait ToGeoJsonFeature {
271 fn to_feature(&self) -> geojson::Feature;
273}
274
275impl<T> ToGeoJsonFeature for T
276where
277 T: HasGeometry + HasProperties,
278{
279 fn to_feature(&self) -> geojson::Feature {
280 let geometry = self.geometry();
281 let properties = self.properties();
282
283 geojson::Feature {
284 properties: Some(properties),
285 geometry: Some(geojson::Geometry::from(geometry)),
286 ..geojson::Feature::default()
287 }
288 }
289}
290
291pub trait ToGeoJsonFeatureCollection {
293 fn to_feature_collection(&self) -> geojson::FeatureCollection;
295}
296
297impl<'a, L, D, T> ToGeoJsonFeatureCollection for &'a L
299where
300 L: Deref<Target = D>,
301 D: Deref<Target = [T]>,
302 T: ToGeoJsonFeature + 'static,
303{
304 fn to_feature_collection(&self) -> geojson::FeatureCollection {
305 let features = self.iter().map(|x| x.to_feature()).collect();
306
307 geojson::FeatureCollection {
308 features,
309 bbox: None,
310 foreign_members: None,
311 }
312 }
313}
314
315pub trait ToGeoJson {
317 fn to_geojson(&self) -> GeoJson;
319}
320
321impl<T> ToGeoJson for T
322where
323 T: ToGeoJsonFeatureCollection,
324{
325 fn to_geojson(&self) -> GeoJson {
326 GeoJson::FeatureCollection(self.to_feature_collection())
327 }
328}
329
330#[cfg(feature = "self-contained")]
334pub fn pad_string_alignment(string: impl AsRef<str>) -> Vec<u8> {
335 let alignment = std::mem::align_of::<Float>();
336 let padding = alignment - (string.as_ref().as_bytes().len() % alignment);
337
338 string.as_ref().as_bytes().iter().chain(std::iter::repeat(&0u8).take(padding)).copied().collect::<Vec<u8>>()
339}
340
341#[cfg(feature = "self-contained")]
343pub fn unpad_string_alignment(data: &[u8]) -> Result<&str, DecodeError> {
344 let terminator = data.iter().position(|&x| x == 0).unwrap_or(data.len());
345 let slice = &data[..terminator];
346
347 let str = str::from_utf8(slice).map_err(|e| DecodeError::Utf8 { inner: e })?;
348
349 Ok(str)
350}
351
352pub fn simplify_geometry(geometry: Geometry<Float>, simplification_epsilon: Float) -> Geometry<Float> {
356 #[cfg(not(feature = "unsimplified"))]
357 let geometry = match geometry {
358 Geometry::Polygon(polygon) => {
359 let simplified = polygon.simplify_vw(&simplification_epsilon);
360 Geometry::Polygon(simplified)
361 }
362 Geometry::MultiPolygon(multi_polygon) => {
363 let simplified = multi_polygon.simplify_vw(&simplification_epsilon);
364 Geometry::MultiPolygon(simplified)
365 }
366 Geometry::LineString(line_string) => {
367 let simplified = line_string.simplify_vw(&simplification_epsilon);
368 Geometry::LineString(simplified)
369 }
370 Geometry::MultiLineString(multi_line_string) => {
371 let simplified = multi_line_string.simplify_vw(&simplification_epsilon);
372 Geometry::MultiLineString(simplified)
373 }
374 g => g,
375 };
376
377 geometry
378}
379
380pub fn get_lookup_from_geometries<T>(geometries: &ConcreteVec<T>) -> HashMap<RoundLngLat, EncodableIds>
382where
383 T: HasGeometry + Send + Sync,
384{
385 let map = CHashMap::new();
386
387 (-180..180).into_par_iter().for_each(|x| {
388 for y in -90..90 {
389 let xf = x as Float;
390 let yf = y as Float;
391
392 let rect = Rect::new(Coord { x: xf, y: yf }, Coord { x: xf + 1.0, y: yf + 1.0 });
393
394 let mut intersected = Vec::new();
395
396 for g in geometries {
397 if g.geometry().intersects(&rect) {
398 intersected.push(g.id() as Id);
399 }
400 }
401
402 map.insert((x as RoundDegree, y as RoundDegree), intersected);
403 }
404 });
405
406 let mut cache = HashMap::new();
407 for (key, value) in map.into_iter() {
408 cache.insert(key, EncodableIds(value));
409 }
410
411 cache
412}
413
414#[cfg(feature = "self-contained")]
419fn generate_lookup_bincode<T>(bincode_input: impl AsRef<Path>, bincode_destination: impl AsRef<Path>)
420where
421 T: HasGeometry + Decode + Send + Sync + 'static,
422{
423 let data = std::fs::read(bincode_input).unwrap();
424 let (timezones, _len): (ConcreteVec<T>, usize) = bincode::decode_from_slice(&data, get_global_bincode_config()).unwrap();
425
426 let cache = get_lookup_from_geometries(&timezones);
427
428 bincode::encode_into_std_write(cache, &mut std::fs::File::create(bincode_destination).unwrap(), get_global_bincode_config()).unwrap();
429}
430
431pub fn get_items_from_features<T>(features: FeatureCollection) -> ConcreteVec<T>
433where
434 T: HasGeometry + From<IdFeaturePair> + Send,
435{
436 ConcreteVec::from(features)
437}
438
439#[cfg(feature = "self-contained")]
441fn generate_item_bincode<T>(geojson_features: FeatureCollection, bincode_destination: impl AsRef<Path>)
442where
443 T: HasGeometry + Encode + From<IdFeaturePair> + Send + 'static,
444{
445 let items: ConcreteVec<T> = get_items_from_features(geojson_features);
446 bincode::encode_into_std_write(items, &mut std::fs::File::create(bincode_destination).unwrap(), get_global_bincode_config()).unwrap();
447}
448
449pub fn get_geojson_features_from_file(geojson_input: impl AsRef<Path>) -> FeatureCollection {
451 let geojson = std::fs::read_to_string(geojson_input).unwrap();
452 FeatureCollection::try_from(geojson.parse::<GeoJson>().unwrap()).unwrap()
453}
454
455pub fn get_geojson_features_from_string(geojson_input: &str) -> FeatureCollection {
457 FeatureCollection::try_from(geojson_input.parse::<GeoJson>().unwrap()).unwrap()
458}
459
460pub fn get_geojson_feature_from_file(geojson_input: impl AsRef<Path>) -> Feature {
462 let geojson = std::fs::read_to_string(geojson_input).unwrap();
463 Feature::try_from(geojson.parse::<GeoJson>().unwrap()).unwrap()
464}
465
466pub fn get_geojson_feature_from_string(geojson_input: &str) -> Feature {
468 Feature::try_from(geojson_input.parse::<GeoJson>().unwrap()).unwrap()
469}
470
471#[cfg(feature = "self-contained")]
473pub fn generate_bincodes<T>(geojson_features: FeatureCollection, timezone_bincode_destination: impl AsRef<Path>, lookup_bincode_destination: impl AsRef<Path>)
474where
475 T: HasGeometry + Encode + From<IdFeaturePair> + Decode + Send + Sync + 'static,
476{
477 generate_item_bincode::<T>(geojson_features, timezone_bincode_destination.as_ref());
478 generate_lookup_bincode::<T>(timezone_bincode_destination, lookup_bincode_destination);
479}
480
481pub trait CanGetGeoJsonFeaturesFromSource {
485 fn get_geojson_features_from_source() -> geojson::FeatureCollection;
487}
488
489#[cfg(all(feature = "self-contained", target_endian = "big"))]
493
494pub fn get_global_bincode_config() -> Configuration<bincode::config::BigEndian, bincode::config::Fixint> {
495 bincode::config::legacy().with_big_endian()
496}
497
498#[cfg(all(feature = "self-contained", target_endian = "little"))]
500pub fn get_global_bincode_config() -> Configuration<bincode::config::LittleEndian, bincode::config::Fixint> {
501 bincode::config::legacy()
502}
503
504#[derive(Debug)]
508pub struct EncodableGeometry(pub Geometry<Float>);
509
510#[cfg(feature = "self-contained")]
511fn encode_poly<E>(polygon: &Polygon<Float>, encoder: &mut E) -> Result<(), EncodeError>
512where
513 E: Encoder,
514{
515 let exterior = &polygon.exterior().0;
516
517 exterior.len().encode(encoder)?;
519
520 for point in exterior {
522 point.x.encode(encoder)?;
523 point.y.encode(encoder)?;
524 }
525
526 let interiors = polygon.interiors();
527
528 interiors.len().encode(encoder)?;
530
531 for interior in interiors {
533 let interior = &interior.0;
534
535 interior.len().encode(encoder)?;
537
538 for point in interior {
540 point.x.encode(encoder)?;
541 point.y.encode(encoder)?;
542 }
543 }
544
545 Ok(())
546}
547
548#[cfg(feature = "self-contained")]
549impl Encode for EncodableGeometry {
550 fn encode<E>(&self, encoder: &mut E) -> Result<(), EncodeError>
551 where
552 E: Encoder,
553 {
554 match &self.0 {
555 Geometry::Polygon(polygon) => {
556 0usize.encode(encoder)?;
558
559 encode_poly(polygon, encoder)?;
560 }
561 Geometry::MultiPolygon(multi_polygon) => {
562 1usize.encode(encoder)?;
564
565 let polygons = &multi_polygon.0;
566
567 polygons.len().encode(encoder)?;
569
570 for polygon in polygons {
572 encode_poly(polygon, encoder)?;
573 }
574 }
575 _ => panic!("Unsupported geometry variant."),
576 }
577
578 Ok(())
579 }
580}
581
582#[cfg(feature = "self-contained")]
583fn decode_poly<D>(decoder: &mut D) -> Result<Polygon<Float>, DecodeError>
584where
585 D: Decoder,
586{
587 let exterior_len = usize::decode(decoder)?;
588
589 let mut exterior = Vec::with_capacity(exterior_len);
590
591 for _ in 0..exterior_len {
592 let x = Float::decode(decoder)?;
593 let y = Float::decode(decoder)?;
594
595 exterior.push(Coord { x, y });
596 }
597
598 let interior_len = usize::decode(decoder)?;
599
600 let mut interiors = Vec::with_capacity(interior_len);
601
602 for _ in 0..interior_len {
603 let interior_len = usize::decode(decoder)?;
604
605 let mut interior = Vec::with_capacity(interior_len);
606
607 for _ in 0..interior_len {
608 let x = Float::decode(decoder)?;
609 let y = Float::decode(decoder)?;
610
611 interior.push(Coord { x, y });
612 }
613
614 interiors.push(LineString(interior));
615 }
616
617 Ok(Polygon::new(LineString(exterior), interiors))
618}
619
620#[cfg(feature = "self-contained")]
621fn borrow_decode_poly<'de, D>(decoder: &mut D) -> Result<Polygon<Float>, DecodeError>
622where
623 D: BorrowDecoder<'de>,
624{
625 let exterior_len = usize::decode(decoder)?;
626 let exterior_slice = decoder.borrow_reader().take_bytes(exterior_len * std::mem::size_of::<Float>() * 2)?;
627
628 let exterior = unsafe { Vec::from_raw_parts(exterior_slice.as_ptr() as *mut Coord<Float>, exterior_len, exterior_len) };
632
633 let interior_len = usize::decode(decoder)?;
634
635 let mut interiors = Vec::with_capacity(interior_len);
636
637 for _ in 0..interior_len {
638 let interior_len = usize::decode(decoder)?;
639 let interior_slice = decoder.borrow_reader().take_bytes(interior_len * std::mem::size_of::<Float>() * 2)?;
640
641 let interior = unsafe { Vec::from_raw_parts(interior_slice.as_ptr() as *mut Coord<Float>, interior_len, interior_len) };
643
644 interiors.push(LineString(interior));
645 }
646
647 Ok(Polygon::new(LineString(exterior), interiors))
648}
649
650#[cfg(feature = "self-contained")]
651impl Decode for EncodableGeometry {
652 fn decode<D>(decoder: &mut D) -> Result<Self, DecodeError>
653 where
654 D: Decoder,
655 {
656 let variant = usize::decode(decoder)?;
657
658 let geometry = match variant {
659 0 => {
660 let polygon = decode_poly(decoder)?;
661
662 Geometry::Polygon(polygon)
663 }
664 1 => {
665 let polygon_len = usize::decode(decoder)?;
666
667 let mut polygons = Vec::with_capacity(polygon_len);
668
669 for _ in 0..polygon_len {
670 let polygon = decode_poly(decoder)?;
671
672 polygons.push(polygon);
673 }
674
675 Geometry::MultiPolygon(MultiPolygon::new(polygons))
676 }
677 _ => panic!("Unsupported geometry variant."),
678 };
679
680 Ok(EncodableGeometry(geometry))
681 }
682}
683
684#[cfg(feature = "self-contained")]
685impl<'de> BorrowDecode<'de> for EncodableGeometry {
686 fn borrow_decode<D>(decoder: &mut D) -> Result<Self, DecodeError>
687 where
688 D: BorrowDecoder<'de>,
689 {
690 let variant = usize::decode(decoder)?;
691
692 let geometry = match variant {
693 0 => {
694 let polygon = borrow_decode_poly(decoder)?;
695
696 Geometry::Polygon(polygon)
697 }
698 1 => {
699 let polygon_len = usize::decode(decoder)?;
700
701 let mut polygons = Vec::with_capacity(polygon_len);
702
703 for _ in 0..polygon_len {
704 let polygon = borrow_decode_poly(decoder)?;
705
706 polygons.push(polygon);
707 }
708
709 Geometry::MultiPolygon(MultiPolygon::new(polygons))
710 }
711 _ => panic!("Unsupported geometry variant."),
712 };
713
714 Ok(EncodableGeometry(geometry))
715 }
716}
717
718#[derive(Debug)]
720pub struct EncodableIds(pub Vec<Id>);
721
722impl Deref for EncodableIds {
723 type Target = Vec<Id>;
724
725 fn deref(&self) -> &Self::Target {
726 &self.0
727 }
728}
729
730impl AsRef<[Id]> for EncodableIds {
731 fn as_ref(&self) -> &[Id] {
732 &self.0
733 }
734}
735
736#[cfg(feature = "self-contained")]
737impl Encode for EncodableIds {
738 fn encode<E>(&self, encoder: &mut E) -> Result<(), EncodeError>
739 where
740 E: Encoder,
741 {
742 self.0.len().encode(encoder)?;
744
745 for x in &self.0 {
747 x.encode(encoder)?;
748 }
749
750 Ok(())
751 }
752}
753
754#[cfg(feature = "self-contained")]
755impl Decode for EncodableIds {
756 fn decode<D>(decoder: &mut D) -> Result<Self, DecodeError>
757 where
758 D: Decoder,
759 {
760 let len = usize::decode(decoder)?;
761
762 let mut vec = Vec::with_capacity(len);
763
764 for _ in 0..len {
765 let x = Id::decode(decoder)?;
766
767 vec.push(x);
768 }
769
770 Ok(EncodableIds(vec))
771 }
772}
773
774#[cfg(feature = "self-contained")]
775impl<'de> BorrowDecode<'de> for EncodableIds {
776 fn borrow_decode<D>(decoder: &mut D) -> Result<Self, DecodeError>
777 where
778 D: BorrowDecoder<'de>,
779 {
780 let len = usize::decode(decoder)?;
781 let slice = decoder.borrow_reader().take_bytes(len * std::mem::size_of::<Id>())?;
782
783 let vec = unsafe { Vec::from_raw_parts(slice.as_ptr() as *mut Id, len, len) };
785
786 Ok(EncodableIds(vec))
787 }
788}