### Initialize MapConfiguration on App Startup Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/04_Configuration_and_Initialization.md Example of initializing the `MapConfiguration` with an API key when the application starts. This must be done before rendering any map components. ```kotlin @Composable fun App() { LaunchedEffect(Unit) { // Must be called before any Map components are rendered MapConfiguration.initialize(googleMapsApiKey = "YOUR_API_KEY_HERE") } // Your app content with Map composables } ``` -------------------------------- ### WebMapProperties Usage Example Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/03_Map_Properties_Settings.md Example of initializing WebMapProperties with specific gesture handling, zoom levels, and geographic restrictions. ```kotlin WebMapProperties( gestureHandling = WebMapGesture.GREEDY, disableDoubleClickZoom = false, minZoom = 5f, maxZoom = 18f, restriction = WebMapRestriction( north = 55.0, south = 40.0, east = 30.0, west = 5.0, strictBounds = false ) ) ``` -------------------------------- ### WebUISettings Usage Example Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/03_Map_Properties_Settings.md Example of initializing WebUISettings to enable zoom and map type controls at specific positions. ```kotlin WebUISettings( zoomControl = true, mapTypeControl = true, streetViewControl = false, rotateControl = true, zoomControlPosition = WebControlPosition.RIGHT_CENTER, mapTypeControlPosition = WebControlPosition.TOP_LEFT ) ``` -------------------------------- ### Install Pods and Open Workspace Source: https://github.com/software-mansion/kmp-maps/blob/main/docs/GOOGLE_MAPS_IOS_SETUP.md Navigate to the iosApp directory, update your pod repository, install the pods, and open the generated .xcworkspace file to begin development. ```bash cd iosApp pod repo update pod install open iosApp.xcworkspace ``` -------------------------------- ### Complete App Setup with KMP Maps Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/10_Usage_Examples.md This snippet shows the complete setup for a KMP Maps application, including initializing the maps with an API key and setting up the main application window. Ensure you replace 'YOUR_API_KEY' with your actual Google Maps API key. ```kotlin import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.foundation.layout.* import androidx.compose.material3.* import com.swmansion.kmpmaps.core.Map import com.swmansion.kmpmaps.core.MapConfiguration import org.jetbrains.compose.ui.tooling.preview.Preview @Composable @Preview fun App() { LaunchedEffect(Unit) { // Initialize maps with API key MapConfiguration.initialize(googleMapsApiKey = "YOUR_API_KEY") } MaterialTheme { CompleteMapApplication() } } fun main() = application { Window(title = "KMP Maps") { App() } } ``` -------------------------------- ### Usage Example: AndroidMapProperties Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/03_Map_Properties_Settings.md Example demonstrating how to instantiate `AndroidMapProperties` with custom values for indoor enablement, zoom preferences, and map styling. ```kotlin AndroidMapProperties( isIndoorEnabled = false, minZoomPreference = 5f, maxZoomPreference = 18f, mapStyleOptions = GoogleMapsMapStyleOptions( json = """[{"featureType": "water", "stylers": [{"color": "#0099dd"}]}]""" ) ) ``` -------------------------------- ### Cluster Click Callback Example Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/02_Core_Types.md Example of how to use the onClusterClick callback within ClusterSettings to handle user taps on a cluster. This example logs cluster information and consumes the event. ```kotlin ClusterSettings( enabled = true, onClusterClick = { cluster -> println("Cluster at ${cluster.coordinates} has ${cluster.size} items") false } ) ``` -------------------------------- ### Complete Event Handling Example Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/05_Event_Callbacks.md This composable function demonstrates a comprehensive setup for handling various map events, including camera movements, marker interactions, map clicks, and shape clicks. It updates UI state based on these events and displays information about the selected marker, tapped location, and camera position. It also includes handling for map loading and cluster clicks. ```kotlin import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.unit.dp import com.google.maps.model.CameraPosition import com.google.maps.model.Coordinates import com.softwaremansion.kmp.maps.model.* import com.softwaremansion.kmp.maps.view.Map @Composable fun AdvancedMapScreen() { var selectedMarker by remember { mutableStateOf(null) } var selectedLocation by remember { mutableStateOf(null) } var currentCamera by remember { mutableStateOf(null) } var mapReady by remember { mutableStateOf(false) } var tappedShapes by remember { mutableStateOf>(emptyList()) } Column(modifier = Modifier.fillMaxSize()) { // Status display if (mapReady) { Text("Map is ready") } if (selectedMarker != null) { Text("Selected: ${selectedMarker?.title}") } if (selectedLocation != null) { Text("Tapped at: ${selectedLocation?.latitude}, ${selectedLocation?.longitude}") } Text("Camera: ${currentCamera?.zoom?.let { "Zoom $it" } ?: "Loading..."}") // Map with all event handlers Map( modifier = Modifier .fillMaxWidth() .weight(1f), cameraPosition = CameraPosition( coordinates = Coordinates(50.0, 20.0), zoom = 12f ), markers = listOf( Marker( coordinates = Coordinates(50.0, 20.0), title = "Office" ) ), circles = listOf( Circle( center = Coordinates(50.05, 20.05), radius = 1000f, color = Color(0x4000FF00) ) ), polygons = listOf( Polygon( coordinates = listOf( Coordinates(50.1, 19.9), Coordinates(50.1, 20.1), Coordinates(49.9, 20.1), Coordinates(49.9, 19.9) ), lineWidth = 2f ) ), clusterSettings = ClusterSettings( enabled = true, onClusterClick = { cluster -> println("Cluster: ${cluster.size} items") false // Allow default zoom behavior } ), // Event handlers onCameraMove = { position -> currentCamera = position }, onMarkerClick = { marker -> selectedMarker = marker }, onMarkerDragEnd = { draggedMarker -> selectedMarker = draggedMarker }, onMapClick = { coordinates -> selectedLocation = coordinates }, onMapLongClick = { coordinates -> println("Long press at: $coordinates") }, onCircleClick = { circle -> tappedShapes = tappedShapes + "Circle" }, onPolygonClick = { polygon -> tappedShapes = tappedShapes + "Polygon" }, onPolylineClick = { polyline -> tappedShapes = tappedShapes + "Polyline" }, onPOIClick = { coordinates -> println("POI at: $coordinates") }, onMapLoaded = { mapReady = true } ) // Event history if (tappedShapes.isNotEmpty()) { LazyColumn(modifier = Modifier.height(100.dp)) { items(tappedShapes) { Text("- Tapped: $it") } } } } } ``` -------------------------------- ### MapContentPadding Usage Example Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/03_Map_Properties_Settings.md Illustrates how to set custom padding values for the top, bottom, start, and end of the map content area. ```kotlin MapContentPadding( top = 100f, // Space for header bottom = 150f, // Space for bottom sheet start = 20f, end = 20f ) ``` -------------------------------- ### MapProperties Usage Example Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/03_Map_Properties_Settings.md Demonstrates how to instantiate MapProperties with custom values for various settings. ```kotlin MapProperties( isMyLocationEnabled = true, isTrafficEnabled = true, mapType = MapType.SATELLITE, mapTheme = MapTheme.DARK, contentPadding = MapContentPadding( top = 64f, bottom = 128f, start = 16f, end = 16f ) ) ``` -------------------------------- ### Create a Simple Marker Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/02_Core_Types.md Example of creating a basic marker with coordinates and a title. ```kotlin // Simple marker Marker( coordinates = Coordinates(50.0, 20.0), title = "Office Location" ) ``` -------------------------------- ### Basic Map Implementation Source: https://github.com/software-mansion/kmp-maps/blob/main/README.md A basic example of how to implement a map with properties, UI settings, camera position, markers, and click listeners. ```kotlin @Composable fun MyMapScreen() { Map( modifier = Modifier.fillMaxSize(), properties = MapProperties( isMyLocationEnabled = true, mapType = MapType.NORMAL, ), uiSettings = MapUISettings( myLocationButtonEnabled = true, compassEnabled = true ), cameraPosition = CameraPosition( coordinates = Coordinates(latitude = 50.0619, longitude = 19.9373), zoom = 13f ), markers = listOf( Marker( coordinates = Coordinates(latitude = 50.0486, longitude = 19.9654), title = "Software Mansion", androidSnippet = "Software house" ) ), onMarkerClick = { marker -> println("Marker clicked: ${marker.title}") }, onMapClick = { coordinates -> println("Map clicked at: ${coordinates.latitude}, ${coordinates.longitude}") } ) } ``` -------------------------------- ### Example LineStringStyle Usage Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/02_Core_Types.md Demonstrates how to construct a LineStringStyle with a custom pattern including dashes, gaps, and dots. ```kotlin LineStringStyle( lineWidth = 5f, lineColor = Color.Blue, pattern = listOf( StrokePatternItem.Dash(lengthPx = 10f), StrokePatternItem.Gap(lengthPx = 5f), StrokePatternItem.Dot ) ) ``` -------------------------------- ### Custom Cluster Rendering Example Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/02_Core_Types.md Demonstrates custom UI rendering for clusters on mobile using the clusterContent lambda in ClusterSettings. This example creates a blue circular background with the cluster size as white text. ```kotlin ClusterSettings( enabled = true, onClusterClick = { cluster -> println("Clicked cluster with ${cluster.size} markers") true // Consume the event }, clusterContent = { cluster -> Box( modifier = Modifier .background(Color.Blue, CircleShape) .size(40.dp), contentAlignment = Alignment.Center ) { Text( text = cluster.size.toString(), color = Color.White, fontWeight = FontWeight.Bold ) } } ) ``` -------------------------------- ### Customizing MapUISettings Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/03_Map_Properties_Settings.md Example of how to instantiate MapUISettings with specific UI elements enabled or disabled. Useful for tailoring the user experience. ```kotlin MapUISettings( compassEnabled = true, myLocationButtonEnabled = true, scrollEnabled = true, zoomEnabled = true, rotateEnabled = false // Disable rotation ) ``` -------------------------------- ### Usage Example: AndroidCameraPosition Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/03_Map_Properties_Settings.md Example showing how to apply Android-specific camera orientation settings, including bearing and tilt, within a `CameraPosition` object. ```kotlin CameraPosition( coordinates = Coordinates(50.0, 20.0), zoom = 13f, androidCameraPosition = AndroidCameraPosition( bearing = 45f, // Rotated 45 degrees tilt = 30f // Tilted 30 degrees ) ) ``` -------------------------------- ### Initialize KCEF for Desktop Map Engine Source: https://github.com/software-mansion/kmp-maps/blob/main/docs/INSTALLATION_SETUP.md Initialize the KCEF (Kotlin Chromium Embedded Framework) library before displaying the map on desktop platforms. This example shows basic initialization with a specified install directory and error handling. ```kotlin import dev.datlag.kcef.KCEF import java.io.File import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext fun main() = application { Window(title = "KMP Maps - Desktop", onCloseRequest = ::exitApplication) { var initialized by remember { mutableStateOf(false) } LaunchedEffect(Unit) { withContext(Dispatchers.IO) { KCEF.init( builder = { installDir(File("kcef-bundle")) progress { onInitialized { initialized = true } } settings { noSandbox = true } }, onError = { it?.printStackTrace() }, ) } } if (initialized) { App() } else { Text("Initializing Map Engine...") } } } ``` -------------------------------- ### Generate Dummy Framework for CocoaPods Source: https://github.com/software-mansion/kmp-maps/blob/main/docs/GOOGLE_MAPS_IOS_SETUP.md Run this Gradle task to generate a dummy framework, which is necessary for CocoaPods to read the KMP-generated podspec before the initial installation. ```bash ./gradlew :shared:generateDummyFramework ``` -------------------------------- ### Create a Marker with Android Options Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/02_Core_Types.md Example of creating a marker with specific Android marker options, including snippet, draggable status, and anchor. ```kotlin // Marker with Android-specific options Marker( coordinates = Coordinates(50.0, 20.0), title = "Office", androidSnippet = "Software house", androidMarkerOptions = AndroidMarkerOptions( draggable = true, anchor = GoogleMapsAnchor(x = 0.5f, y = 1.0f) ) ) ``` -------------------------------- ### Usage Example: AndroidMarkerOptions Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/03_Map_Properties_Settings.md Demonstrates how to configure `AndroidMarkerOptions` for a marker, setting its anchor, making it draggable, adding a snippet, and defining its z-index. ```kotlin Marker( coordinates = Coordinates(50.0, 20.0), title = "Office", androidMarkerOptions = AndroidMarkerOptions( anchor = GoogleMapsAnchor(x = 0.5f, y = 1.0f), draggable = true, snippet = "Software Mansion", zIndex = 1f ) ) ``` -------------------------------- ### Android Core Module Setup (API Key) Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/08_Platform_Specific_Variants.md Configure your AndroidManifest.xml with your Google Maps API key and location permissions. ```xml ``` -------------------------------- ### Code Examples Availability Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/INDEX.txt This section lists the types of code examples available for the KMP Maps library, demonstrating various features and usage patterns. ```APIDOC ## Code Examples Complete examples provided for: - Basic map initialization and rendering - Marker placement and interaction - Overlay shapes (circles, polygons, polylines) - GeoJSON layer rendering with styling - Event callback handling - Custom marker content (mobile and web) - Marker clustering - Multi-platform patterns - Theme configuration - Full application structure ``` -------------------------------- ### Display Multiple Markers with Click Callbacks Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/10_Usage_Examples.md This example shows how to display multiple markers and handle user interactions, such as marker clicks. The `onMarkerClick` callback allows you to update the UI or perform actions based on the selected marker. ```kotlin import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.weight import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import com.google.maps.android.compose.CameraPosition import com.google.maps.android.compose.Coordinates import com.google.maps.android.compose.Map import com.google.maps.android.compose.Marker @Composable fun MapWithMultipleMarkers() { var selectedMarker by remember { mutableStateOf(null) } val markers = listOf( Marker( coordinates = Coordinates(50.0, 20.0), title = "Office", androidSnippet = "Our main office" ), Marker( coordinates = Coordinates(50.1, 20.1), title = "Warehouse", androidSnippet = "Distribution center" ), Marker( coordinates = Coordinates(50.2, 20.2), title = "Store", androidSnippet = "Retail location" ) ) Column(modifier = Modifier.fillMaxSize()) { if (selectedMarker != null) { Text( "Selected: ${selectedMarker?.title}", modifier = Modifier.padding(8.dp), fontWeight = FontWeight.Bold ) } Map( modifier = Modifier .fillMaxWidth() .weight(1f), cameraPosition = CameraPosition( coordinates = Coordinates(50.1, 20.1), zoom = 11f ), markers = markers, onMarkerClick = { selectedMarker = it } ) } } ``` -------------------------------- ### Creating GeoJsonLayer with PointStyle Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/07_GeoJSON_Layers.md Example of how to instantiate a GeoJsonLayer with custom point styling. This snippet demonstrates setting alpha, title, snippet, rotation, and anchor points for markers. ```kotlin GeoJsonLayer( geoJson = pointsGeoJson, pointStyle = PointStyle( alpha = 0.8f, pointTitle = "Points of Interest", snippet = "Tap for details", rotation = 0f, anchorU = 0.5f, anchorV = 1.0f ) ) ``` -------------------------------- ### Usage Guide by Task Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/INDEX.txt This section outlines how to accomplish specific tasks using the KMP Maps library, referencing the relevant documentation files for each. ```APIDOC ## Usage Guide by Task - **Render map**: 01_Map_Component.md → 10_Usage_Examples.md - **Add markers**: 02_Core_Types.md → 10_Usage_Examples.md - **Handle clicks**: 05_Event_Callbacks.md - **Custom markers**: 06_Custom_Content_and_Markers.md - **GeoJSON data**: 07_GeoJSON_Layers.md - **Setup Google Maps**: 04_Configuration_and_Initialization.md - **All types**: 09_Complete_API_Reference.md ``` -------------------------------- ### Use CameraPosition for Map View Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/02_Core_Types.md Examples demonstrating how to set the map's view to a specific point or region using CameraPosition. ```kotlin // Zoom to specific point val cityView = CameraPosition( coordinates = Coordinates(latitude = 52.2297, longitude = 21.0122), zoom = 12f ) // Zoom to specific region val regionView = CameraPosition( bounds = MapBounds( northeast = Coordinates(52.5, 21.5), southwest = Coordinates(52.0, 20.5) ) ) ``` -------------------------------- ### Testing Map Integration with KMP Maps Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/10_Usage_Examples.md These are pseudo-code examples for testing map integration. They demonstrate how to verify marker properties, camera positions, and clustering configurations. These tests assume the existence of Marker, Coordinates, CameraPosition, and Cluster classes. ```kotlin // Example test for map integration (pseudo-code) @Test fun testMapRendering() { val testMarker = Marker( coordinates = Coordinates(50.0, 20.0), title = "Test Marker" ) // Verify marker properties assertEquals(50.0, testMarker.coordinates.latitude) assertEquals(20.0, testMarker.coordinates.longitude) assertEquals("Test Marker", testMarker.title) } ``` ```kotlin @Test fun testCameraPosition() { val position = CameraPosition( coordinates = Coordinates(50.0, 20.0), zoom = 13f ) // Verify camera position is valid assertNotNull(position.coordinates) assertEquals(13f, position.zoom) } ``` ```kotlin @Test fun testClusteringConfiguration() { val cluster = Cluster( coordinates = Coordinates(50.0, 20.0), size = 5, items = listOf() ) assertEquals(5, cluster.size) assertEquals(50.0, cluster.coordinates.latitude) } ``` -------------------------------- ### iOS Location Permission Handling Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/08_Platform_Specific_Variants.md Example of how to handle location permissions using LocationPermissionHandler in an iOS environment. ```kotlin val locationPermissionHandler = remember { LocationPermissionHandler() } LaunchedEffect(Unit) { locationPermissionHandler.setOnPermissionChanged { hasLocationPermission = locationPermissionHandler.checkPermission() } } ``` -------------------------------- ### Basic Polygon Styling Configuration Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/07_GeoJSON_Layers.md Example of how to instantiate and configure PolygonStyle for use with a GeoJsonLayer. This sets a semi-transparent green fill and a green border. ```kotlin GeoJsonLayer( geoJson = polygonsGeoJson, polygonStyle = PolygonStyle( fillColor = Color(0x4400FF00), // Semi-transparent green strokeColor = Color.Green, strokeWidth = 2f ) ) ``` -------------------------------- ### Complete Map Application Example Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/10_Usage_Examples.md This snippet shows a full Jetpack Compose application integrating KMP Maps. It includes map display, traffic layer control, custom marker rendering, and handling user interactions like marker clicks and map taps. Ensure all necessary Compose and KMP Maps dependencies are included. ```kotlin @Composable fun CompleteMapApplication() { var showTraffic by remember { mutableStateOf(true) } var selectedMarker by remember { mutableStateOf(null) } var userLocation by remember { mutableStateOf(null) } var cameraPosition by remember { mutableStateOf( CameraPosition( coordinates = Coordinates(50.0, 20.0), zoom = 12f ) ) } val sampleMarkers = remember { listOf( Marker( coordinates = Coordinates(50.0, 20.0), title = "Office", contentId = "office" ), Marker( coordinates = Coordinates(50.1, 20.1), title = "Warehouse", contentId = "warehouse" ) ) } Column(modifier = Modifier.fillMaxSize()) { // Header with controls Surface( modifier = Modifier .fillMaxWidth() .padding(8.dp), shape = RoundedCornerShape(8.dp), color = MaterialTheme.colorScheme.surface, shadowElevation = 4.dp ) { Column(modifier = Modifier.padding(8.dp)) { Row( modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween, verticalAlignment = Alignment.CenterVertically ) { Text( "Map Explorer", style = MaterialTheme.typography.headlineSmall, modifier = Modifier.weight(1f) ) Checkbox( checked = showTraffic, onCheckedChange = { showTraffic = it } ) Text("Traffic") } if (selectedMarker != null) { Text( "Selected: ${selectedMarker?.title}", style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.primary ) } } } // Map Map( modifier = Modifier .fillMaxWidth() .weight(1f), cameraPosition = cameraPosition, properties = MapProperties( isMyLocationEnabled = true, isTrafficEnabled = showTraffic, isBuildingEnabled = true, mapType = MapType.NORMAL ), uiSettings = MapUISettings( compassEnabled = true, myLocationButtonEnabled = true, zoomEnabled = true, scrollEnabled = true ), markers = sampleMarkers, customMarkerContent = mapOf( "office" to { marker -> Box( modifier = Modifier .background(Color.Blue, RoundedCornerShape(4.dp)) .padding(4.dp) ) { Text( marker.title ?: "Marker", color = Color.White, fontSize = 10.sp ) } }, "warehouse" to { marker -> Icon( imageVector = Icons.Default.HomeWork, contentDescription = marker.title, tint = Color.Orange, modifier = Modifier.size(32.dp) ) } ), onMarkerClick = { marker -> selectedMarker = marker }, onMapClick = { coordinates -> userLocation = coordinates }, onMapLoaded = { println("Map loaded and ready") } ) // Info panel if (userLocation != null) { Surface( modifier = Modifier .fillMaxWidth() .padding(8.dp), shape = RoundedCornerShape(8.dp), color = MaterialTheme.colorScheme.secondaryContainer ) { Text( "Clicked: ${userLocation?.latitude?.toInt()}, ${userLocation?.longitude?.toInt()}", modifier = Modifier.padding(8.dp), style = MaterialTheme.typography.bodySmall ) } } } } ``` -------------------------------- ### Create a Marker with Custom Content ID Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/02_Core_Types.md Example of creating a marker that references custom content using a content ID. ```kotlin // Marker with custom content Marker( coordinates = Coordinates(50.0, 20.0), title = "Custom", contentId = "my_custom_marker" ) ``` -------------------------------- ### Display Routes with Polylines and Markers Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/10_Usage_Examples.md Shows how to draw a route using a polyline and mark the start and end points with markers. Polylines connect a series of coordinates to form a line on the map. ```kotlin import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import com.softwaremansion.kmp.maps.CameraPosition import com.softwaremansion.kmp.maps.Coordinates import com.softwaremansion.kmp.maps.Map import com.softwaremansion.kmp.maps.Marker import com.softwaremansion.kmp.maps.Polyline @Composable fun RoutePolylines() { val route = listOf( Coordinates(50.0, 20.0), Coordinates(50.05, 20.05), Coordinates(50.1, 20.0), Coordinates(50.15, 20.05) ) Map( modifier = Modifier.fillMaxSize(), cameraPosition = CameraPosition( coordinates = Coordinates(50.075, 20.025), zoom = 11f ), polylines = listOf( Polyline( coordinates = route, width = 4f, lineColor = Color.Blue ) ), markers = listOf( Marker( coordinates = route.first(), title = "Start" ), Marker( coordinates = route.last(), title = "End" ) ) ) } ``` -------------------------------- ### Android Location Permission Handling Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/08_Platform_Specific_Variants.md Example of remembering and requesting fine location permission using Accompanist's rememberPermissionState and LaunchedEffect. ```kotlin val locationPermissionState = rememberPermissionState( Manifest.permission.ACCESS_FINE_LOCATION ) LaunchedEffect(properties.isMyLocationEnabled) { if (properties.isMyLocationEnabled && !locationPermissionState.status.isGranted) { locationPermissionState.launchPermissionRequest() } } ``` -------------------------------- ### Desktop KCEF Initialization and Map Configuration Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/04_Configuration_and_Initialization.md Initialize KCEF and configure Google Maps API key before rendering map components on Desktop (JVM). This setup is crucial for desktop map rendering using KCEF. ```kotlin import dev.datlag.kcef.KCEF import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext fun main() = application { Window(title = "KMP Maps") { var initialized by remember { mutableStateOf(false) } LaunchedEffect(Unit) { withContext(Dispatchers.IO) { KCEF.init(builder = { // Customize KCEF if needed }, onError = { error -> error.printStackTrace() }, onRestartRequired = { // Handle restart if needed }) initialized = true } } if (initialized) { MapConfiguration.initialize( googleMapsApiKey = "YOUR_DESKTOP_API_KEY" ) // Render Map components MyMapScreen() } else { Text("Loading maps...") } } } ``` -------------------------------- ### Initialize Map on App Startup Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/00_README.md Initialize the MapConfiguration with your Google Maps API key when your application starts. This is typically done within a `LaunchedEffect` in your main composable. ```kotlin @Composable fun App() { LaunchedEffect(Unit) { MapConfiguration.initialize(googleMapsApiKey = "YOUR_KEY") } // Render Map } ``` -------------------------------- ### Applying LineStringStyle to GeoJsonLayer Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/07_GeoJSON_Layers.md Example of creating a GeoJsonLayer with custom LineString styling, including line width, color, and a pattern of dashes, gaps, and dots. ```kotlin GeoJsonLayer( geoJson = routesGeoJson, lineStringStyle = LineStringStyle( lineWidth = 4f, lineColor = Color.Blue, pattern = listOf( StrokePatternItem.Dash(lengthPx = 10f), StrokePatternItem.Gap(lengthPx = 5f), StrokePatternItem.Dot ) ) ) ``` -------------------------------- ### Update Map Elements Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/00_README.md Manage and update map elements like markers by using state management. This example shows how to update markers and handle marker clicks. ```kotlin var markers by remember { mutableStateOf(initialMarkers) } Map( markers = markers, onMarkerClick = { clicked -> markers = markers.map { if (it == clicked) it.copy(/* update */) else it } } ) ``` -------------------------------- ### Build MapConfiguration with API Key Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/04_Configuration_and_Initialization.md Demonstrates setting up maps by initializing `MapConfiguration` with an API key retrieved from a `remember` block. ```kotlin @Composable fun setupMaps() { val apiKey = remember { "your-api-key-from-buildconfig" } LaunchedEffect(Unit) { MapConfiguration.initialize(googleMapsApiKey = apiKey) } } ``` -------------------------------- ### Using Default and Custom Markers Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/06_Custom_Content_and_Markers.md Demonstrates creating markers with default content (pin icon) and custom content using `contentId`. Ensure custom `contentId` values exist in `customMarkerContent`. ```kotlin Marker( coordinates = Coordinates(50.0, 20.0), title = "Simple Marker" // contentId = null (default) ) // Uses custom content Marker( coordinates = Coordinates(50.0, 20.0), title = "Custom Marker", contentId = "my_custom" // Must exist in customMarkerContent ) ``` -------------------------------- ### Desktop Web Gesture Handling Configuration Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/08_Platform_Specific_Variants.md Configure gesture handling for web-based maps on desktop, including enabling greedy gesture handling and double-click zoom. ```kotlin WebMapProperties( gestureHandling = WebMapGesture.GREEDY, disableDoubleClickZoom = false ) ``` -------------------------------- ### Set Google Maps Anchor Usage Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/02_Core_Types.md Example of how to use the GoogleMapsAnchor type to set the anchor for an Android marker. This positions the marker on the map. ```kotlin AndroidMarkerOptions( anchor = GoogleMapsAnchor(x = 0.5f, y = 1.0f) // Bottom-center ) ``` -------------------------------- ### Basic Custom Marker with Compose Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/06_Custom_Content_and_Markers.md Demonstrates how to define custom marker content using Compose Composables for mobile platforms. This includes defining markers with specific content IDs and providing the corresponding Composable functions in the `customMarkerContent` map. ```kotlin @Composable fun MapWithCustomMarkers() { Map( modifier = Modifier.fillMaxSize(), cameraPosition = CameraPosition( coordinates = Coordinates(50.0, 20.0), zoom = 13f ), markers = listOf( Marker( coordinates = Coordinates(50.0, 20.0), title = "Office", contentId = "office_marker" ), Marker( coordinates = Coordinates(50.1, 20.1), title = "Warehouse", contentId = "warehouse_marker" ) ), customMarkerContent = mapOf( "office_marker" to { marker -> Box( modifier = Modifier .background(Color.Blue, RoundedCornerShape(8.dp)) .padding(8.dp), contentAlignment = Alignment.Center ) { Column( horizontalAlignment = Alignment.CenterHorizontally ) { Icon( imageVector = Icons.Default.Business, contentDescription = "Office", tint = Color.White, modifier = Modifier.size(24.dp) ) Text( text = marker.title ?: "Marker", color = Color.White, fontSize = 10.sp ) } } }, "warehouse_marker" to { marker -> Box( modifier = Modifier .background(Color.Orange, RoundedCornerShape(8.dp)) .padding(8.dp) ) { Icon( imageVector = Icons.Default.Warehouse, contentDescription = "Warehouse", tint = Color.White, modifier = Modifier.size(24.dp) ) } } ) ) } ``` -------------------------------- ### Map with Multiple Overlays Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/01_Map_Component.md Demonstrates how to add various graphical overlays to the map, including circles, polygons, and polylines. It also includes callbacks for handling clicks on circles and polygons. ```kotlin import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import com.swmansion.kmpmaps.CameraPosition import com.swmansion.kmpmaps.Circle import com.swmansion.kmpmaps.Coordinates import com.swmansion.kmpmaps.Map import com.swmansion.kmpmaps.Marker import com.swmansion.kmpmaps.Polygon import com.swmansion.kmpmaps.Polyline @Composable fun MapWithOverlays() { val center = Coordinates(latitude = 50.0619, longitude = 19.9373) Map( modifier = Modifier.fillMaxSize(), cameraPosition = CameraPosition( coordinates = center, zoom = 14f ), markers = listOf( Marker( coordinates = center, title = "Center Point" ) ), circles = listOf( Circle( center = center, radius = 500f, color = Color(0x40FF0000), lineColor = Color.Red, lineWidth = 2f ) ), polygons = listOf( Polygon( coordinates = listOf( Coordinates(50.0, 19.9), Coordinates(50.1, 19.9), Coordinates(50.1, 20.0), Coordinates(50.0, 20.0), ), lineWidth = 2f, color = Color(0x4000FF00), lineColor = Color.Green ) ), polylines = listOf( Polyline( coordinates = listOf( Coordinates(50.0, 19.9), Coordinates(50.05, 19.95), Coordinates(50.1, 20.0), ), width = 3f, lineColor = Color.Blue ) ), onCircleClick = { circle -> println("Circle clicked: radius = ${circle.radius}") }, onPolygonClick = { polygon -> println("Polygon clicked: ${polygon.coordinates.size} vertices") } ) } ``` -------------------------------- ### GeoJSON Coordinate Order Example Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/07_GeoJSON_Layers.md GeoJSON uses [longitude, latitude] ordering, which is reversed from the KMP Maps Coordinates class. Pay attention to this when converting between formats. ```kotlin // GeoJSON format: [longitude, latitude] val geoJsonPoint = "{"type": "Point", "coordinates": [19.9373, 50.0619]}" // Coordinates class: latitude, longitude val coordinates = Coordinates(latitude = 50.0619, longitude = 19.9373) ``` -------------------------------- ### Apply Google Maps Custom Styling Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/02_Core_Types.md Example of applying custom map styles to an Android map. The 'json' field accepts a string containing MapStyle JSON. ```kotlin AndroidMapProperties( mapStyleOptions = GoogleMapsMapStyleOptions( json = "[{"featureType": "water", "stylers": [{"color": "#0099dd"}]}]" ) ) ``` -------------------------------- ### Marker Clustering with Custom Click Handling Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/10_Usage_Examples.md Demonstrates how to enable marker clustering and handle cluster clicks. Customize the `onClusterClick` lambda to manage cluster interactions, returning `false` to allow default zoom behavior. ```kotlin import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.Text import androidx.compose.runtime.* import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import io.github.ajoz88.kmp.maps.model.CameraPosition import io.github.ajoz88.kmp.maps.model.Cluster import io.github.ajoz88.kmp.maps.model.ClusterSettings import io.github.ajoz88.kmp.maps.model.Coordinates import io.github.ajoz88.kmp.maps.model.Marker import io.github.ajoz88.kmp.maps.Map @Composable fun ClusteredMarkersMap() { val markers = remember { (0..100).map { Marker( coordinates = Coordinates( latitude = 50.0 + (Math.random() * 0.2), longitude = 20.0 + (Math.random() * 0.2) ), title = "Marker $it" ) } } var selectedCluster by remember { mutableStateOf(null) } Map( modifier = Modifier.fillMaxSize(), cameraPosition = CameraPosition( coordinates = Coordinates(50.1, 20.1), zoom = 10f ), markers = markers, clusterSettings = ClusterSettings( enabled = true, onClusterClick = { cluster -> selectedCluster = cluster println("Cluster: ${cluster.size} items") false // Allow default zoom behavior } ) ) if (selectedCluster != null) { Text( "Selected cluster with ${selectedCluster?.size} markers", modifier = Modifier.padding(8.dp) ) } } ``` -------------------------------- ### iOS Apple Maps Composable Function Signature Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/08_Platform_Specific_Variants.md Signature for the core Apple Maps implementation using MKMapView. Requires specific setup in Info.plist for location permissions. ```kotlin @OptIn(ExperimentalForeignApi::class) @Composable public actual fun Map( modifier: Modifier, cameraPosition: CameraPosition?, properties: MapProperties, uiSettings: MapUISettings, // ... other parameters ) ``` -------------------------------- ### Map with Markers and Callbacks Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/01_Map_Component.md Renders a map with multiple markers and enables user interaction. It configures the map to show the user's location and a button to center it. The `onMarkerClick` callback is used to handle marker selections. ```kotlin import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import com.swmansion.kmpmaps.CameraPosition import com.swmansion.kmpmaps.Coordinates import com.swmansion.kmpmaps.Map import com.swmansion.kmpmaps.MapProperties import com.swmansion.kmpmaps.MapUISettings import com.swmansion.kmpmaps.Marker @Composable fun MapWithMarkers() { val markers = listOf( Marker( coordinates = Coordinates(latitude = 50.0486, longitude = 19.9654), title = "Software Mansion", androidSnippet = "Software house in Kraków" ), Marker( coordinates = Coordinates(latitude = 52.2297, longitude = 21.0122), title = "Warsaw", androidSnippet = "Capital of Poland" ) ) var selectedMarker by remember { mutableStateOf(null) } Map( modifier = Modifier.fillMaxSize(), cameraPosition = CameraPosition( coordinates = Coordinates(latitude = 51.0, longitude = 20.0), zoom = 6f ), markers = markers, properties = MapProperties(isMyLocationEnabled = true), uiSettings = MapUISettings(myLocationButtonEnabled = true), onMarkerClick = { marker -> selectedMarker = marker println("Clicked: ${marker.title}") } ) } ``` -------------------------------- ### Map with GeoJSON Layers Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/01_Map_Component.md Integrates GeoJSON data to display features on the map, such as points with custom styling. This example shows how to load a GeoJSON string and define a point style for features. ```kotlin import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import com.swmansion.kmpmaps.CameraPosition import com.swmansion.kmpmaps.Coordinates import com.swmansion.kmpmaps.GeoJsonLayer import com.swmansion.kmpmaps.Map import com.swmansion.kmpmaps.PointStyle @Composable fun MapWithGeoJson() { val geoJsonString = """{ "type": "FeatureCollection", "features": [ { "type": "Feature", "geometry": { "type": "Point", "coordinates": [19.9373, 50.0619] }, "properties": { "title": "Software Mansion" } } ] }""" Map( modifier = Modifier.fillMaxSize(), cameraPosition = CameraPosition( coordinates = Coordinates(latitude = 50.0619, longitude = 19.9373), zoom = 13f ), geoJsonLayers = listOf( GeoJsonLayer( geoJson = geoJsonString, pointStyle = PointStyle( pointTitle = "Office", snippet = "Software Mansion offices" ) ) ) ) } ``` -------------------------------- ### Android Marker Clustering Implementation Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/08_Platform_Specific_Variants.md Demonstrates how to use the Clustering composable for marker clustering, including custom cluster UI and click handling. ```kotlin Clustering( items = markers, clusterContent = { cluster -> // Custom cluster UI or default }, onClusterClick = { cluster -> // Handle cluster click } ) ``` -------------------------------- ### Desktop Dependencies (JVM) Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/04_Configuration_and_Initialization.md Add the compose-webview-multiplatform and kcef dependencies to your JVM module's build.gradle.kts file for desktop map rendering. ```kotlin jvmMain { dependencies { implementation("com.kevinnzou:compose-webview-multiplatform:1.7.0") implementation("dev.datlag.kcef:kcef:0.2.5") } } ``` -------------------------------- ### MapContentPadding Data Class Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/09_Complete_API_Reference.md Defines padding around the map content, specified in pixels for top, bottom, start, and end edges. Useful for adjusting map view when UI elements overlap. ```kotlin public data class MapContentPadding( val top: Float = 0f, val bottom: Float = 0f, val start: Float = 0f, val end: Float = 0f, ) ``` -------------------------------- ### Initialize Google Maps API Key (Version 0.8.0+) Source: https://github.com/software-mansion/kmp-maps/blob/main/docs/GOOGLE_MAPS_IOS_SETUP.md Globally initialize your Google Maps API key using MapConfiguration.initialize before rendering any maps. Replace 'YOUR_API_KEY' with your actual key. ```kotlin MapConfiguration.initialize(googleMapsApiKey = "YOUR_API_KEY") ``` -------------------------------- ### Use ARGB Colors with Transparency Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/07_GeoJSON_Layers.md When defining colors for GeoJSON layers, use the ARGB format (Alpha, Red, Green, Blue) to control transparency. This example shows how to create a semi-transparent red fill color. ```kotlin PolygonStyle( fillColor = Color(0x44FF0000), // 26% opaque red strokeColor = Color.Red, strokeWidth = 2f ) ``` -------------------------------- ### Initialize MapConfiguration using BuildConfig Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/04_Configuration_and_Initialization.md Recommended approach for initializing `MapConfiguration` using an API key defined in `BuildConfig`. Ensure the `buildConfigField` is set in your Gradle build file for debug and release types. ```kotlin @Composable fun App() { LaunchedEffect(Unit) { MapConfiguration.initialize(googleMapsApiKey = BuildConfig.MAPS_API_KEY) } } ``` -------------------------------- ### API Reference Overview Source: https://github.com/software-mansion/kmp-maps/blob/main/_autodocs/INDEX.txt This section provides a high-level overview of the API coverage, including documented composables, data types, callbacks, configuration objects, and enumerations. ```APIDOC ## API Coverage ### Composables Documented - Map (core and googlemaps modules) - Platform-specific implementations ### Data Types Documented (50+) - Geographic: Coordinates, MapBounds, CameraPosition - Overlays: Marker, Circle, Polygon, Polyline, Cluster - Configuration: MapProperties, MapUISettings, ClusterSettings - GeoJSON: GeoJsonLayer, PointStyle, PolygonStyle, LineStringStyle - Platform-specific: AndroidMapProperties, IosMapProperties, WebMapProperties - Supporting: GoogleMapsAnchor, GoogleMapsMapStyleOptions, etc. ### Callbacks Documented (8+) - onCameraMove - onMarkerClick - onMarkerDragEnd - onCircleClick - onPolygonClick - onPolylineClick - onMapClick / onMapLongClick - onPOIClick - onMapLoaded - ClusterSettings.onClusterClick ### Configuration Objects - MapConfiguration (singleton) - All property and settings classes ### Enumerations Documented (5+) - MapTheme - MapType - MapPlatform - AppleMapsPointOfInterestCategory (77 values) - WebMapGesture - WebControlPosition ```