Flutter×GoogleMap基礎編③〜polygonでマップに囲いを表示する〜

プログラミング

はじめに

今回はFlutterアプリケーションにGoogleMapを組み込むためのパッケージである、
google_maps_flutterの使い方をご紹介します。

こちらの基礎編③ではGoogleMap()ウィジェットの中でも、
polygon、circle、overlayについて解説していきます。
いずれもマップ上の指定した領域を色付きの枠で囲う機能です。


GoogleMapの表示方法を知りたい。基本的なマーカーの表示方法が知りたい。という方はまずは基礎編①、基礎編②をご覧ください。

https://www.kentosjpn.com/programming/14/
https://www.kentosjpn.com/programming/15/

実装していく

今回使用するgoogle_maps_flutterのバージョンは下記です。

dependencies:
  google_maps_flutter: ^2.1.4

 

図形で囲う(polygons)

マップ上にポリゴン(多角形)を表示します。
GoogleMap()ウィジェットのpolygonsプロパティを使用します。

GoogleMap(
        initialCameraPosition: CameraPosition(
          zoom: 15,
          target: LatLng(35.0, 135.0),
        ),
        polygons: {
          Polygon(
              strokeColor: Colors.pink.withOpacity(0.8),//線の色
              fillColor: Colors.pink.withOpacity(0.2),  //塗りつぶし色
              strokeWidth: 2,                           //線の太さ
              points: [                                 //ポリゴンで囲う地点
                LatLng(35.0, 135.0),
                LatLng(35.0, 135.005),
                LatLng(35.01, 134.999),
                LatLng(35.01, 134.994),
              ],
              polygonId: PolygonId(                      //一意なID
                'polygon1',
              ))
        },
)
  • polygonsプロパティ
    マップに表示したいポリゴンをSet<Polygon>型で渡します。
  • Polygonウィジェット
    pointsプロパティにLatLng(緯度,経度)のリストを渡すと、
    それらの地点を順番に結んだ図形が表示されます。
    デフォルトでは黒の図形で塗りつぶされてしまいますので、
    fillColorで透過色を指定して下のマップが見えるようにしています。

地点は順番に結ばれるため、サンプルコードの3番目と4番目のLatLngを入れ替えると下記のようになります。

円で囲う(circles)

続いてマップ上を円で囲う方法です。
GoogleMap()ウィジェットのcirclesプロパティで指定します。
基本的に先ほどのpolygonsプロパティと同じ考え方でOKです。

GoogleMap(
        initialCameraPosition: CameraPosition(
          zoom: 16,
          target: LatLng(35.0, 135.0),
        ),
        circles: {
          Circle(
            circleId: CircleId('Circle1'),             //一意なID
            center: LatLng(35.0, 135.0),               //中心の座標
            radius: 122,                               //半径(m)
            strokeColor: Colors.pink.withOpacity(0.8), //線の色
            fillColor: Colors.pink.withOpacity(0.2),   //塗りつぶし色
            strokeWidth: 2,                            //線の太さ
          )
        },
)
  • circlesプロパティ
    Set<Circle>型で表示したいCircle()ウィジェットを渡します。
  • Circle()ウィジェット
    Polygon()ウィジェットと異なるのは、中心centerを指定し、
    それに対する半径をradiusで指定する点です。

余談ですが半径122mは大体東京ドームの半径と同じだそうです。
地図上で見ると意外と小さく感じますね。

circlesプロパティにCircle()ウィジェットを複数指定すれと下記のように表示もできます。

タイル表示(tileOverlays)

マップ上にタイル形式で何かを表示したい時にはtileOverlaysプロパティで指定します。

GoogleMap(
    initialCameraPosition: CameraPosition(zoom: 16,target: LatLng(35.0, 135.0),),
    tileOverlays: {
      TileOverlay(
        tileProvider: _DebugTileProvider(),      //表示するタイルのProvider(別途作成する)
        transparency: 0.5,                       //透過度0〜1
        tileOverlayId: TileOverlayId('overlay1'),//一意なID
      )
    },
)
  • tileOverlaysプロパティ
    サンプルコードの通り表示したいタイルをSet<TileOverlay>型で渡しています。
  • TileOverlay()ウィジェット
    表示するタイルを表すウィジェットです。
    実際に表示するタイルはtileProviderプロパティにProviderとして渡してあげる必要があります。

Providerは公式のサンプルを少しコンパクトにした下記を作成します。
GoogleMap()ウィジェットと同じファイルにコピペしてください。

import 'dart:ui' as ui;
import 'dart:typed_data';

class _DebugTileProvider implements TileProvider {//TileProviderを実装する。
  _DebugTileProvider() {
    boxPaint.isAntiAlias = true;
    boxPaint.color = Colors.blue;
    boxPaint.strokeWidth = 2.0;
    boxPaint.style = PaintingStyle.stroke;
  }

  static const int width = 100;
  static const int height = 100;
  static final Paint boxPaint = Paint();

  @override
  Future<Tile> getTile(int x, int y, int? zoom) async {
    final ui.PictureRecorder recorder = ui.PictureRecorder();
    final Canvas canvas = Canvas(recorder);
    //1.drawRectで四角形を作る
    canvas.drawRect(
        Rect.fromLTRB(0, 0, width.toDouble(), width.toDouble()), boxPaint);
    final ui.Picture picture = recorder.endRecording();
    final Uint8List byteData = await picture
        .toImage(width, height)
        .then((ui.Image image) =>
            image.toByteData(format: ui.ImageByteFormat.png)) //2.四角形をpngに変換
        .then((ByteData? byteData) => byteData!.buffer.asUint8List());//3.pngをUint8Listに変換
    return Tile(width, height, byteData);
  }
}

4行目の宣言の通り、TileProviderインタフェースのgetTile()関数を実装します。
getTile()関数の戻り値Tile()ウィジェットは縦(height)、横(width)、表示する画像をUint8List型にした
3つを渡す必要があります。

複雑そうなことをしておりますが、1.drawRectで四角形を作り、
2.それをpngに変換した後、3.Tileに渡すためにUint8List型に変換しているという流れです。

おわりに

google_maps_flutterパッケージの使い方の中でも今回は
Polygon()、Circle()、TileOverlay()についてご紹介しました。

次回の基礎編④はGoogleMapのイベント処理について書きたいと思います。

タイトルとURLをコピーしました