Skip to Content
ReferenceExpressions

MapsGL Android - Expressions

Expressions style vector layers from feature properties and the active timeline. Build them with the Expression factories, then wrap the result in StyleValue.Expression for a paint property or assign it to a layer filter.

See data-driven styling for end-to-end weather-layer examples.

Basic Syntax

Each factory returns an Expression whose raw value is a nested list: the operator first, then arguments.

["<operator>", <arg1>, <arg2>, ...]
Expression.get("temperature") StyleValue.Expression(Expression.get("COLOR"))

Lookup

get

Reads a feature property. Dotted paths such as "alert.info.color" are expanded automatically via getPath.

Expression.get("temperature") Expression.get("alert.info.color")

literal

Wraps a value so it is not parsed as an expression. Used as a filter operand (for example with contains).

Expression.literal(listOf("Polygon", "MultiPolygon"))

has

Returns true when the feature has the given property. Works in layer filters (including dotted paths) and in switchCase conditions.

Expression.has("COLOR") Expression.has("alert.info.color")

Control Flow

switchCase

Evaluates conditions in order and returns the first matching result (["case", …]). Use this on paint properties (color, size, image id). It is not evaluated as a layer filter.

Expression.switchCase( listOf( Expression.Case(Expression.lessThan(Expression.get("value"), 10), "low"), Expression.Case(Expression.lessThan(Expression.get("value"), 20), "medium"), ), "high", )

match

Compares an input against literal labels and returns the matching output. Works for paint and for boolean layer filters (including contains below).

Expression.match( Expression.downcase(Expression.get("report.type")), listOf( Expression.Step("minor", "#dfcb01"), Expression.Step("moderate", "#ff5d01"), Expression.Step("major", "#ce0052"), ), "#999999", )

coalesce

Returns the first non-null argument. Use it as a paint/value operand, not as a standalone filter.

Expression.coalesce(listOf(Expression.get("primary"), Expression.get("backup")))

let / var

Bind a value once and reuse it in the result (Expression.bind / Expression.variable). Works for paint and for layer filters. Unbound names evaluate as missing (fail closed).

Expression.bind( listOf(Expression.Variable("n", Expression.get("value"))), Expression.multiply(Expression.variable("n"), 2), )

Scales

step

Maps a continuous input onto discrete outputs at stops. Works for paint color, number, and string values.

Expression.step( Expression.get("age"), listOf( Expression.Step(null, "#ffffff"), Expression.Step(60000, "#ffff00"), Expression.Step(300000, "#ff0000"), ), )

For text and symbol size, the input may be Expression.zoom so the value follows map zoom. Do not use zoom in a layer filter — filters do not resolve it.

interpolate

Linear, exponential, or cubic-bezier blending between stops. Works for paint color and numeric paint (size, radius, weight).

Expression.interpolate( Expression.get("magnitude"), listOf(0.0, "rgba(0, 0, 255, 1)", 6.0, "rgba(255, 0, 0, 1)"), ) Expression.interpolate( Expression.zoom, listOf(4, 2.0, 12, 16.0), ) Expression.interpolateExponential(Expression.get("value"), 1.5, listOf(0.0, 1.0, 100.0, 10.0)) Expression.interpolateCubicBezier( Expression.get("value"), listOf(0.42, 0.0, 0.58, 1.0), listOf(0.0, 1.0, 100.0, 10.0), )

Heatmap color ramps still use this operator on heatmap-density; that path is separate from fill/line/circle/symbol paint.

Mathematical Expressions

These evaluate on numeric paint properties:

Expression.add(Expression.get("value"), 2) Expression.multiply(Expression.get("value"), 1.8) Expression.subtract(Expression.get("max"), Expression.get("min")) Expression.divide(Expression.get("value"), 2) Expression.min(Expression.get("a"), Expression.get("b")) Expression.max(Expression.get("a"), Expression.get("b")) Expression.floor(Expression.get("value")) Expression.ceil(Expression.get("value")) Expression.abs(Expression.get("value")) Expression.mod(Expression.get("value"), 10) Expression.round(Expression.get("value")) Expression.toNumber(Expression.get("value"))

Comparison and Logic

Use these in layer filters and in switchCase conditions:

Expression.equals(Expression.get("CAT"), "flood") Expression.notEquals(Expression.get("VTEC"), "FL.W") Expression.greaterThan(Expression.get("value"), 100) Expression.greaterThanOrEqual(Expression.get("value"), 0) Expression.lessThanOrEqual(Expression.get("timestamp"), Expression.mapTime)

and serializes as ["all", …], or as ["any", …]. contains compiles to a match filter (not in).

Expression.and( listOf( Expression.equals(Expression.get("featureType"), "trackPoint"), Expression.lessThanOrEqual(Expression.get("timestamp"), Expression.mapTime), ) ) Expression.or( listOf( Expression.equals(Expression.get("CAT"), "flood"), Expression.equals(Expression.get("CAT"), "wind"), ) ) Expression.not(Expression.equals(Expression.get("hidden"), true)) Expression.contains(Expression.geometryType, listOf("Polygon", "MultiPolygon")) Expression.has("COLOR")

Geometry and Map Time

Expression.geometryType // ["geometry-type"] — layer filters Expression.mapTime // ["map-time"] — timeline position as Unix seconds

Expression.mapTime is the active map timeline, not wall-clock time. Built-in tropical tracks and convective outlooks already filter on it. Custom vector layers can do the same:

layer.filter = Expression.lessThanOrEqual( Expression.get("timestamp"), Expression.mapTime, )

String Operators

Expression.concat(listOf("#", Expression.get("COLOR"))) Expression.upcase(Expression.get("label")) Expression.downcase(Expression.get("report.type")) Expression.toString(Expression.get("id")) Expression.join("-", listOf(Expression.get("a"), Expression.get("b"))) Expression.slice(Expression.get("label"), 0, 3) Expression.length(Expression.get("label")) Expression.at(0, Expression.get("vals"))

concat is the usual way to turn an MVT hex property such as COLOR (00FF00) into a CSS color (#00FF00). get("vals.0") compiles to at and reads the first array element.

Color

Paint color on fill, line, circle, and symbol layers evaluates step, match, case, concat, rgb, rgba, and interpolate (linear, exponential, and cubic-bezier):

Expression.rgb(255, 0, 0) Expression.rgba(255, 0, 0, 0.5) Expression.concat(listOf("#", Expression.get("COLOR"))) Expression.interpolate( Expression.get("magnitude"), listOf(0.0, "rgba(0, 0, 255, 1)", 6.0, "rgba(255, 0, 0, 1)"), )

Heatmap color ramps use interpolate on heatmap-density through the heatmap painter, not this general fill/line/circle path.

Not evaluated

These factories still serialize Mapbox-style JSON but are not run for GLES vector paint or filters: format, indexOf, and toBoolean. Expression.zoom works for paint (size, radius, color) but not in a layer filter.

Resources

© 2026 Xweather (opens in a new tab)Terms of Service (opens in a new tab)Privacy Policy (opens in a new tab)