Provider wechseln
Der einzige Unterschied zwischen den Providern sind die drei folgenden Punkte: abhängige Module, Typ der Kartenansicht und Typ des Zustandsobjekts. Die Handhabung von Markern, Formen, Kameraoperationen und Ereignissen ändert sich nicht. Sie können auch mehrere Provider auf demselben Bildschirm nebeneinander anzeigen und zur Laufzeit wechseln.
01 · Was sich ändert und was gleich bleibt
- Abhängigkeitsmodule (for-maplibre → for-googlemaps usw.)
- Typ der Kartenansicht (MapLibreMapView → GoogleMapView)
- Typ des Zustandsobjekts und dessen Erzeugungsfunktion
- Designkonstanten, die an mapDesignType übergeben werden
- So erhalten Sie einen API-Schlüssel und die Initialisierungsverfahren
- GeoPoint · GeoRectBounds · MapCameraPosition
- MarkerState · PolylineState · PolygonState · CircleState …
- moveCameraTo() · fitBounds() · Ereignishandler
- Geoberechnungen (Entfernung, Peilung, Fläche)
- Erweiterungsebenen (Clustering, Heatmap, GeoJSON)
Der Typ des Zustandsobjekts ist zwar für jeden Provider getrennt, implementiert aber eine gemeinsame Schnittstelle (Android: MapViewStateInterface, iOS: MapViewStateProtocol, React: MapViewStateInterface). Kameraoperationen und Designwechsel können über diese gemeinsame Schnittstelle geschrieben werden.





02 · Provider-spezifische Typen
Eine Übersicht der Kartenansichten und Zustandsobjekte, die von jedem Anbieter bereitgestellt werden. Aufgrund historischer Gründe sind die Namen nicht vollständig einheitlich, daher werden die tatsächlich exportierten Namen unverändert aufgeführt.
rememberGoogleMapViewState
GoogleMapViewState
GoogleMapViewState
useGoogleMapViewState
rememberMapLibreMapViewState
MapLibreViewState
MapLibreViewState
useMapLibreViewState
rememberMapboxMapViewState
MapboxViewState
MapboxViewState
useMapboxViewState
rememberHereMapViewState
HereViewState
HereMapViewState
useHereViewState
rememberArcGISMapViewState
ArcGISMapViewState
ArcGISMapViewState
useArcGISViewState
rememberMapTilerMapViewState
MapTilerViewState
MapTilerViewState
useMapTilerViewState
rememberTomTomMapViewState
TomTomMapViewState
TomTomMapViewState
useTomTomViewState
rememberLongdoMapViewState
LongdoViewState
LongdoViewState
useLongdoViewState
MapKitViewState
useMapKitViewState
useLeafletMapViewState
useOpenLayersMapViewState
useAzureMapsViewState
useCesiumMapViewState
"/ 2D" bedeutet, dass es zwei Ansichten gibt: eine 3D-Ansicht und eine 2D-Ansicht. Beide teilen sich dasselbe Zustandsobjekt, und in der 2D-Ansicht ist tilt immer 0.
03 · Wie man den Wechsel schreibt
Wenn Sie zur Laufzeit wechseln möchten, behalten Sie ein Zustandsobjekt für jeden Provider vor und verzweigen nur die angezeigte Ansicht. Die Beschreibung von Overlays kann außerhalb der Verzweigung platziert werden. Die Beispiel-App verwendet diese Form.
@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 */ }
}
}
// Der Aufrufer schreibt nur die Overlays
MapViewContainer(state = selectedState) {
Markers(markerStates)
}@StateObject private var googleState = GoogleMapViewState(cameraPosition: initial)
@StateObject private var mapLibreState = MapLibreViewState(cameraPosition: initial)
// Über die gemeinsame Schnittstelle kommt die Kameraarbeit ohne Verzweigungen aus
private var activeState: any MapViewStateProtocol {
provider == .googleMaps ? googleState : mapLibreState
}
@ViewBuilder
private var mapView: some View {
switch provider {
case .googleMaps:
GoogleMapView(state: googleState, sdkInitialize: {
GMSServices.provideAPIKey(apiKey)
}) { Marker(state: markerState) }
case .mapLibre:
MapLibreMapView(state: mapLibreState) { Marker(state: markerState) }
}
}// Die Hooks je Komponente unverändert aufrufen und nur die View austauschen
const maplibre = useMapLibreViewState({ id: 'maplibre', cameraPosition: INIT });
const google = useGoogleMapViewState({ id: 'google', cameraPosition: INIT });
switch (provider) {
case 'maplibre':
return <MapLibreMapView2D state={maplibre}>{children}</MapLibreMapView2D>;
case 'google-maps':
return <GoogleMapView2D state={google}>{children}</GoogleMapView2D>;
}In React kann die Reihenfolge der Hook-Aufrufe nicht geändert werden, daher ist es sicher, die providerspezifischen Ansichten in separate Komponenten auszulagern und die Hooks innerhalb dieser Komponenten aufzurufen. Das Verzeichnis providers/ der Beispiel-App hat diesen Aufbau.
// 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)
}04 · Umgang mit Provider-Unterschieden
Nicht alle Karten-SDKs bieten denselben Funktionsumfang. MapConductor gleicht Unterschiede aus, wo dies möglich ist, und bietetalternative Darstellungen, wo dies nicht möglich ist.
Wenn die Funktion nicht nativ vorhanden ist, rendert die Seite des SDK sie als Rasterkacheln. Dazu gehören Löcher in Polygonen und das massenhafte Zeichnen von Markern. Der Code des Aufrufers ändert sich nicht.
Für Elemente, die dieser Anbieter nicht verarbeiten kann, verfügt der Treiber über keinen entsprechenden Renderer. Ob es verwendet werden kann, lässt sich zur Kompilierungszeit oder anhand des Typs des Zustandsobjekts entscheiden.
Wenn Sie die für diesen Anbieter spezifische Funktion unbedingt benötigen, können Sie die native Karteninstanz aus `MapViewHolder` abrufen und direkt aufrufen.
Schlüssel und Initialisierung sind anbieterspezifisch
`MapConductor` übernimmt keine API-Schlüssel. Es übergibt sie direkt in der von jedem Karten-SDK geforderten Form (Android-Manifest, `sdkInitialize` unter iOS, Konfigurationsobjekt im Web). Es gibt auch Anbieter wie `MapLibre`, `Leaflet` und `OpenLayers`, die keine Schlüssel benötigen; in diesem Fall wird nur die Quelle der Kacheln festgelegt.