Skip to content

Expression Engine

The expression engine (src/expressions/) parses and evaluates Mapbox expressions for data-driven styling. It consists of three files:

  • types.rsExpression enum, ExprValue, ExpressionContext
  • parse.rsCoreParser (JSON array → Expression)
  • evaluate.rsCoreEvaluator (expression + context → value)

Supported Operations

Data Access

Expression Description
["get", key] Read feature property
["has", key] Check if property exists
["in", value, array] Check membership
["geometry-type"] Feature geometry type string

Variable Binding

["let", "name", ["get", "name:fr"],
  ["coalesce", ["var", "name"], ["get", "name"]]
]

let evaluates the binding expression, stores it in ExpressionContext.bindings, then evaluates the body. var retrieves a bound variable. This is critical for Woosmap styles where all place/city text uses let/var for i18n name resolution.

Logic

Expression Description
["all", expr, ...] Logical AND
["any", expr, ...] Logical OR
["not", expr] Logical NOT
["if", cond, then, else] Conditional (alias: case)
["coalesce", expr, ...] First non-null value
["match", input, val1, out1, ..., fallback] Value matching

Comparison

==, !=, <, <=, >, >= — work on numbers and strings.

Arithmetic

+, -, *, /, %, ^, abs, ceil, floor, round, sqrt

String

concat, downcase, upcase

Interpolation

["interpolate", ["linear"], ["zoom"],
  10, 1,
  15, 5
]

Supported interpolation types:

  • linear — linear interpolation between stops
  • exponentialbase^t curve (e.g., ["exponential", 1.5])
  • cubic-bezier — cubic Bezier curve with control points

Step

["step", ["zoom"], 0,
  10, 1,
  15, 5
]

Returns the output value of the stop just less than or equal to the input.

Evaluation Context

pub struct ExpressionContext<'a> {
    pub zoom: f32,
    pub properties: &'a HashMap<String, serde_json::Value>,
    pub geometry_type: Option<&'a str>,
    pub bindings: HashMap<String, ExprValue>,
}

The evaluator receives feature properties and the current zoom level, returning an ExprValue (number, string, boolean, color, or array).

Example: Data-Driven Line Width

{
  "line-width": [
    "interpolate", ["exponential", 1.5], ["zoom"],
    5, 0.5,
    10, 1,
    14, 4,
    18, 20
  ]
}

This expression produces a line width that grows exponentially from 0.5px at zoom 5 to 20px at zoom 18.