AndroidアプリでGoogle Mapの使えそうな処理

前回の記事でGoogle Mapを表示するまでの手順を書いたので、今回はGoogle Mapで使えそうな処理について紹介します。

https://qiita.com/ssc-ksakamaki/items/7fe03fab5f7b74382753

## 目次

* [レイアウトファイルとマップの紐付け](#レイアウトファイルとマップの紐付け)
* [初期表示の中心地の設定](#初期表示の中心地の設定)
* [初期表示のマーカーの設置](#初期表示のマーカーの設置)
* [タップ時のマーカーの設置](#タップ時のマーカーの設置)
* [マーカーの吹き出しをタップした時の処理の設定](#マーカーの吹き出しをタップした時の処理の設定)
* [ポリラインの設定](#ポリラインの設定)
* [まとめ](#まとめ)

## レイアウトファイルとマップの紐付け
マップを操作するためにレイアウトファイルのマップと紐付けます。

```MapsActivity.java
// 継承とインターフェースを変更
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
    private Button back_btn;

    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_map);

        back_btn = findViewById(R.id.back_btn);
        back_btn.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                onBackPressed();
            }
        });

        // レイアウトファイルのマップと紐付ける
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        //ここにマップの処理を書く
    }
}
```

## 初期表示の中心地の設定
マップを表示したときの中心地を設定します。
現在地を取得して中心地に設定もできますが、位置情報の取得は別記事で書くので今回は東京駅を中心地に設定します。

```MapsActivity.java
    @Override
    public void onMapReady(GoogleMap googleMap) {

        // カメラの中心位置を設定
        setCameraPosition(googleMap);
    }

    // カメラの中心位置を設定
    private void setCameraPosition(GoogleMap googleMap) {
        // 現在地を取得する処理がないため東京駅を中心に表示
        LatLng latlng = new LatLng(35.681167, 139.767052); // 東京駅
        googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, 10));
        // 10はズームの引数で大体東京都が全て見えるくらい
        // 50にすると東京駅だけが見えるくらい
    }
```

1点ではなく範囲で初期表示を設定する場合は以下の通り。
南の緯度より北の緯度の方が小さい、西の経度より東の経度の方が小さいなど矛盾が発生するとエラーになります。
```java
        LatLng sw = new LatLng(35.681167, 139.767052); // 東京駅
        LatLng ne = new LatLng(35.7107921,139.7876583); // 浅草駅
        LatLngBounds bounds = new LatLngBounds(sw, ne);
        googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds, 10));
```
![Screenshot_20240424-155723.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/2d118b2d-ad16-167c-aece-9c2fc557d889.png)


## 初期表示のマーカーの設置
マーカーの設定の仕方です。
```MapActivity.java
    @Override
    public void onMapReady(GoogleMap googleMap) {

        // 記録済みのマーカーを追加
        addPreMarkers(googleMap);
    }

    // マーカーを追加
    private void addMarker(GoogleMap googleMap, LatLng latlng, String title) {
        googleMap.addMarker(new MarkerOptions()
                .title(title)
                .position(latlng)
        );
    }

    // 記録済みのマーカーを追加
    private void addPreMarkers(GoogleMap googleMap) {
        // ダミーデータを使用
        addMarker(googleMap, new LatLng(35.681167, 139.767052), "東京駅");
        addMarker(googleMap, new LatLng(35.6905539, 139.6972769), "新宿駅");
        addMarker(googleMap, new LatLng(35.658034, 139.701636), "渋谷駅");
        addMarker(googleMap, new LatLng(35.710063, 139.8107), "上野駅");
        addMarker(googleMap, new LatLng(35.696312, 139.814606), "秋葉原駅");
        addMarker(googleMap, new LatLng(35.702258, 139.774224), "銀座駅");
    }
```

`title`に設定した文字がマーカーをタップしたときの吹き出しに表示されます。
`icon`を設定するとマーカーの画像を変更できます。

```java
    // マーカーを追加
    private void addMarker(GoogleMap googleMap, LatLng latlng, String title) {
        googleMap.addMarker(new MarkerOptions()
                .title(title)
                .position(latlng)
                .icon(BitmapDescriptorFactory.fromResource(R.drawable.marker))
        );
    }
```

![002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/561749c2-bb88-7d84-bd94-fd87caf4329a.png)

## タップ時のマーカーの設置
マップをタップしたときの処理にマーカーの追加処理を入れます。

```MapActivity.java
    @Override
    public void onMapReady(GoogleMap googleMap) {

        // マップを長押ししたときのイベントを設定
        googleMap.setOnMapLongClickListener( new GoogleMap.OnMapLongClickListener() {
            @Override
            public void onMapLongClick(LatLng latLng) {
                // マーカーを追加
                addMarker(googleMap, latLng, "新しい場所");
            }
        });
    }

    // マーカーを追加
    private void addMarker(GoogleMap googleMap, LatLng latlng, String title) {
        googleMap.addMarker(new MarkerOptions()
                .title(title)
                .position(latlng)
        );
    }
```

誤タップが増えるので使いにくそうですが長押しではない場合は以下です。
```java
        googleMap.setOnMapClickListener( new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                // マーカーを追加
                addMarker(googleMap, latLng, "新しい場所");
            }
        });
```

## マーカーの吹き出しをタップした時の処理の設定
マーカーの吹き出しをタップした時に別画面に遷移するなどの処理を設定できます。
```MapActivity.java
    @Override
    public void onMapReady(GoogleMap googleMap) {

        // マーカーの吹き出しをタップした時のイベントを設定
        googleMap.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {
            @Override
            public void onInfoWindowClick(com.google.android.gms.maps.model.Marker marker) {
                // ここに処理内容を書く
            }
        });
    }
```

## ポリラインの設定
マーカーとマーカーの間に線を設定します。
```MapActivity.java
    @Override
    public void onMapReady(GoogleMap googleMap) {

        // ラインを追加
        addPolyLine(googleMap);
    }

    // 地図上にポリラインを追加する
    private void addPolyLine(GoogleMap googleMap) {
        // 位置情報を取得する処理がないためダミーデータを使用
        ArrayList<LatLng> points = new ArrayList<>();
        points.add(new LatLng(35.681167, 139.767052)); // 東京駅
        points.add(new LatLng(35.6905539, 139.6972769)); // 新宿駅
        points.add(new LatLng(35.658034, 139.701636)); // 渋谷駅

        googleMap.addPolyline(
                new PolylineOptions()
                        .addAll(points)
        );
    }
```

![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2480832/52239717-45ef-e0f0-a8df-2a86c95a7947.png)

## まとめ
ここまでの処理ができるようになれば色々とアイディアが浮かんでくるので是非試してみてください。
場所の検索や現在地の取得などできればもっと色々できそうなので次回はその辺を記事にしたいです。