Add data to the map
The base style defines the map’s content. To show your own data on top of it,
declare sources and layers in the trailing rememberMapState block,
then pass that state to MaplibreMap. A source holds the data, and a
layer draws data from a source.
Reference a base style source
Section titled “Reference a base style source”getBaseSource looks up a source that the base style defines, so a
layer of yours can draw data that the style already loads:
val baseState = rememberMapState(baseStyle = BaseStyle.Uri("https://tiles.openfreemap.org/styles/liberty")) { getBaseSource<VectorTileSource>(id = "openmaptiles")?.let { tiles -> CircleLayer(id = "example", source = tiles, sourceLayer = "poi") } }MaplibreMap(state = baseState)Declare your own source
Section titled “Declare your own source”rememberGeoJsonSource creates a source from a GeoJSON URI or
string. Layers reference the source object directly:
val state = rememberMapState { val amtrakStations = rememberGeoJsonSource(GeoJsonData.Uri(Res.getUri("files/data/amtrak_stations.geojson")))
val amtrakRoutes = rememberGeoJsonSource(GeoJsonData.Uri(Res.getUri("files/data/amtrak_routes.geojson"))) LineLayer( id = "amtrak-routes-casing", source = amtrakRoutes, color = const(Color.White), width = const(6.dp), ) LineLayer( id = "amtrak-routes", source = amtrakRoutes, color = const(Color.Blue), width = const(4.dp), )}MaplibreMap(state = state)Other source types cover vector tiles, raster tiles, and images. The API
reference documents them under org.maplibre.compose.sources.
Style a layer with expressions
Section titled “Style a layer with expressions”Layer properties accept expressions: formulas that the map evaluates at render
time. Wrap a constant value in const. Functions such as
interpolate and zoom build dynamic values:
val state = rememberMapState { val detailedAmtrakRoutes = rememberGeoJsonSource(GeoJsonData.Uri(Res.getUri("files/data/amtrak_routes.geojson"))) LineLayer( id = "amtrak-routes", source = detailedAmtrakRoutes, cap = const(LineCap.Round), join = const(LineJoin.Round), color = const(Color.Blue), width = interpolate( type = exponential(1.2f), input = zoom(), 5 to const(0.4.dp), 6 to const(0.7.dp), 7 to const(1.75.dp), 20 to const(22.dp), ), )}MaplibreMap(state = state)Expressions in Kotlin explains the expression system. The MapLibre Style Specification documents every layer type and property.
Time a property change
Section titled “Time a property change”When a paint property changes, the map animates it over the style’s global
transition. Pass a TransitionOptions to time one property instead:
val state = rememberMapState { val timedAmtrakStations = rememberGeoJsonSource(GeoJsonData.Uri(Res.getUri("files/data/amtrak_stations.geojson"))) CircleLayer( id = "amtrak-stations-timed", source = timedAmtrakStations, color = const(if (isSystemInDarkTheme()) Color.Cyan else Color.Blue), colorTransition = TransitionOptions(duration = 500.milliseconds), )}MaplibreMap(state = state)Every transitionable paint property has a matching transition parameter, named
after the property. The default, null, uses the global transition that
StyleTransition reads and sets.
Anchor a layer in the stack
Section titled “Anchor a layer in the stack”By default, your layers draw above the base style layers. Anchor
inserts a layer at another position: at the Bottom, at the Top, or Above
or Below a base style layer selected by ID or by a predicate over its
LayerHandle:
val state = rememberMapState { val anchoredAmtrakRoutes = rememberGeoJsonSource(GeoJsonData.Uri(Res.getUri("files/data/amtrak_routes.geojson"))) // Below the base style's labels, whatever the style names them Anchor.Below({ it.type == "symbol" }) { LineLayer(id = "amtrak-routes", source = anchoredAmtrakRoutes) } // Above one base layer, named by its ID Anchor.Above("road_motorway") { LineLayer(id = "amtrak-routes-casing", source = anchoredAmtrakRoutes) }}MaplibreMap(state = state)