Skip to content

Expressions in Kotlin

Layer properties in MapLibre are not plain values. Each property takes an expression: a formula that the map evaluates while it renders, per feature and per zoom level. The MapLibre Style Specification defines expressions as JSON arrays. MapLibre Compose provides a Kotlin DSL that builds them with type checking, in org.maplibre.compose.expressions.dsl.

The DSL uses Compose types when a Compose type matches the property: Dp for sizes, Color for colors, and DpOffset for offsets.

A constant value must also be an expression. Wrap a plain value in const:

App.kt
val earthquakes =
rememberGeoJsonSource(
GeoJsonData.Uri("https://maplibre.org/maplibre-gl-js/docs/assets/earthquakes.geojson")
)
CircleLayer(
id = "quakes-constant",
source = earthquakes,
radius = const(4.dp),
color = const(Color.Red),
)

feature accesses the properties of the feature being rendered. The result is untyped, so convert it with functions such as asNumber() or asString(). Functions such as step and switch select an output from the value:

App.kt
CircleLayer(
id = "quakes-by-magnitude",
source = earthquakes,
radius =
step(
input = feature["mag"].asNumber(),
fallback = const(4.dp),
4 to const(8.dp),
6 to const(16.dp),
),
color =
switch(
condition(test = feature["mag"].asNumber() gt const(5), output = const(Color.Red)),
fallback = const(Color.Yellow),
),
)

The map evaluates this formula once per feature: each earthquake receives a radius and a color computed from its own magnitude.

zoom is the current zoom level. interpolate computes a smooth value between stops:

App.kt
CircleLayer(
id = "quakes-by-zoom",
source = earthquakes,
radius =
interpolate(
type = exponential(2f),
input = zoom(),
5 to const(2.dp),
10 to const(8.dp),
),
)

The filter parameter takes a boolean expression. The layer renders only the features for which it is true:

App.kt
CircleLayer(
id = "large-quakes",
source = earthquakes,
filter = feature["mag"].asNumber() gt const(5),
)

Kotlin code outside an expression runs during composition and produces an expression. The expression runs inside the map renderer, once per feature. A Kotlin if selects which expression to build; an expression switch selects a value per feature. Use Kotlin for decisions that depend on app state, and expressions for decisions that depend on feature data or zoom.

The API reference documents the full set of expression functions under org.maplibre.compose.expressions.dsl.