Unified API
Write your map code once and switch map providers whenever you like. Even if you migrate from Google Maps to Mapbox, you don’t need to rewrite large parts of your codebase.
Unified API
Write your map code once and switch map providers whenever you like. Even if you migrate from Google Maps to Mapbox, you don’t need to rewrite large parts of your codebase.
Optimized for Jetpack Compose
Designed for modern Android development, with an API built specifically around Jetpack Compose.
Multiple Providers Supported
Provides consistent behavior across Google Maps, Mapbox, HERE Maps, ArcGIS, and MapLibre.
Open Source
Open-source under the Apache License 2.0 and developed by the community.
Using MapConductor is simple: you combine rememberXxxxViewState with XxxxView.
The Xxxx part switches between GoogleMap, Mapbox, and other providers.
To switch to Mapbox, just change rememberGoogleMapViewState() to rememberMapboxMapViewState()
and GoogleMapView to MapboxMapView. Everything else stays the same.
| Map SDK | mapViewState hook | MapView composable |
|---|---|---|
| GoogleMaps | rememberGoogleMapViewState | GoogleMapView |
| Mapbox | rememberMapboxViewState | MapboxMapView |
| MapLibre | rememberMapLibreViewState | MapLibreView |
| HERE | rememberHereMapViewState | HereMapView |
| ArcGIS | rememberArcGISMapViewState | ArcGISMapView |
@Composablefun MyMap() { // Initial camera position on the map val targetPosition = GeoPointImpl.fromLatLong(37.7749, -122.419) val initCamera = MapCameraPositionImpl( position = targetPosition, zoom = 12.0, ) // Use this mapViewState to control the visible map state val mapViewState = rememberGoogleMapViewState( cameraPosition = initCamera, )
GoogleMapView( state = mapViewState, onMapClick = { geoPoint -> println("Clicked: ${geoPoint.latitude}, ${geoPoint.longitude}") } ) { Marker( position = targetPosition, icon = DefaultIcon(label = "SF") ) }}
@Composablefun MyMap() { // Initial camera position on the map val targetPosition = GeoPointImpl.fromLatLong(38.911254, -77.033458) val initCamera = MapCameraPositionImpl( position = targetPosition, zoom = 12.0, ) // Use this mapViewState to control the visible map state val mapViewState = rememberMapboxMapViewState( cameraPosition = initCamera, )
MapboxMapView( state = mapViewState, onMapClick = { geoPoint -> println("Clicked: ${geoPoint.latitude}, ${geoPoint.longitude}") } ) { Marker( position = targetPosition, icon = DefaultIcon(label = "WA") ) }}
@Composablefun MyMap() { // Initial camera position on the map val targetPosition = GeoPointImpl.fromLatLong(51.43901, 5.47191) val initCamera = MapCameraPositionImpl( position = targetPosition, zoom = 12.0, ) // Use this mapViewState to control the visible map state val mapViewState = rememberHereMapViewState( cameraPosition = initCamera, )
HereMapView( state = mapViewState, onMapClick = { geoPoint -> println("Clicked: ${geoPoint.latitude}, ${geoPoint.longitude}") } ) { Marker( position = targetPosition, icon = DefaultIcon(label = "EIN") ) }}
| Feature | Google Maps | Mapbox | HERE | ArcGIS | MapLibre |
|---|---|---|---|---|---|
| Map | ✓ | ✓ | ✓ | ✓ | ✓ |
| Marker | ✓ | ✓ | ✓ | ✓ | ✓ |
| Circle | ✓ | ✓ | ✓ | ✓ | ✓ |
| Polyline | ✓ | ✓ | ✓ | ✓ | ✓ |
| Polygon | ✓ | ✓ | ✓ | ✓ | ✓ |
| GroundImage | ✓ | N/A | N/A | N/A | N/A |
When you are ready to add MapConductor to your Android app, start with the Introduction and the Tutorial guides.