rtz_core/geo/admin/
osm.rs1#![cfg(not(tarpaulin_include))]
6
7use geo::Geometry;
8use serde_json::{Map, Value};
9use std::borrow::Cow;
10
11#[cfg(feature = "self-contained")]
12use bincode::{
13 de::{BorrowDecoder, Decoder},
14 error::DecodeError,
15 BorrowDecode, Decode, Encode,
16};
17
18use crate::{
19 base::types::Float,
20 geo::shared::{get_geojson_feature_from_string, simplify_geometry, CanGetGeoJsonFeaturesFromSource, EncodableGeometry, EncodableString, HasGeometry, HasProperties, IdFeaturePair},
21};
22
23use super::shared::IsAdmin;
24
25#[cfg(not(feature = "extrasimplified"))]
28const SIMPLIFICATION_EPSILON: Float = 0.001;
29#[cfg(feature = "extrasimplified")]
30const SIMPLIFICATION_EPSILON: Float = 0.1;
31
32#[cfg(not(target_family = "wasm"))]
36pub fn get_geojson_features_from_source() -> geojson::FeatureCollection {
37 use rayon::prelude::{IntoParallelIterator, ParallelIterator};
38
39 let paths = ADDRESS.split(';').collect::<Vec<_>>();
40 let mut files = Vec::new();
41
42 for path in paths {
43 let mut path_files = std::fs::read_dir(path)
44 .unwrap()
45 .filter(|f| f.as_ref().unwrap().file_name().to_str().unwrap().ends_with(".geojson"))
46 .map(|f| f.unwrap())
47 .collect::<Vec<_>>();
48
49 files.append(&mut path_files);
50 }
51
52 let features = files
53 .into_par_iter()
54 .filter(|f| {
55 let md = f.metadata().unwrap();
56
57 md.len() != 0
58 })
59 .map(|f| {
60 let json = std::fs::read_to_string(f.path()).unwrap();
61 get_geojson_feature_from_string(&json)
62 })
63 .collect::<Vec<_>>();
64
65 geojson::FeatureCollection {
66 bbox: None,
67 features,
68 foreign_members: None,
69 }
70}
71
72pub static ADDRESS: &str = "D://LargeData//admin_data//admin2;D://LargeData//admin_data//admin3;D://LargeData//admin_data//admin4;D://LargeData//admin_data//admin5;D://LargeData//admin_data//admin6;D://LargeData//admin_data//admin7;D://LargeData//admin_data//admin8";
76pub static ADMIN_BINCODE_DESTINATION_NAME: &str = "osm_admins.bincode";
78pub static LOOKUP_BINCODE_DESTINATION_NAME: &str = "osm_admin_lookup.bincode";
80
81#[derive(Debug)]
87#[cfg_attr(feature = "self-contained", derive(Encode))]
88pub struct OsmAdmin {
89 pub id: usize,
93
94 pub name: EncodableString,
96 pub level: usize,
98
99 pub geometry: EncodableGeometry,
101}
102
103#[cfg(feature = "self-contained")]
104impl Decode for OsmAdmin {
105 fn decode<D>(decoder: &mut D) -> Result<Self, DecodeError>
106 where
107 D: Decoder,
108 {
109 let id = usize::decode(decoder)?;
110 let name = EncodableString::decode(decoder)?;
111 let level = usize::decode(decoder)?;
112 let geometry = EncodableGeometry::decode(decoder)?;
113
114 Ok(OsmAdmin { id, name, level, geometry })
115 }
116}
117
118#[cfg(feature = "self-contained")]
119impl<'de> BorrowDecode<'de> for OsmAdmin
120where
121 'de: 'static,
122{
123 fn borrow_decode<D>(decoder: &mut D) -> Result<Self, DecodeError>
124 where
125 D: BorrowDecoder<'de>,
126 {
127 let id = usize::decode(decoder)?;
128 let name = EncodableString::borrow_decode(decoder)?;
129 let level = usize::decode(decoder)?;
130 let geometry = EncodableGeometry::borrow_decode(decoder)?;
131
132 Ok(OsmAdmin { id, name, level, geometry })
133 }
134}
135
136impl PartialEq for OsmAdmin {
137 fn eq(&self, other: &Self) -> bool {
138 self.id == other.id
139 }
140}
141
142impl From<IdFeaturePair> for OsmAdmin {
143 fn from(value: IdFeaturePair) -> OsmAdmin {
144 let id = value.0;
145 let properties = value.1.properties.as_ref().unwrap();
146 let geometry = value.1.geometry.as_ref().unwrap();
147
148 let name = EncodableString(Cow::Owned(properties.get("name").unwrap().as_str().unwrap().to_string()));
149 let level = properties.get("admin_level").unwrap().as_u64().unwrap() as usize;
150
151 let geometry: Geometry<Float> = geometry.value.clone().try_into().unwrap();
152 let geometry = EncodableGeometry(simplify_geometry(geometry, SIMPLIFICATION_EPSILON));
153
154 OsmAdmin { id, name, level, geometry }
155 }
156}
157
158impl IsAdmin for OsmAdmin {
159 fn name(&self) -> &str {
160 self.name.as_ref()
161 }
162}
163
164impl HasGeometry for OsmAdmin {
165 fn id(&self) -> usize {
166 self.id
167 }
168
169 fn geometry(&self) -> &Geometry<Float> {
170 &self.geometry.0
171 }
172}
173
174impl HasProperties for OsmAdmin {
175 fn properties(&self) -> Map<String, Value> {
176 let mut properties = Map::new();
177
178 properties.insert("name".to_string(), Value::String(self.name.to_string()));
179 properties.insert("level".to_string(), Value::String(self.level.to_string()));
180
181 properties
182 }
183}
184
185#[cfg(not(target_family = "wasm"))]
186impl CanGetGeoJsonFeaturesFromSource for OsmAdmin {
187 fn get_geojson_features_from_source() -> geojson::FeatureCollection {
188 get_geojson_features_from_source()
189 }
190}