7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

NTTテクノクロスAdvent Calendar 2024

Day 5

【flutter】flutter_mapを使いこなす!

Last updated at Posted at 2024-12-04

はじめに

この記事は「NTTテクノクロス Advent Calendar 2024」の5日目の記事です。

こんにちは!NTTテクノクロスの沼田です。
現在、flutterで地図アプリの開発をしています。

今回は、実際に案件で使用しているライブラリや、苦労している点を踏まえ、flutter_mapをご紹介いたします。

flutter_map とは

・Flutterで地図を表示するためのライブラリ
・オープンソースのMAP-API(OSMなど)を使うのであれば基本無料で作成可能
・カスタマイズが豊富

こんな人におすすめ

・費用を抑えたい
・細かくカスタマイズしたい(詳細は後述)
・独自の地図データを使用したアプリを作成したい(詳細は後述)

flutter_mapで何ができるのか

地図の基本的な機能はもちろん、拡張も豊富なので、大抵のことは出来ます。
(GoogleMapのようなアプリが作成できます)

今回は、細かいカスタマイズ方法までご紹介します。

◾️ 地図の表示

オンライン地図、オフライン地図どちらの表示も可能。任意の地図タイル画像の表示も可能です。

例 )オフライン地図表示の例
  asset配下に置いた地図タイル画像を使用している公式サンプル
  bundled_offline_map.dart

◾️ 地図操作の制御

回転不可、操作可能範囲を設定といった基本的な制御は、 InteractionOptionsを使用します。

自分好みに細かい制御をカスタマイズする場合は、 InteractionOptionsを使用します

★ GoogleMapのように「拡大縮小時のみ回転なし」にしたい
以下設定で適用できます。

interactionOptions: const InteractionOptions(
 rotationWinGestures:
 	 MultiFingerGesture.pinchZoom | MultiFingerGesture.rotate,
 ),

◾️ ポリゴンやラインの表示

Polygon Layerを使用
自由にポリゴン表示ができます。

Polyline Layerを使用
画像はプロパティで点線にしています。点線の感覚をもう少し広げたかったのですが、現在間隔を設定できるプロパティは用意されていませんでした。
image.png

◾️ 地図マーカーの表示

Marker Layerを使用
画像やButtonをマーカーに設定できます。
画像のマーカーは、マーカーのアイコンと、テキストをColumnで並べて表示しています。

★ 指定した箇所を中心にマーカーを回転させたい場合
例えば、地図に以下の画像のようなマーカーを表示し、地図を回転させたとします。

image.png
デフォルトの設定だと、画像の中央を回転軸としてマーカーも回転するので、本来回って欲しい座標軸でマーカーが回転されず、マーカーの表示がずれてしまいます。
ピンの先っぽを回転軸としたい場合、alignmentのbottomCenterなどを使って好みの場所に座標軸を設定することで解消できます。

別ライブラリとの組み合わせで出来ること

◾️ 現在地・方向の表示

flutter_map_location_marker パッケージを使用
画像のように現在地を表示することが出来ます。現在地アイコンは自由にカスタマイズ可能です。

image.png

デフォルトでは位置情報を扱うGeolocatorパッケージと、端末の向きを取得するflutter_compassパッケージが使用されており、それらをもとに現在地が表示されています。

◾️ ヘディングアップ・ノースアップ

同じく、flutter_map_location_marker パッケージを使用
GoogleMapの右下にある現在地中心ボタンと同様の実装が可能で、端末の向きに従い、地図も回転させるといった制御が可能です。

◾️ アニメーションの追加

flutter_map_animationsパッケージを使用

flutter_mapのデフォルトのアニメーションは、カクカクした動きしか対応していません。本パッケージによって、滑らかなアニメーションをつけることが可能です

◾️ マーカーピンのクラスタリング

flutter_map_marker_clusterパッケージを使用
image.png

【iOSのみ】 flutter_map_location_markerについて

現在地の表示を行っているflutter_map_location_markerですが、
同じ画面でGeolocatorパッケージを使用して現在地の更新(getPositionStream)、取得(getCurrentPosition)を行うと、位置情報が更新されなかったり、現在地のちらつきが発生するといった事象がありました。

結果、Geolocatorではなく、Locationパッケージを使用するよう変更したことで対処しましたが、現在地を表示するCurrentLocationLayerが正常に描画されるかは、確認を行うのがいいと思いました。
記録用に、最終的にうまく描画できた時のCurrentLocationLayer

CurrentLocationLayer(
    positionStream: const LocationMarkerDataStreamFactory()
    .fromGeolocatorPositionStream(),
    .asBroadcastStream(),
    ....
)    

iOSは位置情報に注意

(flutter_mapとは直接関係ない話になります)

flutterで位置情報を扱うパッケージ(Geolocator、Locationなど)を使用する際は、Androidで問題なく動いても、iOS実機での検証は必須です。

連続で現在地を取得しない

連続で現在地取得を行うと、2回目以降取得できなくなることが多くあります。
こちらはissueに上がっています。(Geolocator)
https://github.com/Baseflow/flutter-geolocator/issues/1193

対策

1、位置情報の取得方法を変更する
getPositionStreamを使用して位置の更新を取得する実装に変更することで、頻繁にCurrentLocationを実行しないようにする。

2、最後に取得された既知の場所を取得するように変更する
getLastKnownPositionを使用して最後に取得した位置情報を返す実装に変更する。
インターバルを設けて、指定秒数以内に取得できない場合はgetLastKnownPositionを使う、といった実装になるかと思います。

開発中のアプリでは、信憑性の高い現在地が必要だったので1を採用しました。

最後に

ざっとflutter_mapの紹介をしましたが、やろうと思えばGoogleMapと似たようなアプリの作成は可能です。

無料で簡単に使えるので、お試しで使いたい方は是非公式を参考にしてみてください。

繰り返しにはなりますが、位置情報周りの実装はAndroidとiOSそれぞれの実機で、こまめに、検証を行いながら開発することをおすすめします。

7
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
7
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?