DEV Community

myougaTheAxo
myougaTheAxo

Posted on

Google Maps + Compose Advanced Guide — Clustering/Custom Markers/Geocoding

What You'll Learn

Google Maps + Compose応用(Marker Clustering、Custom Markers、ジオコーディング、Route Drawing、ヒートマップ)を解説します。


Setup

dependencies {
    implementation("com.google.maps.android:maps-compose:6.2.1")
    implementation("com.google.maps.android:maps-compose-utils:6.2.1")
    implementation("com.google.android.gms:play-services-maps:19.0.0")
}
Enter fullscreen mode Exit fullscreen mode

Custom Markers

@Composable
fun CustomMarkerMap(spots: List<Spot>) {
    val cameraPositionState = rememberCameraPositionState {
        position = CameraPosition.fromLatLngZoom(
            LatLng(35.6812, 139.7671), 12f // 東京
        )
    }

    GoogleMap(
        modifier = Modifier.fillMaxSize(),
        cameraPositionState = cameraPositionState
    ) {
        spots.forEach { spot ->
            MarkerComposable(
                keys = arrayOf(spot.id),
                state = MarkerState(position = LatLng(spot.lat, spot.lng))
            ) {
                // ComposeでCustom MarkersUI
                Card(
                    colors = CardDefaults.cardColors(
                        containerColor = MaterialTheme.colorScheme.primaryContainer
                    ),
                    shape = RoundedCornerShape(8.dp)
                ) {
                    Text(
                        spot.name,
                        Modifier.padding(horizontal = 8.dp, vertical = 4.dp),
                        style = MaterialTheme.typography.labelSmall
                    )
                }
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Marker Clustering

@Composable
fun ClusteredMap(items: List<SpotClusterItem>) {
    val cameraPositionState = rememberCameraPositionState()

    GoogleMap(
        modifier = Modifier.fillMaxSize(),
        cameraPositionState = cameraPositionState
    ) {
        Clustering(
            items = items,
            onClusterClick = { cluster ->
                // クラスタクリック: ズームイン
                cameraPositionState.move(
                    CameraUpdateFactory.newLatLngZoom(cluster.position, 15f)
                )
                true
            },
            onClusterItemClick = { item ->
                // 個別マーカークリック
                false
            },
            clusterContent = { cluster ->
                Box(
                    Modifier.size(40.dp).background(
                        MaterialTheme.colorScheme.primary, CircleShape
                    ),
                    contentAlignment = Alignment.Center
                ) {
                    Text("${cluster.size}", color = Color.White, fontWeight = FontWeight.Bold)
                }
            }
        )
    }
}

data class SpotClusterItem(
    val spot: Spot,
    val itemPosition: LatLng = LatLng(spot.lat, spot.lng),
    val itemTitle: String = spot.name
) : ClusterItem {
    override fun getPosition() = itemPosition
    override fun getTitle() = itemTitle
    override fun getSnippet() = spot.description
    override fun getZIndex() = 0f
}
Enter fullscreen mode Exit fullscreen mode

Polyline (Route Drawing)

@Composable
fun RouteMap(routePoints: List<LatLng>) {
    val cameraPositionState = rememberCameraPositionState()

    GoogleMap(
        modifier = Modifier.fillMaxSize(),
        cameraPositionState = cameraPositionState
    ) {
        Polyline(
            points = routePoints,
            color = MaterialTheme.colorScheme.primary,
            width = 8f,
            pattern = listOf(Dot(), Gap(10f))
        )

        if (routePoints.isNotEmpty()) {
            Marker(state = MarkerState(routePoints.first()), title = "出発")
            Marker(state = MarkerState(routePoints.last()), title = "到着")
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Summary

機能 API
Custom Markers MarkerComposable
クラスタリング Clustering
Route Drawing Polyline
円/多角形 Circle / Polygon
カメラ操作 CameraPositionState
  • MarkerComposableでComposeウィジェットをマーカーに
  • Clusteringで大量マーカーをグループ化
  • Polylineでルートや経路を描画
  • maps-composeでGoogle MapsをCompose完全統合

8種類のAndroidAppTemplates(MapsIntegration Support)を公開しています。

Template ListGumroad

Related Articles:


Ready-Made Android App Templates

8 production-ready Android app templates with Jetpack Compose, MVVM, Hilt, and Material 3.

Browse templatesGumroad

Top comments (0)