AndroidでGoogle Mapを使う方法まとめ


#概要
先日、[Yahoo!Japanのハッカソン](http://hackday.jp/)でGoogleMapを使ったAndroidアプリを作ったので、そのとき調べたMapの使い方をまとめました。

#画面にMapを表示する
Mapを表示するだけだったら、AndroidStudioのNew Projectを選択したときに、Google Maps Activityを選べば表示できるので、一つ一つポイントだけ説明します。

## GoogleMapのApiキーを取得する
Mapを使うにはApiキーが必要なので、[ここ](https://console.developers.google.com/flows/enableapi?apiid=maps_android_backend&keyType=CLIENT_SIDE_ANDROID)でキーを作成して、res/values/google_maps_api.xml(別にgoogle_maps_api.xmlという名前である必要はない)に書いておく

```XML:google_maps_api.xml
<resources>
    <string name="google_maps_key" templateMergeStrategy="preserve" translatable="false">取得したキー</string>
</resources>
```

## AndroidManifestにPermissionとキーのmeta-dataを追加
AndroidManifest.xmlに下記のPermissionと先ほどのキーを追記して、Mapが利用できるようにしておく

```XML:AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

<application (略)>
    <meta-data 
        android:name="com.google.android.geo.API_KEY" 
        android:value="@string/google_maps_key" />
    <!-- 中略 -->
</application>

```

## build.gradleにgmsへのdependencyを追加する

```gradle:build.gradle
    compile 'com.google.android.gms:play-services:10.0.1'
```

## LayoutにMapを追加する
非常に簡単。SupportMapFragmentを追加するだけ。

```XML:activity_main.xml
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:map="http://schemas.android.com/apk/res-au
      xmlns:tools="http://schemas.android.com/tools"
      android:id="@+id/map"
      android="com.google.android.gms.maps.SupportMapFragment
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      map:cameraZoom="15"/>
```

ここまでやれば、画面にマップが表示されるはず。
ちなみにこんな感じで表示されるはず(map:cameraZoom="15"の場合)。
<p><img src="https://qiita-image-store.s3.amazonaws.com/0/43125/c7731e0a-bd8a-313a-a8d9-f43cf85ec06c.png" width="200dp" alt="Map"/></p>



# Mapの使い方
MapはGoogleMapインスタンス経由で操作できます。
GoogleMapのインスタンスは、SupportMapFragmentのgetMapAsyncからonMapReadyCallbackを通じて下記のように取得できます。

```java
private void createMap() {
    // Obtain the SupportMapFragment and get fied when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}

@Override
public void onMapReady(GoogleMap googleMap) {
    Log.i(TAG, "Map created!");
    mMap = googleMap;
    (以下略)
}
```

細かな使い方は、[オフィシャルのドキュメント](https://developers.google.com/android/reference/com/google/android/gms/maps/GoogleMap)を見てもらうとして、ここでは主な機能の使い方を紹介します。

## 自分の位置をMapに表示する
標準で用意されている方法と、マーカーを自分で設定する方法の2種類があります。

###標準で用意されている方法
一行下記を追記する。この方法の問題点は表示が標準の青丸で、アイコンのカスタマイズができないこと。

```java
mMap.setMyLocationEnabled(true);
```

###自分でマーカーを置く
自分の位置にマーカーをおいて、それを随時更新することで表示します。この方法だと、マーカーのアイコンを自分で決めることができます。

```java
@Override
public void onMapReady(GoogleMap googleMap) {
    (中略)
    mApiClient = new GoogleApiClient.Builder(this)
        .addApi(LocationServices.API)
        .addConnectionCallbacks(mConnectionCal
        .addOnConnectionFailedListener(mConnecedListener)
        .build();
    mApiClient.connect();
}

private GoogleApiClient.ConnectionCallbacks mConnectionCallback = new GoogleApiClient.ConnectionCallbacks() {
    @Override
    public void onConnected(@Nullable Bundle le) {
        final long INTERVAL_MILLIS = 1000;//更新の頻度。ここでは1秒おきに更新する
        LocationRequest request = new tionRequest();
        request.setInterval(INTERVAL_MILLIS);
        request.setPriority(LocationRequest.PRIORITY_HIGH_ACCU);
        LocationServices.FusedLocationApi.requestLocationUpdatApiClient, request, mLocationListener);
    }

    @Override
    public void onConnectionSuspended(int i) {

    }
};

private LocationListener mLocationListener = new LocationListener() {
    @Override
    public void onLocationChanged(Location location) {
        LatLng position = new LatLng(location.getLatitude(), location.getLongitude());
        MarkerOptions markerOptions = new MarkerOptions();
        //zoom to current position:
        if (mCurrentLocationMarker == null) {
            markerOptions.position(position);
            markerOptions.title("タイトル");
            markerOptions.icon(BitmapDescriptorFactory.fromResource(R.mipmap.好きなアイコン));

            mCurrentLocationMarker = mMap.addMarker(markerOptions);
        } else {
            mCurrentLocationMarker.setPosition(position);
        }
    }
};
```

また、表示しているマーカーを消したくなったら、

```java
mCurrentLocationMarker.remove();
```

で一発。MapにaddMarkerしたのを覚えておくのがポイント。
また、addMarkerは自分の位置だけじゃなく、座標（緯度経度）が分かればどこにでも設置可能なので、目的地にマーカーを設置したりするのも簡単。

## Map上に線を引く
GoogleMapApiなどで検索した経路を地図上に表示したいとき、2点（もしくはそれ以上）の緯度経度が分かれば、簡単に線を引くことができます。

```java
private void drawRoute(List<LatLng> route) {
    PolylineOptions options = new lineOptions();
    for (LatLng latLng : route) {
        options.add(latLng);
    }
    options.color(色);
    options.width(幅);
    mMap.addPolyline(options);
}
```

こんな感じ
<p><img src="https://qiita-image-store.s3.amazonaws.com/0/43125/f83abc44-dcf0-05da-f873-c6de2aa820f5.png" width="200dp" alt="route"/></p>

## カメラの倍率、ポジションを変更する
表示の倍率、位置を変更するには、CameraPositionを設定しなおせばOK。
下記では、北緯50度、東経50度（カザフスタンの西あたり）、Zoomのレベルを10に移動しています

```java
CameraPosition cameraPosition = new CameraPosition.Builder().target(new LatLng(50.0, 50.0)).zoom(10).build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
```

# さいごに
たくさん書いたので、補足があったら後日追記します