2021-08-27 19:26:09 +02:00
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
pub enum Selector {
|
|
|
|
MinZoom(i32),
|
|
|
|
MaxZoom(i32),
|
|
|
|
HasTag(&'static str),
|
|
|
|
TagEquals(&'static str, &'static str),
|
|
|
|
And(&'static [Selector]),
|
|
|
|
Or(&'static [Selector]),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Selector {
|
|
|
|
fn matches(&self, zoom: &i32, tags: &HashMap<String, String>) -> bool {
|
|
|
|
match self {
|
|
|
|
Selector::MinZoom(min_zoom) =>
|
|
|
|
zoom >= min_zoom,
|
|
|
|
Selector::MaxZoom(max_zoom) =>
|
|
|
|
zoom <= max_zoom,
|
|
|
|
Selector::HasTag(name) =>
|
|
|
|
tags.contains_key(*name),
|
|
|
|
Selector::TagEquals(name, value) =>
|
|
|
|
tags.get(*name).map(|s| s.as_str()) == Some(*value),
|
|
|
|
Selector::And(selectors) =>
|
|
|
|
selectors.iter().all(|selector| selector.matches(zoom, tags)),
|
|
|
|
Selector::Or(selectors) =>
|
|
|
|
selectors.iter().any(|selector| selector.matches(zoom, tags)),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type Color = (f64, f64, f64, f64);
|
|
|
|
|
|
|
|
pub struct Style {
|
|
|
|
pub z_index: i32,
|
|
|
|
pub stroke: Option<(f64, Color)>,
|
|
|
|
pub fill: Option<Color>,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Style {
|
|
|
|
const DEFAULT: Style = Style {
|
|
|
|
z_index: 0,
|
|
|
|
stroke: None,
|
|
|
|
fill: None,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
const STYLES: &[(Selector, Style)] = &[
|
|
|
|
(Selector::HasTag("tunnel"),
|
|
|
|
Style { z_index: -10, ..Style::DEFAULT }),
|
|
|
|
|
2021-08-28 19:23:23 +02:00
|
|
|
(Selector::TagEquals("landuse", "forest"),
|
|
|
|
Style { z_index: -8, fill: Some((0.2, 0.7, 0.2, 0.8)), ..Style::DEFAULT }),
|
|
|
|
(Selector::TagEquals("leisure", "park"),
|
|
|
|
Style { z_index: -8, fill: Some((0.3, 0.7, 0.3, 0.8)), ..Style::DEFAULT }),
|
|
|
|
(Selector::TagEquals("landuse", "meadow"),
|
|
|
|
Style { z_index: -6, fill: Some((0.2, 0.8, 0.2, 0.8)), ..Style::DEFAULT }),
|
|
|
|
(Selector::TagEquals("landuse", "grass"),
|
|
|
|
Style { z_index: -5, fill: Some((0.3, 0.9, 0.3, 0.8)), ..Style::DEFAULT }),
|
|
|
|
|
|
|
|
(Selector::TagEquals("landuse", "industrial"),
|
|
|
|
Style { z_index: -9, fill: Some((0.3, 0.3, 0.2, 0.8)), ..Style::DEFAULT }),
|
|
|
|
(Selector::TagEquals("landuse", "construction"),
|
|
|
|
Style { z_index: -9, fill: Some((0.5, 0.5, 0.3, 0.8)), ..Style::DEFAULT }),
|
|
|
|
|
2021-08-27 19:26:09 +02:00
|
|
|
(Selector::TagEquals("highway", "motorway"),
|
2021-08-28 19:23:23 +02:00
|
|
|
Style { z_index: 10, stroke: Some((50., (1., 1., 1., 1.))), ..Style::DEFAULT }),
|
2021-08-27 19:26:09 +02:00
|
|
|
(Selector::TagEquals("highway", "trunk"),
|
2021-08-28 19:23:23 +02:00
|
|
|
Style { z_index: 9, stroke: Some((35., (1., 1., 1., 1.))), ..Style::DEFAULT }),
|
2021-08-27 19:26:09 +02:00
|
|
|
(Selector::TagEquals("highway", "primary"),
|
2021-08-28 19:23:23 +02:00
|
|
|
Style { z_index: 8, stroke: Some((25., (1., 1., 1., 1.))), ..Style::DEFAULT }),
|
2021-08-27 19:26:09 +02:00
|
|
|
(Selector::And(&[Selector::TagEquals("highway", "secondary"), Selector::MinZoom(12)]),
|
2021-08-28 19:23:23 +02:00
|
|
|
Style { z_index: 7, stroke: Some((20., (1., 1., 1., 1.))), ..Style::DEFAULT }),
|
2021-08-27 19:26:09 +02:00
|
|
|
(Selector::And(&[Selector::TagEquals("highway", "tertiary"), Selector::MinZoom(14)]),
|
2021-08-28 19:23:23 +02:00
|
|
|
Style { z_index: 6, stroke: Some((15., (1., 1., 1., 1.))), ..Style::DEFAULT }),
|
2021-08-27 19:26:09 +02:00
|
|
|
(Selector::And(&[Selector::TagEquals("highway", "residential"), Selector::MinZoom(16)]),
|
2021-08-28 19:23:23 +02:00
|
|
|
Style { z_index: 5, stroke: Some((10., (1., 1., 1., 1.))), ..Style::DEFAULT }),
|
2021-08-27 19:26:09 +02:00
|
|
|
(Selector::And(&[Selector::TagEquals("highway", "living_street"), Selector::MinZoom(16)]),
|
2021-08-28 19:23:23 +02:00
|
|
|
Style { z_index: 4, stroke: Some((8., (1., 1., 1., 1.))), ..Style::DEFAULT }),
|
2021-08-27 19:26:09 +02:00
|
|
|
(Selector::And(&[Selector::HasTag("highway"), Selector::MinZoom(18)]),
|
2021-08-28 19:23:23 +02:00
|
|
|
Style { z_index: 3, stroke: Some((6., (1., 1., 1., 1.))), ..Style::DEFAULT }),
|
2021-08-27 19:26:09 +02:00
|
|
|
|
|
|
|
(Selector::And(&[Selector::HasTag("railway"), Selector::MinZoom(10)]),
|
|
|
|
Style { z_index: 20, stroke: Some((3., (0., 0., 0., 1.))), ..Style::DEFAULT }),
|
|
|
|
|
|
|
|
(Selector::Or(&[Selector::HasTag("waterway"), Selector::TagEquals("natural", "water")]),
|
|
|
|
Style { z_index: -2, fill: Some((0.5, 0.5, 0.7, 1.)), ..Style::DEFAULT }),
|
|
|
|
|
2021-08-28 19:23:23 +02:00
|
|
|
(Selector::And(&[Selector::HasTag("building"), Selector::MinZoom(16)]),
|
2021-08-27 19:26:09 +02:00
|
|
|
Style { z_index: 30, fill: Some((0.7, 0.7, 0.7, 1.)), stroke: Some((1., (0., 0., 0., 1.))), ..Style::DEFAULT }),
|
|
|
|
];
|
|
|
|
|
|
|
|
pub fn find(zoom: &i32, tags: &HashMap<String, String>) -> Option<&'static Style> {
|
|
|
|
for (selector, style) in STYLES {
|
|
|
|
if selector.matches(zoom, tags) {
|
|
|
|
return Some(&style);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
None
|
|
|
|
}
|