Skip to content

MapCameraPositionInterface

MapCameraPositionInterface representa la posición, orientación y área visible de la cámara en el mapa. Define hacia dónde mira la cámara, cuánto mapa se ve y desde qué perspectiva.

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

La implementación principal proporciona datos inmutables de la posición de la cámara:

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: Punto geográfico central de la vista de la cámara.
  • zoom: Double: Nivel de zoom (aproximadamente alineado con la escala de Google Maps).
  • bearing: Double: Rumbo en grados (0 = norte, 90 = este).
  • tilt: Double: Ángulo de inclinación en grados (0 = vista cenital, 90 = horizontal).
  • paddings: MapPaddingsInterface?: Márgenes del viewport que afectan a la región visible. Nota: esta propiedad aún no funciona en v1.1.3.
  • visibleRegion: VisibleRegion?: (Solo lectura) Límites geográficos que realmente se ven en pantalla.
// Posición de cámara por defecto en el origen
val defaultPosition = MapCameraPosition.Default
// Posición básica de la cámara
val sanFrancisco = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 15
)
// Cámara con rumbo e inclinación
val aerialView = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 18,
bearing = 45, // Northeast direction
tilt = 60 // Angled view
)

Los niveles de zoom de MapConductor se alinean aproximadamente con la escala de Google Maps, aunque pueden variar ligeramente según el proveedor:

  • 0-2: Vista mundial, continentes visibles
  • 3-5: Nivel de país
  • 6-9: Nivel de estado/región
  • 10-12: Nivel de ciudad
  • 13-15: Nivel de barrio/distrito
  • 16-18: Nivel de calle
  • 19-21: Nivel de edificio (alto detalle)
// Different zoom levels for different use cases
val worldView = MapCameraPosition(
position = GeoPoint.fromLatLong(0, 0),
zoom = 2 // Mostrar continentes
)
val cityView = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 12 // Mostrar ciudad completa
)
val streetView = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
zoom = 17 // Mostrar calles individuales
)

El rumbo rota el mapa alrededor del punto central:

// Norte arriba (por defecto)
val northUp = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
bearing = 0
)
// Este arriba
val eastUp = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
bearing = 90
)
// Siguiendo el rumbo de la ruta
val routeBearing = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
bearing = 135, // Sureste
zoom = 18.0
)

La inclinación proporciona ángulos de vista en 3D:

// Vista cenital (por defecto)
val topDown = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
tilt = 0
)
// Ángulo ligero para dar profundidad
val angled = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
tilt = 30,
zoom = 16
)
// Inclinación máxima para vista a nivel de calle
val streetLevel = MapCameraPosition(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
tilt = 80,
bearing = 45,
zoom = 19
)

La región visible describe el área geográfica real mostrada en pantalla teniendo en cuenta la posición de la cámara, el nivel de zoom, el rumbo, la inclinación y los márgenes del viewport.

data class VisibleRegion(
val bounds: GeoRectBounds, // Rectángulo delimitador general
val nearLeft: GeoPointInterface?, // Esquina inferior izquierda (cerca de la cámara)
val nearRight: GeoPointInterface?, // Esquina inferior derecha (cerca de la cámara)
val farLeft: GeoPointInterface?, // Esquina superior izquierda (lejos de la cámara)
val farRight: GeoPointInterface? // Esquina superior derecha (lejos de la cámara)
)
  • bounds: GeoRectBounds: Límites geográficos rectangulares que abarcan toda el área visible.
  • nearLeft: GeoPointInterface?: Coordenada geográfica de la esquina inferior izquierda de la región visible.
  • nearRight: GeoPointInterface?: Coordenada geográfica de la esquina inferior derecha.
  • farLeft: GeoPointInterface?: Coordenada geográfica de la esquina superior izquierda.
  • farRight: GeoPointInterface?: Coordenada geográfica de la esquina superior derecha.
@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) }
// Reemplace MapView con su proveedor de mapas elegido, como GoogleMapView, MapboxMapView
MapboxMapView(
state = mapViewState,
modifier = modifier,
onCameraMoveEnd = { cameraPosition ->
cameraPosition.visibleRegion?.let { visibleRegion ->
visibleRegionInfo = visibleRegion
}
},
) {
// Mostrar información de la región visible
visibleRegionInfo?.let { region ->
// Mostrar límites como polígono
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) }
// Animar a la siguiente ubicación cada 5 segundos
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
)
// Reemplace MapView con su proveedor de mapas elegido, como GoogleMapView, MapboxMapView
MapLibreMapView(
state = mapViewState,
) {
Marker(
position = mapViewState.cameraPosition.position,
icon = DefaultIcon(fillColor = Color.Red)
)
}
}
}