🦍

FlutterでGoogle Map表示アプリを作り、ピンを刺す方法

2021/05/23に公開1

はじめに

Google Map上にピンを刺すコードを書いていきましょう。

Google Maps for Flutterとして公開されているパッケージを使用しています。
google_maps_flutter

この記事のコードをベースに追加していきます。
FlutterでGoogle Mapを呼び出すアプリを作ってみよう

Markerを表示する

まずは、マーカーを指定した座標に表示するコードを追加します。
main.dartにMarkerオブジェクトを返す関数を追加し、マーカーを刺す位置とIDを設定していきます。

static final LatLng _kMapCenter1 =
    LatLng(37.43296265331129, -122.08832357078792);

Set<Marker> _createMarker() {
  return {
    Marker(
      markerId: MarkerId("marker_1"),
      position: _kMapCenter1,
    ),
  };
}

この関数をGoogleMapクラスを生成し、その中で先程作った関数を呼び出します。

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

マーカを表示するコードの基本形はこれで完成です。

実行結果

上手く動作すると指定した座標にマーカが表示されます。

複数のマーカを表示する

先程のコード上に追加して複数マーカーを表示してみます。
やり方は簡単ですが、Markerを複数返すだけです。

例えば、事前に複数の店舗情報をSQLで用意しておき、取得したデータ分だけマーカを追加するように作り込んでいくと中々見れたものになりそうですね。

static final LatLng _kMapCenter1 =
    LatLng(37.43296265331129, -122.08832357078792);

+static final LatLng _kMapCenter2 =
+    LatLng(37.43306265331129, -122.08830057078792);

Set<Marker> _createMarker() {
  return {
    Marker(
      markerId: MarkerId("marker_1"),
      position: _kMapCenter1,
    ),
+    Marker(
+      markerId: MarkerId("marker_2"),
+      position: _kMapCenter2,
+    ),
  };
}

実行結果

マーカーの位置が近ずぎて表示すると1つのマーカみたいに表示されますが…
右下の+ーアイコンで表示距離を変更するとこのように複数マーカ表示されていることが確認できます。

マーカに情報を追加する

infoWindowをMarker()の中に追加することで実装できます。
店の名前をここに入れていくのが良いんでないでしょうか。

Set<Marker> _createMarker() {
  return {
    Marker(
        markerId: MarkerId("marker_1"),
        position: _kMapCenter1,
        infoWindow: InfoWindow(title: "腐ったみかん")),
    Marker(
      markerId: MarkerId("marker_2"),
      position: _kMapCenter2,
    ),
  };
}

実行結果

マーカに情報を追加する

infoWindow: InfoWindow(title: "腐ったみかん", snippet: '俺は腐ったみかんじゃない')),

infoWindowのsnippetを追加するとこんなふうに表示されます。

今回実装したコードの全文

こんな感じになります。

import 'dart:async';
import 'dart:typed_data';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/services.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.43296265331129, -122.08832357078792),
    zoom: 13.0000,
    bearing: 0.0,
    tilt: 0.0,
  );

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

  static final LatLng _kMapCenter1 =
      LatLng(37.43296265331129, -122.08832357078792);

  static final LatLng _kMapCenter2 =
      LatLng(37.43306265331129, -122.08830057078792);

  Set<Marker> _createMarker() {
    return {
      Marker(
          markerId: MarkerId("marker_1"),
          position: _kMapCenter1,
          icon: BitmapDescriptor.defaultMarkerWithHue(5.4),
          infoWindow: InfoWindow(title: "腐ったみかん", snippet: '俺は腐ったみかんじゃない')),
      Marker(
        markerId: MarkerId("marker_2"),
        position: _kMapCenter2,
      ),
    };
  }

  Future<BitmapDescriptor> getMarker() async {
    final ui.PictureRecorder pictureRecorder = ui.PictureRecorder();

    final Canvas canvas = Canvas(pictureRecorder);
    final Paint paint = Paint();
    paint.color = Colors.red;
    canvas.drawCircle(Offset(100, 35), 25, paint);

    final image = await pictureRecorder.endRecording().toImage(100, 100);
    final data = await image.toByteData(format: ui.ImageByteFormat.png);
    final Uint8List bytes = data!.buffer.asUint8List();
    return BitmapDescriptor.fromBytes(bytes);
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      body: GoogleMap(
        mapType: MapType.hybrid,
        markers: _createMarker(),
        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));
  }
}

まとめ

FlutterでGoogle Mapにマーカを追加する方法を理解しました。Android JavaでGoogle Mapを実装した時に比べると随分簡単で良いですね。

Flutter全然分かってないので、記事のネタとしては弱いですが少しずつできること増やしていきましょ。

FlutterではCanvasを画像データに変換してGoogle Map上に書き出すやり方もあるので次回はそれを試して行きたいですね。

Discussion