params
"params": { "paper": { "type": "color", "default": "#fbf6e6" }, "softness": { "type": "number", "default": 0, "min": 0, "max": 4, "description": "Blur over the finished tile, in px." }, "labels": { "type": "bool", "default": true }}Reference a param with $name anywhere a scalar field lives:
"bg": { "op": "solid", "color": "$paper" },"out": { "op": "blur", "input": "@composite", "sigma": "$softness" }Declaration fields
Section titled “Declaration fields”| Field | Applies to | Meaning |
|---|---|---|
type |
all | color, number, or bool — required |
default |
all | used when the caller supplies nothing — required |
min / max |
number |
validated on every override; max also serves as the static bound for padding-determining fields |
description |
all | surfaced in the generated schema and the editor’s params panel |
Colours are #rrggbb or #rrggbbaa. Bools are true / false.
Overriding at render time
Section titled “Overriding at render time”# CLI — repeatable, validated against the declarationsezu tile --style watercolor.json --tile 13/7276/3225 \ --param 'paper=#ffe0f0' --param softness=2 --out tile.png
# Tile server — query-string overrides on the tile endpointcurl 'http://127.0.0.1:8080/tiles/13/7276/3225.png?paper=%23ffe0f0&softness=2'let mut params = ezu::graph::ParamValues::new();params.set("softness".into(), parse_param_value(&doc.params, "softness", "2")?);Every path validates: a number outside min/max, a malformed colour, or a
non-boolean fails before rendering. An unset param falls back to its default.
One graph, every combination
Section titled “One graph, every combination”Params resolve at render time, so nothing rebuilds when a value changes, and the cache keys on the values each node actually reads — flipping one param re-evaluates only its subtree. That is what makes the editor’s params panel responsive on a style that takes hundreds of milliseconds cold.
The generated schema
Section titled “The generated schema”Document::params_schema() derives a JSON Schema of the declarations — types,
defaults, ranges, descriptions:
curl http://127.0.0.1:8080/style/paramsThe same document is available wherever the style is loaded: the tile server
serves it at /style/params, and in the browser it is the paramsSchema getter
on the wasm Renderer.
Drive your own sliders and colour pickers off that rather than parsing the style. The live editor’s panel is generated from exactly this.
Padding-determining fields need max
Section titled “Padding-determining fields need max”Canvas padding is fixed at build time, so a field that decides it — blur sigma and
friends — must carry an upper bound the build can see. A literal is its own; a
$param qualifies only if it declares max:
"softness": { "type": "number", "default": 0, "min": 0, "max": 4 } // ✅ usable as a blur sigma"softness": { "type": "number", "default": 0 } // ❌ build errorA @node port carries no bound, so the style states one beside it with a
<field>-max — see
padding and neighbours.
The bound is what the graph budgets padding for, so keep it as tight as the style
actually needs — an unnecessarily large max costs render time on every tile.
Inside a table
Section titled “Inside a table”Some fields are not scalars but tables — a colour ramp’s stops, a palette, a
dash pattern. A $param works in each entry too:
"tint": { "op": "color-ramp", "field": "@dem", "stops": [ { "value": 0, "color": "$lowland" }, { "value": "$treeline", "color": "$upland" } ] }Two differences from a scalar field. A table entry takes a literal or a
$param but not a @node: a port needs a fixed name and its own slot on
the node, and a table of unknown length has neither. And a ramp is sorted by
value on every render rather than at build time, since a param can reorder
it — so stops need not be declared in order.
Composing computed values
Section titled “Composing computed values”Params are inputs, not expressions. To combine them, wire scalars through the
graph — a $param argument keeps its runtime-override behaviour all the way
through:
"z": { "op": "zoom" },"zfrac": { "op": "math", "fn": "div", "a": "@z", "b": 16 },"lu_alpha": { "op": "math", "fn": "mul", "a": "$landuse-alpha", "b": "@zfrac" }watercolor.json
is a complete parametric style.
Map renders on this site are made fromOpenStreetMap data viaProtomaps (© OpenStreetMap contributors), elevation from Re:Earth Terrain,Mapterhorn andEGM2008 (NGA), and aerial imagery from GSI Japan(© 国土地理院). The painterly styles use CC0 brushes byDavid Revoy.