Skip to content

Map controls

MaplibreMap draws controls on top of the map. The overlay parameter sets which ones. The default is a scale bar and a compass along the top edge, and the MapLibre logo and an attribution button along the bottom edge. The scale bar and the compass appear only while they are relevant.

App.kt
MaplibreMap()

MapOverlay.None draws no controls. Use it when your app shows the attribution somewhere else, such as an about screen.

App.kt
MaplibreMap(overlay = MapOverlay.None)

A MapOverlay block draws the controls you list in it. Modifier.align positions a control against an inset edge of the map.

App.kt
MaplibreMap(
overlay =
MapOverlay {
MaplibreLogo(Modifier.align(Alignment.BottomStart))
ExpandingAttributionButton(
cameraState = cameraState, // (1)!
styleState = styleState,
modifier = Modifier.align(Alignment.TopEnd),
contentAlignment = Alignment.TopEnd,
)
}
)
  1. The block can read the map’s cameraState and styleState, so a control inside it takes no state arguments.

MapOverlay.Material3 from the Material 3 extensions draws the same controls, themed from your color scheme and typography.

Use contentWindowInsets to inset overlay controls. Use cameraPadding to shift the camera center. They can use the same values or vary independently.

App.kt
val mapInsets = WindowInsets.safeDrawing.union(WindowInsets(bottom = 128.dp))
MaplibreMap(
contentWindowInsets = mapInsets, // (1)!
cameraPadding = mapInsets.asPaddingValues(),
)
  1. union takes the larger inset on each edge.

Padding on a bounding-box camera move adds to cameraPadding for that fit.

Modifier.placedAt puts a child on a geographic position. Keep the default controls with include, then add the child in the same overlay. A pan, a zoom, or a window resize moves the child with the map.

App.kt
MaplibreMap(
overlay =
MapOverlay {
include(MapOverlay.Default)
Text(
"Next sailing 12:40",
Modifier.placedAt(position, Alignment.BottomCenter).padding(bottom = 8.dp), // (1)!
)
}
)
  1. Alignment.BottomCenter sits the bottom edge of the chip on the point. Padding lifts the chip above the feature.

Modifier.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.

App.kt
MaplibreMap(
overlay =
MapOverlay {
include(MapOverlay.Default)
val placement = rememberPlacedTowardsState() // (1)!
Text(
"▲",
Modifier.placedTowards(position, placement).graphicsLayer {
rotationZ = placement.angleDegrees // (2)!
},
)
}
)
  1. The state carries the placement that the overlay computed.
  2. angleDegrees is the direction of the target, clockwise from screen-up.

PointerPinButton from the Material 3 extensions is a styled consumer of this modifier: an elevated button in the shape of a pin that points at the target.