yasudacloudの日記

札幌に住むソフトウェアエンジニア

flutter_mapのtileProviderがもどかしい

たまには苦戦してる系の内容を発信したいと思います。

 

現在、個人プロダクトでflutter_mapを使用しています。

以前の記事でも少し紹介していますが、flutter_mapではマップのUIを簡単に実装することができ、地図以外の画像にすれば別の用途にも使える優れたライブラリです。

 

今はマップ表示するためのTileLayerOptionsにあるtileProviderで少し詰まっています。tileとは上記で言う所の、マップに用いられる画像の最小単位を指します。tileProviderでは1枚の画像を読み込むためのプロバイダーを設定することができます。

 

例えばNetworkTileProviderを使えばHTTPやHTTPSといったURL形式の画像を読み込むことができ、AssetTileProviderを使えばアプリ内にある画像を読み込むことができます。

 

今の私のプロダクトの機能要件には「URL形式の画像を読み込む」「アプリ内の画像を読み込む」の両方のパターンがあります。この場合はどちらのProviderでも実現することはできないのです。

仕方なく取った手段として、まずtileProviderにAssetTileProviderを使います。次に、読み込む画像を1x1の極めて小さい画像に設定して常にこの画像を参照するようにします。

そしてtileBuilderプロパティで任意のインターネット画像 or アプリ内画像を参照するようにします。具体的には下記のようにTileからレンダリングするx, y, z座標を取得できるため、こちらを判定条件にしています。

 

tileBuilder: (BuildContext context, Widget tileWidget, Tile tile) {
print(tile.coords.x);
print(tile.coords.y);
print(tile.coords.z);
return Image.network("https://hogehoge/");
}

他の方法だと全ての画像をNetworkTileProviderにしてバックエンド側で動的に判定して画像を出力するようなことが思いつきますが、どう考えてもパフォーマンスが悪いのでおすすめできません。404とかも多発しますし。

でも画像がほぼ変わらなくてマップの領域が狭いのであればCDN使うことで許容できる可能性がワンチャンあるかもしれません。

 

ライブラリ内のtile_provider.dartを追っかけるとCustomTileProviderというそれっぽいのがありますが、ここでうまい実装ができればなーとモヤモヤしています。