Flutterでバイナリベクトルタイルを描画
FlutterのCustomPaintでバイナリベクトルタイルを描画します。
バイナリベクトルタイルを使ってみたいと思った経緯
不動産取引情報APIを見ているとバイナリベクトルタイルを返すAPIがありました。取引情報を地図上に表示することができます。GeoJSONという形式もあるようですが、バイナリベクトルタイルの方がサイズが小さくなりそうかなと思い、バイナリベクトルタイルにしました。ただし、日本地図のバイナリベクトルタイルの提供が実験中となっています。詳しくはリファレンスの国土地理院のサイトを確認してください。
次に、バイナリベクトルタイルを扱うパッケージがあるか探しました。地図を扱うパッケージでflutter_mapが有名ですが、バイナリベクトルタイルをサポートしていません。flutter_mapにバイナリベクトルタイルを扱うためのvector_map_tilesというプラグインもありますが、あまり更新されてないように見えました。
ということで、CustomPaintを使って自分で描画してみることにしました。
リファレンス
- バイナリベクトルタイル
- Webの参考にさせていただいた記事
protocol buffers
バイナリベクトルタイルはプロトコルバッファで定義されます。まずはDartでプロトコルバッファを扱えるようにします。
Dartのチュートリアル
以下の公式チュートリアルに従って、チュートリアルのデータモデル addressbook.proto の書き込み/読み出しができることを確認しました。
https://protobuf.dev/getting-started/darttutorial
困ったところをメモしました。
- addressbook.protoをDart向けにコンパイルするときに”protoc_plugin”というDartのパッケージが必要。以下のコマンドでインストールできる。
- dart pub global activate protoc_plugin
- addressbook.protoをコンパイルするとdartのファイルが出力されるが、コンパイルエラーが出力されている。以下の対応が必要。
ベクトルタイルのprotoをコンパイル
ベクトルタイルのprotoも同じ要領で扱うことができます。
コンパイルしてテストしたコードが以下になります。
https://github.com/ohmusso/map_app/tree/main/vecmap
一つ注意点があります。以下のzigzagデコード関数で使用するxor演算がFlutter Webのjavascriptに変換されたときに正しく動作しませんでした※1。stackoverflowにあった対策コードで実装しています。Flutterでビット演算をするときは気をつける必要があります。
※1 戻り値をint型で定義したのに戻り値がUInt32で扱われてしまう。
バイナリベクトルタイルの描画
まずは一つのタイルを描画してみます。
ソースコードは以下になります。
https://github.com/ohmusso/map_app/tree/main/app_map
assets/11_1796_811.pbfに描画するタイルを置いています。京都市を表示するタイルです。
タイルの読み込み
以下のgetTileFromPbfでassetsフォルダに置いたタイルを読み込みます。将来的にhttps://cyberjapandata.gsi.go.jp/xyz/experimental_bvmap/{z}/{x}/{y}.pbfにアクセスして必要なタイルを読み込みます。
CustomPaintでタイルを描画
以下のコードでタイルを描画しています。
いろいろと未対応です。
- 一部のレイヤでエラーが出力されたのでコメントアウトしています。
- 線の色は適当です。地図のスタイルを規定したjsonがあるので、これを読み込んで描画する必要があります。