Skip to content

Integrating location

The location module provides a cross-platform way to track and visualize user position in MapLibre Compose.

Location support is split into a few small pieces: providers collect position and orientation updates, LocationPuck draws the user's location on the map, and LocationTrackingEffect can optionally keep the camera in sync with those updates.

Overview

Component Purpose
rememberDefaultLocationProvider Provides location data from GPS or other location sources.
rememberDefaultOrientationProvider Provides device orientation data from sensors.
LocationPuck Visual indicator that displays the user's current position and bearing on the map.
LocationTrackingEffect Composable effect to subscribe to location updates.

Android and iOS provide default location and orientation providers. On Desktop and Web there is no default: rememberDefaultLocationProvider and rememberDefaultOrientationProvider throw, so supply a custom LocationProvider or OrientationProvider.

Bearing

Location.course is the direction of movement reported by the location provider. Orientation.orientation is the direction the device is pointing. Use locationState.mostAccurateBearing() when either source is acceptable and the more accurate one should be used.

The puck bearing and camera bearing are separate: LocationPuck(bearing = ...) rotates only the puck indicator, while LocationTrackingEffect and updateFromLocation(updateBearing = ...) control camera rotation.

Bearing update mode Camera behavior
IGNORE Keep the current camera bearing.
ALWAYS_NORTH Reset the camera to north.
TRACK_COURSE Rotate the camera with the user's direction of movement.
TRACK_ORIENTATION Rotate the camera with the device orientation.
TRACK_AUTOMATIC Use the more accurate course or orientation measurement.

Implementation

val cameraState = rememberCameraState()

val locationProvider = rememberDefaultLocationProvider()
val orientationProvider =
  rememberDefaultOrientationProvider() // optional: get device orientation from sensors
val locationState = rememberUserLocationState(locationProvider, orientationProvider)

MaplibreMap(cameraState = cameraState) {
  LocationPuck(
    idPrefix = "user",
    location = locationState.location,
    // optional: combine course and orientation bearing
    bearing = locationState.mostAccurateBearing(),
    cameraState = cameraState,
  )

  LocationTrackingEffect(locationState = locationState) {
    val position = currentLocation.location?.position?.value
    if (position != null) {
      cameraState.animateTo(CameraPosition(target = position, zoom = 15.0))
    }
  }
}

Customizing the puck

Use accuracyThreshold = Float.POSITIVE_INFINITY to hide the accuracy circle. Use showBearing = false or showBearingAccuracy = false to hide bearing indicators. If you use the Material 3 extension module, pass colors = LocationPuckDefaults.colors() for themed colors. onClick and onLongClick can react to interactions with the puck.

Platform Options

Android

Request runtime location permission before collecting location updates. For better accuracy on Android, use the Fused Location/Orientation Provider (requires Google Play Services):

val locationProvider = rememberFusedLocationProvider()
val orientationProvider = rememberFusedOrientationProvider()

Maven dependency:

implementation('com.google.android.gms:play-services-location:21.3.0')