Skip to content

MapViewComponent

MapConductor provides map provider-specific map view components that serve as the foundation for displaying maps in your application. Each map SDK has its own implementation, but a consistent API interface is maintained across all providers.

MapConductor provides a MapViewContainer component that wraps the MapView provided by the map SDK. MapViewComponent is a conceptual layer; when actually used, it employs the XxxMapView provided by each map SDK (e.g., GoogleMapView, MapBoxView, etc.). MapViewComponent contains controls for managing the MapView. These controls can be manipulated through the MapViewStateInterface.

MapViewContainer Architecture

MapConductor supports multiple map SDKs, each with a dedicated component. Multiple objects (markers, polylines, etc.) are typically placed on a map, so rather than setting event callbacks on individual objects, map and camera callbacks are set on the map provider-specific component, while overlay callbacks are set on each State.

Provider-specific special event callbacks are not yet supported in v1.1.3.

GoogleMapView(
state: GoogleMapViewState,
modifier: Modifier = Modifier,
onMapLoaded: OnMapLoadedHandler? = null,
onMapClick: OnMapEventHandler? = null,
onCameraMoveStart: OnCameraMoveHandler? = null,
onCameraMove: OnCameraMoveHandler? = null,
onCameraMoveEnd: OnCameraMoveHandler? = null,
content: (@Composable () -> Unit)? = null
)

All map view components share the following parameters:

  • modifier: Compose modifier for styling and layout
  • state: Map provider-specific map view state implementation
  • content: Composable content containing map overlays (markers, circles, etc.)
  • onMapLoaded: Called when the map has finished loading
  • onMapClick: Called when the user taps on the map
  • onCameraMoveStart: Called when moveCameraTo(dst, durationMs) begins. Not called when the user moves the map interactively.
  • onCameraMove: Called when the camera displaying the map moves.
  • onCameraMoveEnd: Called when the movement of the camera displaying the map completes.
  • sdkInitialize: SDK-specific initialization process
@Composable
fun GoogleMapsExample() {
val mapViewState = rememberGoogleMapViewState()
GoogleMapView(
state = mapViewState,
onMapClick = { geoPoint ->
println("Map clicked at: ${geoPoint.latitude}, ${geoPoint.longitude}")
}
) {
Marker(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
icon = DefaultIcon(label = "SF"),
extra = "San Francisco",
onClick = { markerState ->
println("Marker clicked: ${markerState.extra}")
}
)
Circle(
center = GeoPoint.fromLatLong(37.7749, -122.4194),
radiusMeters = 1000,
strokeColor = Color.Blue,
fillColor = Color.Blue.copy(alpha = 0.3f)
)
}
}

While specific map components are required for each SDK, you can create provider-independent content:

@Composable
fun MapContent() {
Marker(
position = GeoPoint.fromLatLong(37.7749, -122.4194),
icon = DefaultIcon(label = "Point"),
extra = "Common marker"
)
Circle(
center = GeoPoint.fromLatLong(37.7749, -122.4194),
radiusMeters = 500,
strokeColor = Color.Green,
fillColor = Color.Green.copy(alpha = 0.2f)
)
}
@Composable
fun GoogleMapsScreen() {
val state = rememberGoogleMapViewState()
GoogleMapView(state = state) {
MapContent() // Reusable content
}
}
@Composable
fun MapboxScreen() {
val state = remember { MapboxViewState() }
MapboxMapView(state = state) {
MapContent() // Same content, different map SDK
}
}
@Composable
fun AdvancedMapExample() {
val center = GeoPoint.fromLatLong(37.7749, -122.4194)
val mapViewState = rememberGoogleMapViewState(
cameraPosition = MapCameraPosition(position = center, zoom = 13)
)
var clickedPoint by remember { mutableStateOf<GeoPointInterface?>(null) }
val onMarkerClick: (MarkerState) -> Unit = { markerState ->
println("Marker clicked: ${markerState.extra}")
}
GoogleMapView(
state = mapViewState,
onMapLoaded = {
println("Map loaded successfully")
},
onMapClick = { geoPoint ->
clickedPoint = geoPoint
println("Map clicked at: ${geoPoint.latitude}, ${geoPoint.longitude}")
},
onCameraMoveStart = {
println("Camera move started")
},
onCameraMove = { cameraPosition ->
println("Camera position: ${cameraPosition.position}")
},
onCameraMoveEnd = {
println("Camera move ended")
}
) {
// Show marker and circle
Marker(
position = center,
icon = DefaultIcon(label = "Center", fillColor = Color.Red),
extra = "Center marker",
onClick = onMarkerClick
)
Circle(
center = center,
radiusMeters = 1000,
strokeColor = Color.Blue,
fillColor = Color.Blue.copy(alpha = 0.2f)
)
// Show marker at clicked position
clickedPoint?.let { point ->
Marker(
position = point,
icon = DefaultIcon(label = "Clicked", fillColor = Color.Green),
extra = "Clicked point",
onClick = onMarkerClick
)
}
}
}

While the API is consistent across all map SDKs, there are differences in the following areas:

  • GroundImage: Currently supported on Google Maps and ArcGIS
  • Marker Animation: Available on Google Maps and Mapbox
  • Custom Styling: Each map SDK has different map style options
  • Google Maps: Excellent for general use with great marker performance
  • Mapbox: Optimal for custom styling and large datasets
  • HERE Maps: Optimized for location services integration
  • ArcGIS: Optimal for GIS and enterprise applications

Each map SDK may have different requirements regarding API keys, permissions, and platform setup. Refer to the provider-specific setup documentation for details.

  1. Choose the Right SDK: Select based on your app’s specific needs (styling, performance, features)
  2. Consistent State Management: Use the same state patterns regardless of the map SDK
  3. Reusable Content: Create provider-independent Composable content when possible
  4. Event Handling: Implement comprehensive event handling for better user experience
  5. Error Handling: Always handle initialization failures and provide fallback UI
  6. Performance: Consider custom rendering strategies for large marker sets
  7. Testing: Test your application with multiple map SDKs to ensure compatibility