Mvt Expression
Mapbox-style expression tree. Each node evaluates to T? against an EvalContext (current tile zoom + feature property map); null propagates when an upstream node has no value (e.g. Get on a missing property).
Supported subset of the Mapbox GL spec:
Literals: numbers, strings, booleans, colors, arrays.
Sources:
["zoom"],["get", key],["has", key],["literal", value].Comparisons:
==,!=,<,<=,>,>=.Boolean:
all,any,!.Arithmetic:
+,-,*,/(variadic where Mapbox is variadic).Conditionals:
case,match,step.Interpolation:
interpolate ["linear"]andinterpolate ["exponential", base]forFloatandColor.Coercion:
to-number,to-string,to-boolean.
Not supported (returns null / falls through to default):
feature-state,geometry-type, color expression functions (rgb/rgba/to-color), string functions (concat/downcase/upcase/length), cubic-bezier curves.
Construction is allocation-free at evaluation; trees are built once at style time and evaluated per-feature/per-frame.
Inheritors
Types
Variadic sum. Mapbox + accepts ≥ 2 operands; empty list → 0.
["case", cond1, val1, cond2, val2, …, default] — first true condition wins. Both sides of each branch are evaluated lazily — non-matching value-side expressions never run.
["concat", arg, arg, …] — joins string-coerced operands.
Equality via Kotlin ==. Numbers compare by toDouble for cross-type matches.
Tile-zoom + feature properties + optional feature state. Construct once per feature and frame. featureState surfaces dynamic per-feature data (hover/select highlight, pulse animation phase) — read by FeatureState expressions.
["feature-state", key] — reads dynamic per-feature state set on the layer at runtime (typically for hover / select highlight). Looks up key in EvalContext.featureState (set per-feature via MvtVectorLayer.setFeatureState). Returns null when no state is set for the current feature.
["geometry-type"] — returns the feature's geometry type as one of "Point", "LineString", "Polygon", or "Unknown" (Mapbox spelling). Useful for filter expressions like ["==", ["geometry-type"], "Polygon"].
Linear or exponential interpolation between typed stops. lerp supplies the per-T blend (lerp(a, b, t) where t ∈ 0, 1); standard implementations live in Interpolators.
Built-in lerp functions for the value types interpolation actually targets in MVT styling: floats and colors. Plugged into Interpolate's lerp parameter at construction.
Length in characters of a string or number of items in an array.
["line-progress"] — arc-length parameter along the current line feature, in 0, 1. Read from EvalContext.lineProgress which the layer fills when sampling a line gradient at progress points along each line subdivision.
["match", input, label, value, label, value, …, default] — first label that equals the input wins. Labels can be a single value or a list (the latter is the variadic-label Mapbox extension).
["rgb", r, g, b] — RGB channels in 0..255; produces a Color with alpha = 1.
["rgba", r, g, b, a] — channels in 0..255 for RGB and 0..1 for alpha.
["step", input, base, stop1, val1, stop2, val2, …] — piecewise-constant. Returns base when input < stops[0]; otherwise the value of the largest stop ≤ input.
Variadic difference (left-fold): a - b - c = (a - b) - c.
["to-color", value] — pass-through if child already evaluates to a Color; otherwise yields null. Mapbox also accepts a parseColor hex/css coercion of String inputs; pass parseColor to enable that path.
Functions
True when this expression (or any sub-expression) reads per-feature data — i.e. its result can differ between two features in the same tile at the same zoom. That means a reference to a feature property (Get / Has), the feature's dynamic state (FeatureState), its geometry type (GeometryType), or its line-progress parameter (LineProgress).