Skip to content

MapCameraPositionInterface

MapCameraPositionInterface represents the camera’s viewing position, orientation, and visible area on the map. It defines where the camera is looking, how much of the map is visible, and the perspective from which the map is viewed.

interface MapCameraPositionInterface {
val position: GeoPointInterface
val zoom: Double
val bearing: Double
val tilt: Double
val paddings: MapPaddingsInterface?
val visibleRegion: VisibleRegion?
}

The main implementation provides immutable camera position data:

data class MapCameraPosition(
override val position: GeoPoint,
override val zoom: Double = 0.0,
override val bearing: Double = 0.0,
override val tilt: Double = 0.0,
override val paddings: MapPaddingsInterface? = MapPaddings.Zeros,
override val visibleRegion: VisibleRegion? = null
) : MapCameraPositionInterface
  • position: GeoPointInterface: Geographic center point of the camera’s view
  • zoom: Double: Zoom level (approximately follows Google Maps scale)
  • bearing: Double: Compass direction in degrees (0 = North, 90 = East)
  • tilt: Double: Camera tilt angle in degrees (0 = top-down, 90 = horizontal)
  • paddings: MapPaddingsInterface?: Viewport padding that affects the visible region
  • visibleRegion: VisibleRegion?: (Readonly) The actual geographic bounds visible on screen. Note: this property does not work in v1.1.3 yet.
// Default camera position at origin
val defaultPosition = MapCameraPosition.Default
// Basic camera position
val sanFrancisco = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 15
)
// Camera with bearing and tilt
val aerialView = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 18,
bearing = 45, // Northeast direction
tilt = 60 // Angled view
)

MapConductor zoom levels approximately follow Google Maps scale but may vary slightly between providers:

  • 0-2: World view, continents visible
  • 3-5: Country level
  • 6-9: State/region level
  • 10-12: City level
  • 13-15: District/neighborhood level
  • 16-18: Street level
  • 19-21: Building level (high detail)
// Different zoom levels for different use cases
val worldView = MapCameraPosition(
position = GeoPoint.fromLatLong(0, 0),
zoom = 2 // Show continents
)
val cityView = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 12 // Show entire city
)
val streetView = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 17 // Show individual streets
)

Bearing rotates the map around the center point:

// North-up (default)
val northUp = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
bearing = 0
)
// East-up
val eastUp = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
bearing = 90
)
// Following route bearing
val routeBearing = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
bearing = 135, // Southeast
zoom = 18.0
)

Tilt provides 3D viewing angles:

// Top-down view (default)
val topDown = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
tilt = 0
)
// Slight angle for depth
val angled = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
tilt = 30,
zoom = 16
)
// Maximum tilt for street-level view
val streetLevel = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
tilt = 80,
bearing = 45,
zoom = 19
)

The visible region describes the actual geographic area shown on screen after considering camera position, zoom level, bearing, tilt, and viewport padding.

data class VisibleRegion(
val bounds: GeoRectBounds, // Overall bounding rectangle
val nearLeft: GeoPointInterface?, // Bottom-left corner (near to camera)
val nearRight: GeoPointInterface?, // Bottom-right corner (near to camera)
val farLeft: GeoPointInterface?, // Top-left corner (far from camera)
val farRight: GeoPointInterface? // Top-right corner (far from camera)
)
  • bounds: GeoRectBounds: The rectangular geographic bounds that encompass the entire visible area. This is the minimum bounding rectangle that contains all visible content.
  • nearLeft: GeoPointInterface?: The geographic coordinate of the bottom-left corner of the visible region. “Near” refers to the side closest to the camera position.
  • nearRight: GeoPointInterface?: The geographic coordinate of the bottom-right corner of the visible region.
  • farLeft: GeoPointInterface?: The geographic coordinate of the top-left corner of the visible region. “Far” refers to the side furthest from the camera position.
  • farRight: GeoPointInterface?: The geographic coordinate of the top-right corner of the visible region.
@Composable
fun VisibleRegionExample() {
val mapViewState = rememberMapboxMapViewState(
cameraPosition = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 15.0
),
)
var visibleRegionInfo by remember { mutableStateOf<VisibleRegion?>(null) }
// Replace MapView with your chosen map provider, such as GoogleMapView, MapboxMapView
MapboxMapView(
state = mapViewState,
modifier = modifier,
onCameraMoveEnd = { cameraPosition ->
cameraPosition.visibleRegion?.let { visibleRegion ->
visibleRegionInfo = visibleRegion
}
},
) {
// Display visible region info
visibleRegionInfo?.let { region ->
// Show bounds as a polygon
region.bounds.let { bounds ->
if (!bounds.isEmpty) {
val sw = bounds.southWest!!
val ne = bounds.northEast!!
Polygon(
points = listOf(
sw,
GeoPoint.fromLatLong(sw.latitude, ne.longitude),
ne,
GeoPoint.fromLatLong(ne.latitude, sw.longitude),
sw
),
strokeColor = Color.Blue,
strokeWidth = 2.dp,
fillColor = Color.Blue.copy(alpha = 0.1f)
)
}
}
}
}
}
@Composable
fun AnimatedCameraExample() {
val locations = listOf(
GeoPoint.fromLatLong(37.7749, -122.4194), // San Francisco
GeoPoint.fromLatLong(40.7128, -74.0060), // New York
GeoPoint.fromLatLong(51.5074, -0.1278) // London
)
val mapViewState = rememberHereMapViewState(
cameraPosition = MapCameraPosition(
position = locations[0],
zoom = 6.0
),
)
var currentIndex by remember { mutableStateOf(0) }
// Animate to next location every 5 seconds
LaunchedEffect(Unit) {
while (true) {
delay(5000)
currentIndex = (currentIndex + 1) % locations.size
val targetPosition = MapCameraPosition(
position = locations[currentIndex],
zoom = 6.0,
bearing = 0.0,
tilt = 0.0
)
mapViewState.moveCameraTo(targetPosition, 1000)
}
}
// Replace MapView with your chosen map provider, such as GoogleMapView, MapboxMapView
HereMapView(
state = mapViewState,
modifier = modifier,
) {
// Add markers for each location
locations.forEachIndexed { index, location ->
Marker(
position = location,
icon = DefaultIcon(
fillColor = if (index == currentIndex) Color.Red else Color.Gray,
label = when (index) {
0 -> "SF"
1 -> "NYC"
2 -> "LON"
else -> "$index"
}
)
)
}
}
}
@Composable
fun CameraControlExample(modifier: Modifier = Modifier) {
val mapViewState = rememberMapLibreMapViewState(
mapDesign = MapLibreDesignType(
id = "debug-tiles",
styleJsonURL = "https://demotiles.maplibre.org/debug-tiles/style.json",
),
cameraPosition = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 15.0
),
)
Column(
modifier = modifier,
) {
// Camera controls
Row {
Button(
onClick = {
val newZoom = mapViewState.cameraPosition.copy(
zoom = (mapViewState.cameraPosition.zoom + 1)
.coerceAtMost(21.0),
)
mapViewState.moveCameraTo(newZoom, 500)
}
) {
Text("Zoom In")
}
Button(
onClick = {
val newZoom = mapViewState.cameraPosition.copy(
zoom = (mapViewState.cameraPosition.zoom - 1)
.coerceAtMost(21.0),
)
mapViewState.moveCameraTo(newZoom, 500)
}
) {
Text("Zoom Out")
}
Button(
onClick = {
val newZoom = mapViewState.cameraPosition.copy(
bearing = (mapViewState.cameraPosition.bearing + 45) % 360,
)
mapViewState.moveCameraTo(newZoom, 500)
}
) {
Text("Rotate")
}
}
// Tilt slider
Slider(
value = mapViewState.cameraPosition.tilt.toFloat(),
onValueChange = { tilt ->
val newZoom = mapViewState.cameraPosition.copy(
tilt = tilt.toDouble(),
)
mapViewState.moveCameraTo(newZoom)
},
valueRange = 0f..80f
)
// Replace MapView with your chosen map provider, such as GoogleMapView, MapboxMapView
MapLibreMapView(
state = mapViewState,
) {
Marker(
position = mapViewState.cameraPosition.position,
icon = DefaultIcon(fillColor = Color.Red)
)
}
}
}