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 crate::{
types::CountryData,
utils::{get_country, read_config},
types::{CountryData, ToFeature, ToFeatures},
utils::{diff_countries, get_country, read_config},
};
pub fn build() {
let config = read_config();
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 mut countries: Vec<CountryData> = vec![];
let tags = processing_item.tags.unwrap_or(vec!["*".to_string()]);
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 {
let mut country = get_country(country_id.to_owned());
let country = get_country(country_id.to_owned());
let mut matches = false;
for glob in &globs {
@ -38,17 +38,16 @@ pub fn build() {
continue;
}
features.append(&mut country.geo.features);
countries.push(country);
}
// TODO: Country diff
// TODO: Add country_rewrite support
// TODO: let countries = vec![rewrite_info];
let countries = diff_countries(countries);
// TODO: Add nature support
// TODO: Create from Vec<CountryData>
let feature_collection = FeatureCollection {
bbox: None,
features,

View file

@ -112,9 +112,20 @@ pub struct CountryConfig {
pub struct CountryData {
pub id: String,
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 coordinates: Point,
pub title: String,
@ -145,6 +156,7 @@ impl ToFeature for Marker {
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum MarkerType {
Capital,
City,
@ -172,20 +184,11 @@ impl ToTerritory for MultiPolygon {
}
}
impl ToCountryFeature for MultiPolygon {
fn to_country_feature(&self, id: &String, config: &CountryConfig) -> geojson::Feature {
impl ToFeature for MultiPolygon {
fn to_feature(&self) -> geojson::Feature {
geojson::Feature {
geometry: Some(geojson::Geometry::new((self).into())),
properties: Some(
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(),
),
properties: None,
bbox: 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 geojson::{FeatureCollection, GeoJson};
use geojson::{Feature, FeatureCollection, GeoJson};
use crate::types::{
Config, CountryConfig, CountryData, Territory, ToCountryFeature, ToMultiPolygon, ToSplitGeo,
UnsplitGeo,
Config, CountryConfig, CountryData, Marker, Territory, ToCollection, ToCountryFeature,
ToFeature, ToFeatures, ToMultiPolygon, ToSplitGeo, UnsplitGeo,
};
pub fn read_config() -> Config {
@ -37,29 +37,42 @@ pub fn get_country(id: String) -> CountryData {
_ => panic!("Invalid geojson, expected FeatureCollection"),
};
let (markers, territories) = geo.split_geo();
let geo = dissolve_territories(territories);
CountryData {
id: id.clone(),
config: config.clone(),
geo: dissolve_territory(geo, id, config),
land: geo,
markers,
}
}
pub fn dissolve_territory(
geo: FeatureCollection,
id: String,
config: CountryConfig,
) -> FeatureCollection {
let (markers, territories) = geo.split_geo();
pub fn dissolve_territories(territories: Vec<Territory>) -> MultiPolygon {
let dissolved = territories
.iter()
.fold(MultiPolygon::new(vec![]), |a, b| match b {
Territory::Polygon(p) => a.union(&p.to_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 {