Skip to content
This site is a preview of pull request #1363.

Add images and icons

A SymbolLayer draws an icon at each feature in its source. The image expression supplies the icon, from a Compose painter, an ImageBitmap, or the base style’s sprite.

Pass a painter to image(). The library rasterizes it and registers it with the style. This works with painterResource, vector drawables, and any other painter:

App.kt
val state = rememberMapState {
val stations =
rememberGeoJsonSource(GeoJsonData.Uri(Res.getUri("files/data/amtrak_stations.geojson")))
SymbolLayer(
id = "station-icons",
source = stations,
iconImage = image(painterResource(Res.drawable.map_24px), size = DpSize(24.dp, 24.dp)),
)
}
MaplibreMap(state = state)

Base styles usually bundle a sprite: a named set of icons. Pass the icon name to image():

App.kt
val state = rememberMapState {
SymbolLayer(id = "station-markers", source = stations, iconImage = image("marker"))
}
MaplibreMap(state = state)

An ImageSource positions one image on the map by its four corner coordinates. A RasterLayer draws it:

App.kt
val state = rememberMapState {
val corners =
PositionQuad(
topLeft = Position(longitude = -74.0178, latitude = 40.7040),
topRight = Position(longitude = -74.0118, latitude = 40.7100),
bottomRight = Position(longitude = -74.0060, latitude = 40.7067),
bottomLeft = Position(longitude = -74.0120, latitude = 40.7006),
)
val plan = rememberImageSource(position = corners, uri = Res.getUri("files/castello-plan.jpg"))
RasterLayer(id = "castello-plan", source = plan, opacity = const(0.8f))
}
MaplibreMap(state = state)

A style can reference an icon that its sprite does not contain. Set MapState.missingImageResolver to supply one. The map calls the resolver with the icon’s ID and adds the ResolvedStyleImage that it returns:

App.kt
val mapState = rememberMapState()
DisposableEffect(mapState, fallback) {
mapState.missingImageResolver = { ResolvedStyleImage(fallback) }
onDispose { mapState.missingImageResolver = null }
}
MaplibreMap(state = mapState)