【Flutter】Google Maps上に線を引く為にPolylineを試してみる
概要
Google Maps上にPolylineで線を描画する際に、Flutterでどのように実装するかを試してみたいと思います。
方法
どうやら調べた所以下の2つのPubがひっかかったので、それぞれを試して比較してみたいと思います。
- google_maps_flutter で polyline を指定する方法
- flutter_polyline_points パッケージを使う方法
google_maps_flutter で polyline を試す
早速 google_maps_flutter
の poyline
を試してみたいと思います。
パッケージインストール
dependencies:
google_maps_flutter: ^2.7.0
まずはMapを表示するだけの画面を作成
google_maps_flutter_polyline.dart
を以下内容で作成します。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class GoogleMapsFlutterPolyline extends StatefulWidget {
const GoogleMapsFlutterPolyline({super.key});
State<GoogleMapsFlutterPolyline> createState() =>
GoogleMapsFlutterPolylineState();
}
class GoogleMapsFlutterPolylineState extends State<GoogleMapsFlutterPolyline> {
final Completer<GoogleMapController> _controller =
Completer<GoogleMapController>();
static const CameraPosition _initialCameraPosition = CameraPosition(
target: LatLng(35.68123428932672, 139.76714355230686),
zoom: 14.4746,
);
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Google Maps Flutter Polyline')),
body: GoogleMap(
mapType: MapType.normal,
initialCameraPosition: _initialCameraPosition,
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
),
);
}
}
実行すると以下のようなMapが表示されるだけの画面が表示されるかと思います。
実際にPolylineを使ってみる
次に本題のPolylineを使って線をひいてみたいと思います。google_maps_flutter_polyline.dart
を以下に修正します。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class GoogleMapsFlutterPolyline extends StatefulWidget {
const GoogleMapsFlutterPolyline({super.key});
State<GoogleMapsFlutterPolyline> createState() =>
GoogleMapsFlutterPolylineState();
}
class GoogleMapsFlutterPolylineState extends State<GoogleMapsFlutterPolyline> {
final Completer<GoogleMapController> _controller =
Completer<GoogleMapController>();
static const CameraPosition _initialCameraPosition = CameraPosition(
target: LatLng(35.68123428932672, 139.76714355230686),
zoom: 14.4746,
);
final Set<Polyline> _polylines = {};
void initState() {
super.initState();
_setPolylines();
}
void _setPolylines() {
setState(() {
_polylines.add(
const Polyline(
polylineId: PolylineId('polyline_1'),
points: [
LatLng(35.681236, 139.767125),
LatLng(35.680959, 139.767552),
LatLng(35.680583, 139.767998),
],
color: Colors.red,
width: 5,
),
);
_polylines.add(
const Polyline(
polylineId: PolylineId('polyline_2'),
points: [
LatLng(35.681236, 139.767125),
LatLng(35.682839, 139.769435),
LatLng(35.683342, 139.770674),
],
color: Colors.green,
width: 5,
),
);
_polylines.add(
const Polyline(
polylineId: PolylineId('polyline_3'),
points: [
LatLng(35.681236, 139.767125),
LatLng(35.680178, 139.766273),
LatLng(35.679694, 139.765451),
],
color: Colors.blue,
width: 5,
),
);
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Google Maps Flutter Polyline')),
body: GoogleMap(
mapType: MapType.normal,
initialCameraPosition: _initialCameraPosition,
polylines: _polylines,
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
),
);
}
}
こちらを実行すると以下の様に3つの異なる色のラインが表示されるかと思います。
Polylineクラス
サンプルの実装を見ていただけると分かるように、 Polyline
の Set を GoogleMap
クラスの polylines
に設定する事で線を描画してくれます。
設定する主なプロパティは以下になります。
- polylineId
- PolylineId を指定します
- PolylineIdは
これはグローバルに一意である必要はなく、リスト内で一意であるだけで十分です
とあるように、Polyline
の Set 内でユニークになれば良いみたいです
- points
- 描画するポリラインの頂点で
List<LatLng>
を指定します
- 描画するポリラインの頂点で
- color
- 線分の色を ARGB フォーマットで指定
- width
- 描画する線分の幅
点線にする
pattens
に PatternItem の dash を設定してやると点線にする事ができます。
Polyline(
// ...
patterns: [PatternItem.dash(20), PatternItem.gap(20)], // ←追加
),
上記の意味として20pxで赤線を引いて、20pxの空白を作るのを繰り返し点線にしてます。
flutter_polyline_points で polyline を試す
次は flutter_polyline_points
を試してみたいと思います。
パッケージインストール
dependencies:
flutter_polyline_points: ^2.0.1
実際に使ってみる
flutter_polyline_points.dart
というファイル名で以下内容で作成します。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_polyline_points/flutter_polyline_points.dart';
import 'package:google_maps_flutter/google_maps_flutter.dart';
class FlutterPolylinePoints extends StatefulWidget {
const FlutterPolylinePoints({super.key});
State<FlutterPolylinePoints> createState() => FlutterPolylinePointsState();
}
class FlutterPolylinePointsState extends State<FlutterPolylinePoints> {
final Completer<GoogleMapController> _controller =
Completer<GoogleMapController>();
static const CameraPosition _initialCameraPosition = CameraPosition(
target: LatLng(35.68123428932672, 139.76714355230686),
zoom: 14.4746,
);
final Set<Polyline> _polylines = {};
final PolylinePoints polylinePoints = PolylinePoints();
void initState() {
super.initState();
_setPolylines();
}
void _setPolylines() async {
PolylineResult result = await polylinePoints.getRouteBetweenCoordinates(
request: PolylineRequest(
origin: const PointLatLng(26.48424, 50.04551),
destination: const PointLatLng(26.46423, 50.06358),
mode: TravelMode.walking,
wayPoints: [PolylineWayPoint(location: "Sabo, Yaba Lagos Nigeria")],
),
googleApiKey: 'YOUR_API_KEY',
);
if (result.points.isNotEmpty) {
setState(() {
_polylines.add(
Polyline(
polylineId: const PolylineId('polyline_1'),
points: result.points
.map((p) => LatLng(p.latitude, p.longitude))
.toList(),
color: Colors.red,
width: 5,
),
);
});
}
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('FlutterPolylinePoints')),
body: GoogleMap(
mapType: MapType.normal,
initialCameraPosition: _initialCameraPosition,
onMapCreated: (GoogleMapController controller) {
_controller.complete(controller);
},
polylines: _polylines,
),
);
}
}
googleApiKey
には事前に取得したAPI Keyを設定します。↑を実行すると↓の様になります。
このパッケージがGoogle Maps Platformの Routes API を使っているようで、
事前にfrom-toの位置を指定し、その間のルートを計算して各pointを配列で返してくれる様です。
flutter_polyline_points
自体がPolylineをひいてくれるという訳ではなく、google_maps_flutter
でPolylineを引くためのpointsを計算してくれるという様な位置付けのPubの様でした。
まとめ
基本は google_maps_flutter
を使って、特定の地点間のルートを求めたいなどの要求が出た場合に flutter_polyline_points
を使えば良さそうかなという感想でした。
参考URL
Discussion