mirror of
https://github.com/CIMEngine/cimengine-build-tools.git
synced 2024-11-21 19:56:22 +03:00
feat: diff
This commit is contained in:
parent
2f309bd389
commit
2a9268fae8
3 changed files with 53 additions and 38 deletions
19
src/build.rs
19
src/build.rs
|
@ -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,
|
||||||
|
|
29
src/types.rs
29
src/types.rs
|
@ -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,
|
||||||
|
|
43
src/utils.rs
43
src/utils.rs
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Reference in a new issue