#![cfg(not(tarpaulin_include))]
use std::borrow::Cow;
use geo::Geometry;
use serde_json::{Map, Value};
#[cfg(feature = "self-contained")]
use bincode::{error::DecodeError, de::{Decoder, BorrowDecoder}, BorrowDecode, Encode, Decode};
use crate::{
base::types::Float,
geo::shared::{get_geojson_feature_from_string, simplify_geometry, HasGeometry, HasProperties, EncodableGeometry, CanGetGeoJsonFeaturesFromSource},
};
use super::shared::IsAdmin;
#[cfg(not(feature = "extrasimplified"))]
const SIMPLIFICATION_EPSILON: Float = 0.001;
#[cfg(feature = "extrasimplified")]
const SIMPLIFICATION_EPSILON: Float = 0.1;
#[cfg(not(target_family = "wasm"))]
pub fn get_geojson_features_from_source() -> geojson::FeatureCollection {
use rayon::prelude::{IntoParallelIterator, ParallelIterator};
let paths = ADDRESS.split(';').collect::<Vec<_>>();
let mut files = Vec::new();
for path in paths {
let mut path_files = std::fs::read_dir(path)
.unwrap()
.filter(|f| f.as_ref().unwrap().file_name().to_str().unwrap().ends_with(".geojson"))
.map(|f| f.unwrap())
.collect::<Vec<_>>();
files.append(&mut path_files);
}
let features = files.into_par_iter().filter(|f| {
let md = f.metadata().unwrap();
md.len() != 0
}).map(|f| {
let json = std::fs::read_to_string(f.path()).unwrap();
get_geojson_feature_from_string(&json)
}).collect::<Vec<_>>();
geojson::FeatureCollection {
bbox: None,
features,
foreign_members: None,
}
}
pub 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";
pub static ADMIN_BINCODE_DESTINATION_NAME: &str = "osm_admins.bincode";
pub static LOOKUP_BINCODE_DESTINATION_NAME: &str = "osm_admin_lookup.bincode";
#[derive(Debug)]
#[cfg_attr(feature = "self-contained", derive(Encode))]
pub struct OsmAdmin {
pub id: usize,
pub name: Cow<'static, str>,
pub level: u8,
pub geometry: EncodableGeometry,
}
#[cfg(feature = "self-contained")]
impl Decode for OsmAdmin
{
fn decode<D>(decoder: &mut D) -> Result<Self, DecodeError>
where
D: Decoder,
{
let id = usize::decode(decoder)?;
let name = Cow::<'static, str>::decode(decoder)?;
let level = u8::decode(decoder)?;
let geometry = EncodableGeometry::decode(decoder)?;
Ok(OsmAdmin { id, name, level, geometry })
}
}
#[cfg(feature = "self-contained")]
impl<'de> BorrowDecode<'de> for OsmAdmin
where
'de: 'static
{
fn borrow_decode<D>(decoder: &mut D) -> Result<Self, DecodeError>
where
D: BorrowDecoder<'de>,
{
let id = usize::decode(decoder)?;
let name = Cow::<'static, str>::borrow_decode(decoder)?;
let level = u8::decode(decoder)?;
let geometry = EncodableGeometry::borrow_decode(decoder)?;
Ok(OsmAdmin { id, name, level, geometry })
}
}
impl PartialEq for OsmAdmin {
fn eq(&self, other: &Self) -> bool {
self.id == other.id
}
}
impl From<(usize, geojson::Feature)> for OsmAdmin {
fn from(value: (usize, geojson::Feature)) -> OsmAdmin {
let id = value.0;
let properties = value.1.properties.as_ref().unwrap();
let geometry = value.1.geometry.as_ref().unwrap();
let name = Cow::Owned(properties.get("name").unwrap().as_str().unwrap().to_string());
let level = properties.get("admin_level").unwrap().as_u64().unwrap() as u8;
let geometry: Geometry<Float> = geometry.value.clone().try_into().unwrap();
let geometry = EncodableGeometry(simplify_geometry(geometry, SIMPLIFICATION_EPSILON));
OsmAdmin { id, name, level, geometry }
}
}
impl IsAdmin for OsmAdmin {
fn name(&self) -> &str {
self.name.as_ref()
}
}
impl HasGeometry for OsmAdmin {
fn id(&self) -> usize {
self.id
}
fn geometry(&self) -> &Geometry<Float> {
&self.geometry.0
}
}
impl HasProperties for OsmAdmin {
fn properties(&self) -> Map<String, Value> {
let mut properties = Map::new();
properties.insert("name".to_string(), Value::String(self.name.to_string()));
properties.insert("level".to_string(), Value::String(self.level.to_string()));
properties
}
}
#[cfg(not(target_family = "wasm"))]
impl CanGetGeoJsonFeaturesFromSource for OsmAdmin {
fn get_geojson_features_from_source() -> geojson::FeatureCollection {
get_geojson_features_from_source()
}
}