LoginSignup
3
2

More than 1 year has passed since last update.

FlutterでGoogle Mapを表示させる

Posted at

初めに

Flutterを使っている人の中で、GoogleMapの導入を考えている人も多いのではないでしょうか。
自分も自作しているアプリの中で、GoogleMapを導入することになったので、その使い方を共有したいと思います!
なお、今回はiOSのみ行います。

APIキー取得

Google Maps Platformのページから以下の6つの項目を完了させてください。

  • Googleアカウント作成
  • Google Cloud Platform 利用開始
  • 請求先アカウントの設定
  • プロジェクトの作成
  • API有効化
  • APIキーの作成

今回はiOSに導入するため、有効化させるAPIは「Maps SDK for iOS」のみです。

AppDelegate.swift の変更

APIキーの取得が完了したら GoogleMap を読み込むために設定を変更する必要があります。
以下のパスにあるファイルを開いて下のコードの緑で囲まれた部分を追加してください。
ios/Runner/AppDelegate.swift

AppDelegate.swift
import UIKit
import Flutter
+ import GoogleMaps 

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

"YOUR KEY"の部分に Google Maps Platform で取得した APIキーを記述してください。

pubspec.yaml の変更

次に必要なパッケージを「pubspec.yaml」に記述します。
今回使用するパッケージはgoogle_maps_flutterです。

pubspec.yaml
dependencies:
  flutter:
    sdk: flutter

  cupertino_icons: ^1.0.2
+ google_maps_flutter: ^2.1.8

Pub get も忘れないようにしましょう!

Map を表示させる

これで全ての準備が完了しました。
今回は google_maps_flutter のサンプルを表示させてみましょう。
以下のコードを記述してください。

main.dart
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Google Maps Demo',
      home: MapSample(),
    );
  }
}

class MapSample extends StatefulWidget {
  @override
  State<MapSample> createState() => MapSampleState();
}

class MapSampleState extends State<MapSample> {
  Completer<GoogleMapController> _controller = Completer();

  static final CameraPosition _kGooglePlex = CameraPosition(
    target: LatLng(37.42796133580664, -122.085749655962),
    zoom: 14.4746,
  );

  static final CameraPosition _kLake = CameraPosition(
      bearing: 192.8334901395799,
      target: LatLng(37.43296265331129, -122.08832357078792),
      tilt: 59.440717697143555,
      zoom: 19.151926040649414);

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: GoogleMap(
        mapType: MapType.hybrid,
        initialCameraPosition: _kGooglePlex,
        onMapCreated: (GoogleMapController controller) {
          _controller.complete(controller);
        },
      ),
      floatingActionButton: FloatingActionButton.extended(
        onPressed: _goToTheLake,
        label: Text('To the lake!'),
        icon: Icon(Icons.directions_boat),
      ),
    );
  }

  Future<void> _goToTheLake() async {
    final GoogleMapController controller = await _controller.future;
    controller.animateCamera(CameraUpdate.newCameraPosition(_kLake));
  }
}

以下の画像のように Map と 「To the lake!」と書かれた FloatingActionButton が表示されました。「To the lake!」ボタンを押すと視点が入れ替わるようになっています。

normal-map

※「To the lake!」ボタンの下のレイヤーにあるのは以下のような現在地を表示するためのボタンでした。

Map を変更する

次に Map の変更をしてみましょう。以下で GoogleMap のプロパティをまとめました。この他にもありますが、今回は使用頻度が高いと思われるものをまとめました。

プロパティ 用途
mapType Map のタイプを指定
markers Map 上にマーカーを表示
initialCameraPosition カメラの初期値を指定
polylines 2地点以上マーカーがある場合にその直線距離を結ぶ直線を表示

mapType

mapType には以下の4種類があります。

種類 説明 実際の表示
hybrid normal と satellite の情報を複合した地図
normal 道路や建物などが表示される地図
satellite 衛星写真を使った地図
terrain 地形情報を使った地図

markers

次はマーカーを表示させてみましょう。

main.dart
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class GoogleMapExample extends StatefulWidget {
  @override
  State<GoogleMapExample> createState() => GoogleMapExampleState();
}

class GoogleMapExampleState extends State<GoogleMapExample> {
  Completer<GoogleMapController> _controller = Completer();

+   static Marker _kGooglePlexMarker = Marker(
+   markerId: MarkerId("_kGooglePlex"),
+   infoWindow: InfoWindow(
+     title: "Google",
+   ),
+   icon: BitmapDescriptor.defaultMarker,
+   position: LatLng(37.42796133580664, -122.085749655962),
+ );

  static final CameraPosition _kGooglePlex = CameraPosition(
    target: LatLng(37.42796133580664, -122.085749655962),
    zoom: 14.4746,
  );

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: GoogleMap(
        mapType: MapType.hybrid,
+       markers: {
+         _kGooglePlexMarker,
+       },
        initialCameraPosition: _kGooglePlex,
        onMapCreated: (GoogleMapController controller) {
          _controller.complete(controller);
        },
      ),
    );
  }
}

コードを追加して実行するとマーカーが表示され、マーカーを押すと infoWindowtitle に指定した「Google」というテキストが以下のように表示されます

タイトル以外にもアイコンを以下のように変更すると

main.dart
- icon: BitmapDescriptor.defaultMarker,
+ icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueBlue),

ピンの色を変更できます。

他にも自分で指定した画像をピンとして使うこともできます。

initialCameraPosition

GoogleMap が初めて読み込まれた時のカメラの位置を指定できます。

main.dart
static final CameraPosition _kGooglePlex = CameraPosition(
  target: LatLng(37.42796133580664, -122.085749655962),
  zoom: 14.4746,
);

このコードのように予め Cameraposition という型で指定したい地点の緯度、経度とカメラのズームの程度を指定することで初期値を決めることができます。

polylines

polylines を使うことで2地点以上を結ぶ直線を描くことができます。

main.dart
import 'dart:async';

import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';

class GoogleMapExample extends StatefulWidget {
  @override
  State<GoogleMapExample> createState() => GoogleMapExampleState();
}

class GoogleMapExampleState extends State<GoogleMapExample> {
  Completer<GoogleMapController> _controller = Completer();

  static Marker _kGooglePlexMarker = Marker(
    markerId: MarkerId("_kGooglePlex"),
    infoWindow: InfoWindow(
      title: "Google",
    ),
    // icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueBlue),
    icon: BitmapDescriptor.defaultMarkerWithHue(BitmapDescriptor.hueBlue),
    position: LatLng(37.42796133580664, -122.085749655962),
  );

+  static final Marker _kLakeMarker = Marker(
+    markerId: MarkerId("_kLake"),
+    infoWindow: InfoWindow(
+      title: "Lake",
+    ),
+    icon: BitmapDescriptor.defaultMarker,
+    position: LatLng(37.43296265331129, -122.08832357078792),
+  );

+  static final CameraPosition _kLake = CameraPosition(
+      bearing: 192.8334901395799,
+      target: LatLng(37.43296265331129, -122.08832357078792),
+      tilt: 59.440717697143555,
+      zoom: 19.151926040649414
+  );

+  static final Polyline _kPolyline = Polyline(
+    polylineId: PolylineId("_kPolyline"),
+    points: [
+      LatLng(37.42796133580664, -122.085749655962),
+      LatLng(37.43296265331129, -122.08832357078792),
+    ],
+    width: 5,
+    color: Colors.white70,
+  );


  static final CameraPosition _kGooglePlex = CameraPosition(
    target: LatLng(37.42796133580664, -122.085749655962),
    zoom: 14.4746,
  );

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: GoogleMap(
        mapType: MapType.hybrid,
        markers: {
          _kGooglePlexMarker,
+         _kLakeMarker,
        },
+       polylines: {_kPolyline},
        initialCameraPosition: _kGooglePlex,
        onMapCreated: (GoogleMapController controller) {
          _controller.complete(controller);
        },

      ),
    );
  }
}

新たに_kLakeMarkerという地点を追加し、_kGooglePlexMarker_kLakeMarkerの二地点間をつなぐ直線を追加しました。

polylines は直線の幅や色を変更することができます。

以上です!

あとがき

最後まで読んでいただきありがとうございました。
参考にしていただければ幸いです。

誤っている箇所やその他のアイコンがあればご指摘いただければ幸いです。

参考にしたサイト

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2