Documentación / Vista de mapa / Cambiar proveedor

Cambiar proveedor

Lo único que varía entre los proveedores son tres cosas: los módulos dependientes, el tipo de vista de mapa y el tipo de objeto de estado. La forma de escribir marcadores, figuras, operaciones de cámara y eventos no cambia. También puede colocar varios proveedores en la misma pantalla y cambiarlos en tiempo de ejecución.

ANDROID
8 proveedores
iOS
9 proveedores
REACT
13 proveedores

01 · Qué cambia y qué permanece igual

Cambia
  • Módulos de dependencia (for-maplibre → for-googlemaps, etc.)
  • Tipo de vista de mapa (MapLibreMapView → GoogleMapView)
  • Tipo del objeto de estado y su función de generación
  • Constantes de diseño que se pasan a mapDesignType
  • Cómo obtener una clave de API y las prácticas de inicialización
No cambia
  • GeoPoint · GeoRectBounds · MapCameraPosition
  • MarkerState · PolylineState · PolygonState · CircleState …
  • moveCameraTo() · fitBounds() · controladores de eventos
  • Cálculos geográficos (distancia, rumbo, área)
  • Capas extendidas (agrupación, mapa de calor, GeoJSON)

Si bien el tipo de objeto de estado está separado para cada proveedor, implementa una interfaz común (Android: MapViewStateInterface, iOS: MapViewStateProtocol, React: MapViewStateInterface). Las operaciones de cámara y el cambio de diseño se pueden escribir a través de esta interfaz común.

Fig. · El mapa real que dibuja cada proveedor (de la aplicación de ejemplo)
GOOGLE MAPS
MAPLIBRE
MAPBOX
HERE
ARCGIS

02 · Tipos por proveedor

Una lista de las vistas de mapa y objetos de estado que expone cada proveedor. Debido a razones históricas, hay lugares donde los nombres no coinciden completamente, por lo que se muestran los nombres tal como se exportan realmente.

Provider
Android
iOS
React
Google Maps
GoogleMapView
rememberGoogleMapViewState
GoogleMapViewState
GoogleMapView
GoogleMapViewState
GoogleMapView2D / GoogleMapView
useGoogleMapViewState
MapLibre
MapLibreMapView
rememberMapLibreMapViewState
MapLibreViewState
MapLibreMapView
MapLibreViewState
MapLibreMapView2D
useMapLibreViewState
Mapbox
MapboxMapView
rememberMapboxMapViewState
MapboxViewState
MapboxMapView
MapboxViewState
MapBoxMapView2D / MapBoxMapView
useMapboxViewState
HERE
HereMapView
rememberHereMapViewState
HereViewState
HereMapView
HereMapViewState
HereMapView2D
useHereViewState
ArcGIS
ArcGISMapView / 2D
rememberArcGISMapViewState
ArcGISMapViewState
ArcGISMapView / 2D
ArcGISMapViewState
ArcGISMapView2D / ArcGISMapView
useArcGISViewState
MapTiler
MapTilerMapView
rememberMapTilerMapViewState
MapTilerViewState
MapTilerMapView
MapTilerViewState
MapTilerMapView2D
useMapTilerViewState
TomTom
TomTomMapView
rememberTomTomMapViewState
TomTomMapViewState
TomTomMapView
TomTomMapViewState
TomTomMapView2D
useTomTomViewState
Longdo
LongdoMapView
rememberLongdoMapViewState
LongdoViewState
LongdoMapView
LongdoViewState
LongdoMapView2D
useLongdoViewState
Apple MapKit
MapKitMapView
MapKitViewState
MapKitMapView
useMapKitViewState
Leaflet
LeafletMapView
useLeafletMapViewState
OpenLayers
OpenLayersMapView
useOpenLayersMapViewState
Azure Maps
AzureMapsMapView
useAzureMapsViewState
Cesium
CesiumMapView
useCesiumMapViewState

"/ 2D" indica que hay dos vistas: una vista 3D y una vista 2D. Ambas comparten el mismo objeto de estado y, en 2D, tilt siempre es 0.

Plataforma

03 · Cómo escribir el cambio

Cuando desee cambiar en tiempo de ejecución, mantenga un objeto de estado para cada proveedor y bifurque solo la vista que se muestra. La descripción de las superposiciones se puede colocar fuera de la bifurcación. La aplicación de ejemplo tiene esta forma.

MapViewContainer.kt · Jetpack Compose
@Composable
fun MapViewContainer(
    modifier: Modifier = Modifier,
    state: MapViewStateInterface<*>? = null,
    content: (@Composable MapViewScope.() -> Unit)? = null,
) {
    when (state) {
        is GoogleMapViewState -> GoogleMapView(modifier, state, content = content)
        is MapLibreViewState -> MapLibreMapView(modifier, state, content = content)
        is MapboxViewState -> MapboxMapView(modifier, state, content = content)
        is HereViewState -> HereMapView(modifier, state, content = content)
        else -> { /* not selected */ }
    }
}

// Quien llama escribe solo las capas
MapViewContainer(state = selectedState) {
    Markers(markerStates)
}

En React, no se puede cambiar el orden de las llamadas a los hooks, por lo que es seguro extraer las vistas de cada proveedor en componentes separados y llamar a los hooks dentro de ese componente. El directorio providers/ de la aplicación de ejemplo tiene esa configuración.

Implementación en video · Android + MapLibreKotlin · Jetpack Compose
// One state per provider
val maplibre = rememberMapLibreMapViewState(
    mapDesign = MapLibreDesign.OsmBrightJa,
    cameraPosition = MapCameraPosition(
        position = GeoPoint.fromLatLong(35.6812, 139.7671),
        zoom = 12.0,
    ),
)
val googlemaps = rememberGoogleMapViewState(
    cameraPosition = MapCameraPosition(
        position = GeoPoint.fromLatLong(35.6812, 139.7671),
        zoom = 12.0,
    ),
)
var useMapLibre by remember { mutableStateOf(true) }

// The overlays are declared outside the branch, so swapping does not touch them
val overlays: @Composable MapViewScope.() -> Unit = {
    Marker(markerState)
    Polyline(routeState)
}

// Hand the camera you were just looking at to the side you are switching to
LaunchedEffect(useMapLibre) {
    if (useMapLibre) {
        maplibre.moveCameraTo(googlemaps.cameraPosition)
    } else {
        googlemaps.moveCameraTo(maplibre.cameraPosition)
    }
}

if (useMapLibre) {
    MapLibreMapView(state = maplibre, content = overlays)
} else {
    GoogleMapView(state = googlemaps, content = overlays)
}
Video de ejemplo · Cambiar de proveedor durante la ejecución
Video aún no grabadoEn la aplicación de ejemplo: cambiar solo la vista del mapa mientras se mantienen las superposiciones. Ver que los marcadores y polilíneas permanecen en la misma posición antes y después del cambio ilustra el punto de esta sección.

04 · Manejo de las diferencias entre proveedores

No todos los SDK de mapas tienen las mismas funciones. MapConductor cubre las diferencias donde puede y proporciona representaciones alternativas donde no puede.

1 · Renderizado alternativo

Si la funcionalidad no está disponible de forma nativa, el SDK la renderiza como teselas de trama. Esto incluye huecos en polígonos y el renderizado masivo de marcadores. El código de llamada no cambia.

2 · Indicar por tipo

Para los elementos que ese proveedor no puede manejar, el controlador no tiene un renderizador compatible. Se puede saber si se puede usar en tiempo de compilación o por el tipo del objeto de estado.

3 · Salida

Si de verdad necesita la funcionalidad específica de ese proveedor, puede obtener la instancia del mapa nativo desde `MapViewHolder` y llamarla directamente.

CLAVES DE API

Las claves y la inicialización son por proveedor

`MapConductor` no recibe claves de API. Las pasa tal cual en la forma que cada SDK de mapas requiere (manifiesto de Android, `sdkInitialize` en iOS, objeto de configuración en Web). También hay proveedores como `MapLibre`, `Leaflet` y `OpenLayers` que no necesitan claves; en ese caso solo se determina la fuente de las teselas.

Páginas relacionadas