MapComposeにMarkerを動的に追加する

# JetpackCompose+MapComposeにMarkerを動的に追加する（ついでに地図座標も取得するよ）
[前回](https://qiita.com/jozuko_dev/items/666b327c5df02ae7aa2a)は、MapComposeを表示しました。
今回は、このMapComposeにMarkerを動的に追加していこうと思います。

MapComposeの下にボタンをおいて、ボタンをタップするたびに、地図にマーカーを増やしていきます。

ゴールイメージは以下の画像の様になります。
![map_add_marker_2_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491965/a96b019b-e06d-6f9c-358b-b9394cddda90.gif)

## 環境
AndroidStudio：Flamingo | 2022.2.1 Patch 2
OS：macOS

ライブラリは前回と一緒ですね。
```gradle:build.gradle
    implementation platform('androidx.compose:compose-bom:2022.10.00')
    implementation 'androidx.compose.ui:ui'
    implementation 'androidx.compose.ui:ui-graphics'
    implementation 'androidx.compose.ui:ui-tooling-preview'
    implementation 'androidx.compose.material3:material3'
    implementation 'androidx.navigation:navigation-compose:2.7.0-beta01'
    implementation platform('com.google.firebase:firebase-bom:32.1.1')
    implementation 'com.google.maps.android:maps-compose:2.11.4'
    implementation 'com.google.android.gms:play-services-maps:18.1.0'
```

## Step1.「Marker追加ボタン」を追加する
地図とボタンを縦並びにしたいので、Columnを使用します。
ボタンは、地図の下に配置したいので、GoogleMapの方だけweightを指定しています。

```kotlin:GoogleMapsScreen.kt
Column {
    GoogleMap(
        modifier = Modifier.weight(1f),
        cameraPositionState = cameraPositionState,
    )
    Button(
        modifier = Modifier.fillMaxWidth(),
        onClick = { /* TODO */ }
    ) {
        Text("Marker追加")
    }
}
```

## Step2.マーカーを1つ出してみる。
まずは、複数のマーカーのことは忘れて、ひとつだけ地図中央にマーカーを動的に表示します。
マーカー座標を保持するStateを定義します。
```kotlin:GoogleMapsScreen.kt
val markerItems = remember { mutableStateListOf<LatLng>() }
```
次に、markerItemsをMarkerとして表示する部分を書きます。
```kotlin:GoogleMapsScreen.kt
GoogleMap(
    modifier = modifier,
    cameraPositionState = cameraPositionState,
) {
    markerItems.forEach { markerItem ->
        Marker(
            state = MarkerState(position = markerItem),
            title = "${markerItem.latitude},${markerItem.longitude}"
        )
    }
}
```
最後にボタンクリック時にマーカー座標を設定します。
```kotlin:GoogleMapsScreen.kt
Button(
    onClick = {
        markerItems.add(initPos)
    },
) {
    Text("Marker追加")
}
```
## (ここまでを)いざ実行
ボタンを押すと、地図の真ん中にマーカーが増えました。
![map_add_marker_1_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491965/316fa437-2e14-1841-71bf-23b72125a72a.gif)

## Step3.マップのロード完了を待つ
マップのロードが完了する前にいろいろ処理したくないので、マップのロードが完了したらボタンを押せるように修正します。

まずは、マップロード状態を管理するStateを定義します。
```kotlin:GoogleMapsScreen.kt
var isMapLoaded by remember { mutableStateOf(false) }
```
次に、MapｓComposeのonMapLoadedでStateを変更します。
```kotlin:GoogleMapsScreen.kt
GoogleMap(
    modifier = Modifier.weight(1f),
    cameraPositionState = cameraPositionState,
    onMapLoaded = {
        isMapLoaded = true
    }
)
```
最後に、このフラグを見てButtonのenabledを変化させます。
```kotlin:GoogleMapsScreen.kt
Button(
    enabled = isMapLoaded,
    onClick = { /* ... */ }
)
```

## Step4.GoogleMapの表示座標(緯度経度)を取得する
マップが表示している緯度経度は、以下で取得できます。
```kotlin
// 地図の緯度経度領域
val latLngBounds:LatLngBounds = cameraPositionState.projection?.visibleRegion?.latLngBounds
// 地図の北東 緯度経度
val northEast:LatLng = latLngBounds.northeast
// 地図の南西 緯度経度
val southWest:LatLng = latLngBounds.southwest
```
ボタンのonClickで、緯度経度それぞれを10等分して、北東から南西に順番にマーカーが追加されるように計算します。
ついでに、地図が動かされている（=カメラ位置が変化している）タイミングでは、計算しないようにしました。
```kotlin:GoogleMapsScreen.kt
onClick = {
    if (!cameraPositionState.isMoving) {
        val latLngBounds = cameraPositionState.projection?.visibleRegion?.latLngBounds
        if (latLngBounds != null) {
            val northEast = latLngBounds.northeast
            val southWest = latLngBounds.southwest
            val latitude = northEast.latitude - ((northEast.latitude - southWest.latitude) / 10.0) * (markerItems.count() + 1)
            val longitude = northEast.longitude - ((northEast.longitude - southWest.longitude) / 10.0) * (markerItems.count() + 1)
            markerItems.add(LatLng(latitude, longitude))
        }
    }
},
```

## いざ実行
北東から順番にマーカーが増えていきます。[コード](https://github.com/jozuko/ComposeTutorial/blob/1ae6c473ccaeeba40a96075a710d4e0132274141/app/src/main/java/com/jozu/jetpack/compose/tutorial/screen/GoogleMapsScreen.kt)

![map_add_marker_2_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491965/a96b019b-e06d-6f9c-358b-b9394cddda90.gif)