google_maps_flutterでGoogle Mapを表示する

Table of Contents

Table of Contents

Google Mapを利用して地図関連の個人アプリを作りたくて、FlutterでGoogle mapの表示を試してみました。 公式パッケージのpreview版を提供していますので、それを使って地図表示、移動、マーカー設置、zoom機能などを操作しました。 また、現在地の取得もできるようになっていますので、Flutterで簡単な地図系のアプリを作れそうですね。



Table of Contents

  • demo video
  • Google Map API KEYの準備
  • パッケージ導入
  • API KEYの設定
    • Andorid
    • iOS
  • 地図の表示
  • mapType
  • zoomGesturesEnabled
  • minMaxZoomPreference
  • markers
  • myLocationEnable
    • Android
    • iOS
  • まとめ


demo video



Google Map API KEYの準備

下記のサイトからAPI KEYの取得ができます。 https://cloud.google.com/maps-platform/

流れとしては、Google Cloud Platformでプロジェクトを準備する。 (新規プロジェクトを作成するか、もしくは既存のプロジェクトを指定する)

プロジェクトの準備できましたら、下記の二つAPIをEnableにします。

  • Maps SDK for Android
  • Maps SDK for iOS

Maps SDK

こちらの ウェブページからAPI KEYを取得できます。



パッケージ導入

公式パッケージgoogle_maps_flutterを導入します。

pubspec.yamlに追加します。(現時点、0.5.28+1は最新版です。)

google_maps_flutter: 0.5.28+1


API KEYの設定

これからAndoridiOSに前の取得したAPI KEYを設定します。

Andorid

android/app/src/main/AndroidManifest.xmlにAPI KEYを追加する。

<application
    android:name="io.flutter.app.FlutterApplication"
    android:label="flutter_example"
    android:icon="@mipmap/ic_launcher">
    <meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="YOUR_API_KEY"/>
    <activity
        ...


iOS

iOSの設定には、AppDelegate.swiftInfo.plistの編集は必要になります。

  • AppDelegate.swift
  • Info.plist

AppDelegate.swift

ios/Runner/AppDelegate.swiftにAPI KEYを設定する。

二つの記述を追加する。 import GoogleMapsGMSServices.provideAPIKey("API_KEY")です。

全体的にこんな感じになります。

import UIKit
import Flutter
import GoogleMaps

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?
  ) -> Bool {
    GMSServices.provideAPIKey("API_KEY")
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

Info.plist

Inof.plistに下記の記述を追加します。

<key>io.flutter.embedded_views_preview</key>
<true/>


地図の表示

API KEYの設定とパッケージの導入できたら、GoogleMapというWidgetを使用できます。

下記は今回作成した例です。

class GoogleMapSample extends StatefulWidget {
  @override
  _GoogleMapSampleState createState() => _GoogleMapSampleState();
}

class _GoogleMapSampleState extends State<GoogleMapSample> {
  Completer<GoogleMapController> _controller = Completer();
  Set<Marker> _markers = {};
  @override
  Widget build(BuildContext context) {
    final CameraPosition _initPosition = CameraPosition(
      target: LatLng(37.42796133580664, -122.085749655962),
      zoom: 14.5
    );
    return new Scaffold(
      appBar: new AppBar(
        title: const Text("Google Map"),
      ),
      body: GoogleMap(
        mapType: MapType.normal,
        initialCameraPosition: _initPosition,
        markers: _markers,
        onMapCreated: (GoogleMapController controller) {
          _controller.complete(controller);
          setState(() {
            _markers.add(
                Marker(
                    markerId: MarkerId('marker_1'),
                    position: LatLng(37.42796133580664, -122.085749655962),
                )
            );
          });
        },
        minMaxZoomPreference: MinMaxZoomPreference(16, 18),
        myLocationEnabled: true,
        myLocationButtonEnabled: true,
      ),
    );
  }
}

Android & iOS

andorid_ios



mapType

一般地図航空写真主要な道路表示なしの表示をmapTypeの設定で変更できます。

設定できる値

  • MapType.terrain:地形
  • MapType.satellite:航空写真
  • MapType.normal:一般
  • MapType.none:表示なし
  • MapType.hybrid:主要な道路と建物の名前が表示


zoomGesturesEnabled

地図のzoom機能を許可することはできます。 デフォルトはtrueになっています。



minMaxZoomPreference

地図の拡大縮小の範囲をminMaxZoomPreferenceで設定できます。 デフォルトはMinMaxZoomPreference.unbounded(制限なし)になっています。

範囲を制限したい例(min: 16, max: 18):

minMaxZoomPreference: MinMaxZoomPreference(16, 18)


markers

markersで地図にマーカーの設置ができます。

以下は簡単な設定例です。

値はSet<Marker>型なので、複数の設定はできますが、今回は一つだけを設定してみます。 setState関数を使って、_markersにマーカーを追加してから画面を更新するように処理します。

(マーカーの画像を変更したい場合は、iconの属性を設定すれば表示が変わります。)

Set<Marker> _markers = {};

...
markers: _markers,
onMapCreated: (GoogleMapController controller) {
  _controller.complete(controller);
  setState(() {
    _markers.add(
        Marker(
            markerId: MarkerId('marker_1'),
            position: LatLng(37.42796133580664, -122.085749655962),
        )
    );
  });
},


myLocationEnable

地図の表示ができたら、やはり現在地も表示させたいと思いまして、現在地の取得も試してました。 位置情報を取得するため、位置情報の権限は必要になります。

以下は、AndroidとiOSそれぞれの位置情報の権限の取得方法を説明します。

Android

まず、AndroidManifest.xmlに下記のどちらの権限を追加します。

  • <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  • <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

自分のAndorid端末はAndorid 10なので、ユーザーに権限許可してもらう処理を簡単にできるため、下記のパッケージを導入しました。

permission_handler

そのため、pubspec.yamlpermission_handler: 5.0.1+1を追加する。

作成したアプリはホーム画面にGoogle mapボタンがあり、そのボタンを押した後地図を表示しますので、 地図画面を表示する前に権限を確認&要求しています。

if文でawait Permission.location.request().isGrantedを判断し、許可できたら地図画面に遷移します。

RaisedButton(
    child: Text("google map"),
    onPressed: () async {
      if (await Permission.location.request().isGranted) {
        Navigator.push(
            context, MaterialPageRoute(builder: (context) => GoogleMapSample())
        );
      }
    }
)

home_map



ios

Info.plistに下記の記述追加します。

<key>NSLocationWhenInUseUsageDescription</key>
<string>Your location is required to share you location within google map</string>


まとめ

Google MapのAPI KEYの取得とgoogle_maps_flutterパッケージの導入を準備できたら、GoogleMapというWidgetでGoogle Mapの表示ができました。 地図の表示、指でカメラの移動、zoom機能、拡大縮小の制限、マーカーの設置などを一通りで操作できます。 最後に現在地の表示には少し手間がかかりますが、このパッケージはまだpreviewバージョンなので、今後の更新を期待しています。