Mapbox Style JSON
Nimbus parses and evaluates Mapbox Style Spec JSON for data-driven rendering. The style system lives across three modules:
src/style.rs— JSON deserialization (sources, layers, metadata)src/style_eval/— filter compilation, paint/layout resolutionsrc/styler/— Google Maps styler JSON transforms
Supported Layer Types
| Type | Paint properties | Layout properties |
|---|---|---|
| background | background-color |
— |
| fill | fill-color, fill-opacity |
visibility |
| line | line-color, line-width, line-opacity |
visibility, line-cap |
| symbol | icon-color, icon-opacity, text-color, text-opacity, text-halo-color, text-halo-width |
icon-image, text-field, text-font, text-size, text-anchor, text-offset, text-variable-anchor, text-radial-offset, symbol-placement, visibility |
Style Resolution Pipeline
graph LR
A[style.json] -->|deserialize| B[Style struct]
B -->|resolve_style| C[Vec of ResolvedLayer]
C -->|compile filters| D[CompiledFilter per layer]
C -->|resolve paint| E[StyleValue per property]
ResolvedLayer
resolve_style() compiles the raw JSON into a Vec<ResolvedLayer>, each containing:
- A
CompiledFilterfor feature matching StyleValue<T>for each paint/layout property (constant, zoom function, or expression)- Optional
feature_typeandelement_typesfor Google Maps styler matching visibleflag (layers withvisibility: "none"are kept but marked invisible)
Filters
Two filter syntaxes are supported:
Filters are compiled into CompiledFilter at style load time and evaluated per-feature during extraction.
Paint Values
Paint properties resolve to StyleValue<T>, which can be:
- Constant — a single value (e.g.,
"#ff0000") - Zoom function — legacy
stopsarray or moderninterpolate/stepexpression - Data expression — depends on feature properties (e.g.,
["get", "height"])
Color Parsing
src/color.rs provides parse_color() supporting:
- Hex:
#rgb,#rrggbb,#rrggbbaa - Functions:
rgb(),rgba(),hsla() - Named colors:
red,blue,transparent, etc.
Colors are stored as [f32; 4] (linear RGBA). sRGB correction (pow(c, 2.2)) is applied in the shader via a branchless approximation.
Google Maps Styler
src/styler/ applies Google Maps-style JSON rules to modify layer colors after the Mapbox style is loaded.
map_renderer.apply_styler(r#"[
{"featureType": "water", "elementType": "geometry.fill",
"stylers": [{"color": "#529acc"}]}
]"#)?;
How It Works
- Builds a
Tree<T>from dot-separatedfeatureTypepaths (e.g.,poi.medical) - Matches rules to resolved layers by feature type and element type
- Applies HSL delta transforms:
color,hue,saturation,lightness,invert_lightness,gamma,visibility - Only transforms
StyleValue::Constant(zoom functions are left as-is)
POI Expansion
Enabled POI classes are expanded into individual ResolvedLayer entries (one per class) rather than using case expressions. This gives each POI class its own filter, icon, and color:
Prefix matching: rule "poi.medical" enables both "medical.pharmacy" and "medical.hospital".