Overlay Compose UI
MaplibreMap draws controls on top of the map. The overlay
block replaces the default controls when you supply it. The default draws a
scale bar and a compass along the top edge. It draws the MapLibre logo and an
attribution button along the bottom edge. The scale bar and the compass appear
only while they are relevant.
MaplibreMap()Two variants cover common needs. MapOverlay.Full adds zoom in and zoom out
buttons at the middle of the end edge. MapOverlay.AttributionOnly draws only
the logo and the attribution button.
Replace the overlay
Section titled “Replace the overlay”An empty block, or MapOverlay.None, draws no controls. Use it when your app
shows the attribution somewhere else, such as an about screen.
MaplibreMap {}The trailing block draws the controls that you list. Modifier.align positions
a control against an inset edge of the map.
MaplibreMap { MaplibreLogo(Modifier.align(Alignment.BottomStart)) ExpandingAttributionButton( modifier = Modifier.align(Alignment.TopEnd), contentAlignment = Alignment.TopEnd, )}Theme the controls with Material 3
Section titled “Theme the controls with Material 3”The base library draws controls with a fixed palette that stays legible on any
basemap. The maplibre-compose-material3 module draws the same controls with
your Material 3 color scheme and typography. Add the dependency:
[libraries]maplibre-composeMaterial3 = { module = "org.maplibre.compose:maplibre-compose-material3", version = "0.15.0" }commonMain.dependencies { implementation(libs.maplibre.composeMaterial3)}MapOverlay.Material3 draws the same controls
as MapOverlay.Default in the same places. Include it in the block:
MaplibreMap { include(MapOverlay.Material3) }MapOverlay.Material3AttributionOnly and MapOverlay.Material3Full apply the
theme to the other presets.
Each Material 3 control is also a composable that you can place in the trailing block:
MaplibreMap { ScaleBar( mapState.viewport?.metersPerDpAtTarget ?: 0.0, modifier = Modifier.align(Alignment.TopStart), ) // (1)! CompassButton(modifier = Modifier.align(Alignment.TopEnd)) ZoomButtons(Modifier.align(Alignment.CenterEnd)) MaplibreLogo(Modifier.align(Alignment.BottomStart)) ExpandingAttributionButton( modifier = Modifier.align(Alignment.BottomEnd), contentAlignment = Alignment.BottomEnd, )}ScaleBarandCompassButtonstay on screen. TheDisappearingversions thatMapOverlay.Material3uses fade in when the zoom or the orientation changes, and fade out once it settles.
Inset overlays and the camera
Section titled “Inset overlays and the camera”Use contentWindowInsets to inset overlay controls. Use cameraPadding to
shift the camera center. They can use the same values or vary independently.
val mapInsets = WindowInsets.safeDrawing.union(WindowInsets(bottom = 128.dp))MaplibreMap( contentWindowInsets = mapInsets, // (1)! cameraPadding = mapInsets.asPaddingValues(),)uniontakes the larger inset on each edge.
Padding on a bounding-box camera move adds to cameraPadding for that fit.
Pin Compose UI to a location
Section titled “Pin Compose UI to a location”MapOverlayScope.placedAt puts a child on a geographic position.
Include MapOverlay.Default to keep the default controls. A pan, a
zoom, or a window resize moves the child with the map.
MaplibreMap { include(MapOverlay.Default) Text( "Next sailing 12:40", Modifier.placedAt(position, Alignment.BottomCenter).padding(bottom = 8.dp), // (1)! )}Alignment.BottomCentersits the bottom edge of the chip on the point. Padding lifts the chip above the feature.
Point at an off-screen location
Section titled “Point at an off-screen location”MapOverlayScope.placedTowards puts a child on the edge of an
ellipse inscribed in the unobstructed map region, on the line towards a
geographic position. The
child appears only while the position projects outside of that ellipse. A
position near a corner of the map region can be visible and still lie outside
the ellipse.
MaplibreMap { include(MapOverlay.Default) val placement = rememberPlacedTowardsState() // (1)! Text( "▲", Modifier.placedTowards(position, placement).graphicsLayer { rotationZ = placement.angleDegrees // (2)! }, )}- The state stores the placement that the overlay computed.
angleDegreesis the direction of the target, clockwise from screen-up.
PointerPinButton from the Material 3 module uses this modifier
to display a pin-shaped button that points at the target.