diadia

興味があることをやってみる。自分のメモを残しておきます。

GoogleMapにデータを表示する

記事概要

この記事では2種類のGoogleMapsを使った実装方法のメモを残す。

一つは暗黙的インテントによるGoogleMapsアプリの起動例。
もう一つは、GoogleMapsPlatformを利用した自前アプリへの組込例である。

コンテンツ

  1. 暗黙的インテントによるGoogleMapsアプリの起動
  2. GoogleMasPlatformを利用した方法

1. 暗黙的インテントによるGoogleMapsアプリの起動

イメージ

写真や何かを表示するためのIntent.ACTION_VIEWを使う。 そしてGoogleMapを直接使うためにintentにgooglemapをsetPackage()メソッドでセットする。 その後にstartActivityメソッドを実行すれば良い。

コードサンプル

val longitude = ***
val latitude = ***
val geoStrUri = "geo:" + longitude+ "," + latitude + "?z=13"
val geoUri = Uri.parse(geoStrUri)
val intent = Intent(Intent.ACTION_VIEW, geoUri)
intent.setPackage("com.google.android.apps.maps")
startIntent(intent)

この実装の特徴

この実装では自分のアプリからGoogleMapsをintentを使って起動している。それはアプリから別アプリを起動しただけであるので、googleMaps内でタップすると、GoogleMapsのアプリのロジックに従ったレスポンスが返されるだけである。 マップをタップすると、そのタップした内容に従って自作アプリのレスポンスを返すことがしたい場合にはintentではなく、GoogleMapsPlatformのAPIを利用する必要がある。

Uriについて補足

intent関係でuriオブジェクトを生成することが多い事がわかった。 例えば、カメラでとった写真をアプリケーションで表示したい場合もuriを生成しなければならなかったと思う。 このuriが何かわからなかったが、uriの作り方は共通している。

Uri#parse()メソッドに特定の文字列(ファイルパス等)を渡すだけである。

これさえ理解すればUriについて困ることはない。

GoogleMapをタッチして別の反応を実装するにはどうすればよいか

参考 Map Objects  |  Maps SDK for Android  |  Google Developers

1. GoogleMasPlatformを利用した方法

GoogleMasPlatformを使えば良いようだ。

Google Maps Platform  |  Google Developers

これを使うにはGCPに登録が必要だった。API keyを取得し、そのkeyをマニフェストファイルにmetaタグに含めて記述する。 そしてactivityでgoogleMapsを呼び出すフラグメントを実施すればgoogleMapsの画面(GoogleMapsのアプリではない)を呼び出すことができた。

Google Play services SDKAndroid Studioにインストールする

Update the IDE and SDK Tools  |  Android Developers

Android SDK Build-Tools、Android SDK Platform-Tools、Android SDK Toolsのインストールを実施する。

GoogleMapsのAPIKeyを取得する。

Get an API Key  |  Maps SDK for Android  |  Google Developers

マニフェストファイルにAPIkeyを入力する

Get an API Key  |  Maps SDK for Android  |  Google Developers

以下のメタタグをapplicationタグの子要素として追加する。しかしこのメタタグは子要素のうち最後の要素として追加する。

<meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="YOUR_API_KEY"/>

appレベルのgradleに以下を追加

implementation 'com.google.android.gms:play-services-maps:17.0.0'

これがないとSupportMapFragmentをインポートできない。
これに関してはgradleに手入力しなくても済ませる方法もある。fragmentファイルまたはActivityファイルに、 SupportMapFragmentを入力するとエラーを示す赤波線が表示される。そのSupportMapFragmentをalt + Enterボタンを押すとgradleに必要なサービスを追加する事ができるのでそれを選ぶ。するとgradleに追加される。

GoogleMapsをアプリ内で描画する

ドキュメントはどこにあるのか?
Adding a Map with a Marker  |  Maps SDK for Android  |  Google Developers

どのように実装するのか?
フラグメントを使う場合と同じような感じで実装する。
マップを描画する場所はFrameLayoutViewである。FrameLayoutViewにMapを描画するのは、supportFragmentManager.beginTransaction()...のような感じで記述することになる。これはfragmentの起動とほぼ同じだ。

具体的にアクティビティ、レイアウトファイルにはどのように記述するか?
以下を参照。

val map = SupportMapFragment.newInstance()
supportFragmentManager.beginTransaction().add(R.id.googleMapsApiFrameLayout, map).commit()
map.getMapAsync(this)
public void onMapReady(GoogleMap googleMap) {
        // Add a marker in Sydney, Australia,
        // and move the map's camera to the same location.
        LatLng sydney = new LatLng(-33.852, 151.211);
        googleMap.addMarker(new MarkerOptions().position(sydney)
                .title("Marker in Sydney"));
        googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
    }

マップに座標地点(ポイント)をマーキングする

Adding a Map with a Marker  |  Maps SDK for Android  |  Google Developers

OnMapReadyCallback#onMapReady()コールバックメソッドをoverrideする。そのなかでaddMarkerメソッドを実装する。

地図の縮尺を変更する

地図の縮尺レベルを説明した資料

Camera and View  |  Maps SDK for Android  |  Google Developers

具体的な縮尺の設定方法を示した資料

Android Google Maps v2 - set zoom level for myLocation - Stack Overflow

サンプルコード

まずLatLngオブジェクトを生成し、地図の中心位置をmoveCameraメソッドで定める。そして縮尺をCameraUpdateFactory.zoomTo()で定める。

    override fun onMapReady(googleMap: GoogleMap) {
        
        val xela = LatLng(14.845833, -91.518889)
        googleMap.moveCamera(CameraUpdateFactory.newLatLng(xela));
        googleMap.moveCamera(CameraUpdateFactory.zoomTo(10.0f));
    }

moveCameraメソッドの引数として座標データオブジェクトと縮尺レベルを同時に渡すこともできる。それはmoveCameraメソッドにnewLatLngメソッドの代わりにnewLatLngZoomメソッドを使えば良い。

    override fun onMapReady(googleMap: GoogleMap) {
        
        val xela = LatLng(14.845833, -91.518889)
        googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(xela, 12.0f));
    }

関連記事

GoogleMapsのタップイベントから座標情報取得を試みる内容
緯度経度情報を取得する(GoogleMapのマーカーから) - diadia

marker, polygonをmapに描画する
GoogleMapsPlatformを使ってポリゴンを描画 - diadia