feat: diff

This commit is contained in:
Artemy 2024-05-29 20:56:51 +03:00
parent 2f309bd389
commit 2a9268fae8
3 changed files with 53 additions and 38 deletions

View file

@ -5,25 +5,25 @@ use serde_json::json;
use wax::{Glob, Pattern}; use wax::{Glob, Pattern};
use crate::{ use crate::{
types::CountryData, types::{CountryData, ToFeature, ToFeatures},
utils::{get_country, read_config}, utils::{diff_countries, get_country, read_config},
}; };
pub fn build() { pub fn build() {
let config = read_config(); let config = read_config();
for processing_item in config.processing { for processing_item in config.processing {
let mut features: Vec<Feature> = vec![]; let features: Vec<Feature> = vec![];
let out_folder = Path::new(&processing_item.output_folder); let out_folder = Path::new(&processing_item.output_folder);
let mut countries: Vec<CountryData> = vec![];
let tags = processing_item.tags.unwrap_or(vec!["*".to_string()]); let tags = processing_item.tags.unwrap_or(vec!["*".to_string()]);
let globs: Vec<Glob> = tags.iter().map(|tag| Glob::new(tag).unwrap()).collect(); let globs: Vec<Glob> = tags.iter().map(|tag| Glob::new(tag).unwrap()).collect();
let mut countries: Vec<CountryData> = vec![];
for country_id in &config.main.layers { for country_id in &config.main.layers {
let mut country = get_country(country_id.to_owned()); let country = get_country(country_id.to_owned());
let mut matches = false; let mut matches = false;
for glob in &globs { for glob in &globs {
@ -38,17 +38,16 @@ pub fn build() {
continue; continue;
} }
features.append(&mut country.geo.features);
countries.push(country); countries.push(country);
} }
// TODO: Country diff
// TODO: Add country_rewrite support // TODO: Add country_rewrite support
// TODO: let countries = vec![rewrite_info];
let countries = diff_countries(countries);
// TODO: Add nature support // TODO: Add nature support
// TODO: Create from Vec<CountryData>
let feature_collection = FeatureCollection { let feature_collection = FeatureCollection {
bbox: None, bbox: None,
features, features,

View file

@ -112,9 +112,20 @@ pub struct CountryConfig {
pub struct CountryData { pub struct CountryData {
pub id: String, pub id: String,
pub config: CountryConfig, pub config: CountryConfig,
pub geo: FeatureCollection, pub land: MultiPolygon,
pub markers: Vec<Marker>,
} }
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct CountryPolyProps {
id: String,
r#type: String,
fill: String,
stroke: String,
tags: Vec<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Marker { pub struct Marker {
pub coordinates: Point, pub coordinates: Point,
pub title: String, pub title: String,
@ -145,6 +156,7 @@ impl ToFeature for Marker {
} }
} }
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum MarkerType { pub enum MarkerType {
Capital, Capital,
City, City,
@ -172,20 +184,11 @@ impl ToTerritory for MultiPolygon {
} }
} }
impl ToCountryFeature for MultiPolygon { impl ToFeature for MultiPolygon {
fn to_country_feature(&self, id: &String, config: &CountryConfig) -> geojson::Feature { fn to_feature(&self) -> geojson::Feature {
geojson::Feature { geojson::Feature {
geometry: Some(geojson::Geometry::new((self).into())), geometry: Some(geojson::Geometry::new((self).into())),
properties: Some( properties: None,
serde_json::Map::from_iter([
("id".to_owned(), json!(id)),
("type".to_owned(), json!("country")),
("fill".to_owned(), json!(config.fill)),
("stroke".to_owned(), json!(config.stroke)),
("tags".to_owned(), json!(config.tags)),
])
.into(),
),
bbox: None, bbox: None,
id: None, id: None,

View file

@ -1,11 +1,11 @@
use std::{fs, path::Path}; use std::{fs, marker, path::Path};
use geo::{BooleanOps, MultiPolygon}; use geo::{BooleanOps, MultiPolygon};
use geojson::{FeatureCollection, GeoJson}; use geojson::{Feature, FeatureCollection, GeoJson};
use crate::types::{ use crate::types::{
Config, CountryConfig, CountryData, Territory, ToCountryFeature, ToMultiPolygon, ToSplitGeo, Config, CountryConfig, CountryData, Marker, Territory, ToCollection, ToCountryFeature,
UnsplitGeo, ToFeature, ToFeatures, ToMultiPolygon, ToSplitGeo, UnsplitGeo,
}; };
pub fn read_config() -> Config { pub fn read_config() -> Config {
@ -37,29 +37,42 @@ pub fn get_country(id: String) -> CountryData {
_ => panic!("Invalid geojson, expected FeatureCollection"), _ => panic!("Invalid geojson, expected FeatureCollection"),
}; };
let (markers, territories) = geo.split_geo();
let geo = dissolve_territories(territories);
CountryData { CountryData {
id: id.clone(), id: id.clone(),
config: config.clone(), config: config.clone(),
geo: dissolve_territory(geo, id, config), land: geo,
markers,
} }
} }
pub fn dissolve_territory( pub fn dissolve_territories(territories: Vec<Territory>) -> MultiPolygon {
geo: FeatureCollection,
id: String,
config: CountryConfig,
) -> FeatureCollection {
let (markers, territories) = geo.split_geo();
let dissolved = territories let dissolved = territories
.iter() .iter()
.fold(MultiPolygon::new(vec![]), |a, b| match b { .fold(MultiPolygon::new(vec![]), |a, b| match b {
Territory::Polygon(p) => a.union(&p.to_mp()), Territory::Polygon(p) => a.union(&p.to_mp()),
Territory::MultiPolygon(mp) => a.union(mp), Territory::MultiPolygon(mp) => a.union(mp),
}) });
.to_country_feature(&id, &config);
(markers, dissolved).unsplit_geo() dissolved
}
pub fn diff_countries(countries: Vec<CountryData>) -> Vec<CountryData> {
let mut countries = countries;
for i in 0..countries.len() {
for j in 0..countries.len() {
if i == j {
continue;
}
countries[i].land = countries[i].land.difference(&countries[j].land);
}
}
countries
} }
pub fn hash_hex_color(s: String) -> String { pub fn hash_hex_color(s: String) -> String {