フリーダムの日記

GIS(地理情報システム)を中心に技術的なことを書いています。

GDAL と felt の tippecanoe を使用してファイルジオデータベースから PMTiles を作成

はじめに

オープンソース系の GIS 界隈では Cloud Optimized が重要なキーワードになっているようです。以前の記事では、Cloud Optimized の GeoTIFF (COG) についての記事「ArcGIS で Cloud Optimized GeoTIFF (COG) を触ってみる 」について紹介しました。今回は、Cloud Optimized 形式のうち PMTiles(ベクトルタイル)の作成について紹介していきたいと思います。PMTiles の作成方法については、すでに多くの方が試されているようでして、色々なブログ等で紹介されているのを確認することができます。幾つか紹介されているなかで、shi_works さんの「ベクターデータから PMTiles を生成する方法」を参考にさせていただきました。非常に分かりやすく、まとめられています。

zenn.dev

PMTiles の作成では、国土交通省が G 空間情報センターにてオープンデータとして公開している 3D 都市モデル PLATEAU の建築物データ(LOD1)から PMTiles を作成しました。建築物データ(LOD1)は 2020 年の岐阜県のデータを使用しました。また、PMTiles は国土地理院からも最適化ベクトルタイル試験公開ということで、2023 年 8 月 30 日に PMTiles 形式の最適化ベクトルタイルを試験公開されていたりと注目されているのが分かります。

github.com

PMTile について

PMTiles そのものについては、多くの方がブログなどでも共有していますので、そちらを確認していただければと思います。

Protomaps Docs のコンセプトによると PMTiles は、Z/X/Y 座標で指定されたタイル状データの一般的なフォーマットで、ベースマップなどのベクタータイル、リモートセンシングの観測データ、JPEG 画像などです。

PMTiles リーダーは HTTP Range Requests を使って、PMTiles アーカイブ内の関連するタイルやメタデータのみをオンデマンドで取得します。

タイルとディレクトリの配置は、パンやズーム時のオーバーヘッドのリクエストを最小限に抑えるように設計されています。

PMTiles の現在の仕様バージョンはバージョン 3 で、GitHub で確認することができます。

全体の流れ

大まかな流れは、ファイルジオデータベースから FlatGeobuf を作成して、FlatGeobuf から PMTiles を作成しています。ファイルジオデータベースから FlatGeobuf の作成では GDAL の ogr2ogr コマンドを使用し、FlatGeobuf から PMTiles の作成には tippecanoe を使用しました。

FGDB から PMTiles の作成

PMTiles の表示は、オープンソースの地図ライブラリ MapLibre GL JS を使用しました。背景地図には、ArcGIS のロケーションサービスを使用しました。ArcGIS のロケーションサービスも無償から利用することができます。

PMTiles - ArcGIS

いずれもすべてオープンソースのツールで実行することができます。

環境構築

PMTiles の作成にあたって、GDAL や tippecanoe をインストールする必要がありますが、手軽にかつスピーディに実行環境を構築する上でも便利な Docker を使用しました。tippecanoe と GDAL は Docker のイメージは公開されていますので、簡単にイメージからコンテナを作成できます。

tippecanoe Docker イメージ作成

git clone https://github.com/felt/tippecanoe.git   
cd .\tippecanoe\     
docker build -t tippecanoe:latest .   

github.com

GDAL Docker イメージ作成

docker pull ghcr.io/osgeo/gdal:alpine-normal-latest

GDAL の Docker イメージ は幾つか用意されています。 github.com

イメージの確認

以下のコマンドでイメージが作成されていることを確認できます。

$ docker image ls
REPOSITORY           TAG                    IMAGE ID       CREATED        SIZE
tippecanoe           latest                 b9ae62fd276c   5 hours ago    164MB
ghcr.io/osgeo/gdal   alpine-normal-latest   36d826050fec   2 weeks ago    410MB

ファイルジオデータベースから FlatGeobuf の作成

3D 都市モデル(Project PLATEAU)岐阜市(2020年度)からファイルジオデータベースをダウンロードします。ダウンロードした 21201_gifu-shi_fgdb.7z ファイルを解凍します。解凍したファイル(21201_gifu-shi.gdb)は、約 1.77 GB のサイズになります。

ファイルジオデータベースについては以下の GIS 基礎解説が参考になります。 www.esrij.com

FlatGeobuf 作成するにあたり、ファイルジオデータベースには複数のレイヤーが含まれており、該当のレイヤーから作成する必要があるため、レイヤー名の一覧を確認する必要があります。以下の ogrinfo コマンドでファイルジオデータベースのレイヤ名ーを確認することができます。

PS C:\Work\pmtiles> docker run --rm -v ${PWD}:/pmtiles ghcr.io/osgeo/gdal:alpine-normal-latest ogrinfo pmtiles/21201_gifu-shi.gdb
INFO: Open of `pmtiles/21201_gifu-shi.gdb'
      using driver `OpenFileGDB' successful.
Layer: lod2_Building (3D Multi Polygon)
Layer: lod1_Building (3D Multi Polygon)
Layer: lod0_Building (3D Multi Polygon)
Layer: lod2_RoofSurface (3D Multi Polygon)
Layer: lod2_WallSurface (3D Multi Polygon)
Layer: lod2_GroundSurface (3D Multi Polygon)
Layer: lod1_Road (3D Multi Polygon)
Layer: lod1_TinRelief (3D TIN)
Layer: lod0_UrbanPlan (3D Multi Polygon)
Layer: lod0_AreaClassification (3D Multi Polygon)
Layer: lod0_DistrictAndZones (3D Multi Polygon)
Layer: lod1_LandUse (3D Multi Polygon)

その他、ファイルジオデータベースの中身については、ArcGIS Pro などの ArcGIS 製品を使用することで簡単に確認できるかと思います。

今回使用するデータは、建築物データ(LOD1)ですので、レイヤー名が「lod1_Building」のデータを使用します。ファイルジオデータベースから FlatGeobuf の作成には、GDAL の ogr2ogr を使用します。以下のコマンド ogr2ogr -f FlatGeobuf 出力ファイル 入力ファイル レイヤー名 を指定して、ファイルジオデータベースから FlatGeobuf を作成します。

PS C:\Work\pmtiles> docker run --rm -v ${PWD}:/pmtiles ghcr.io/osgeo/gdal:alpine-normal-latest ogr2ogr -f FlatGeobuf pmtiles/21201_gifu-shi_lod1_Building.fgb pmtiles/21201_gifu-shi.gdb lod1_Building

FlatGeobuf から PMTiles の作成

FlatGeobuf から PMTiles の作成には felt の tippecanoe を使用します。以下のコマンドを実行します。

PS C:\Work\pmtiles> docker run -it --rm -v ${PWD}:/pmtiles tippecanoe:latest tippecanoe -o /pmtiles/21201_gifu-shi_lod1_Building.pmtiles -Z10 -z18 /pmtiles/21201_gifu-shi_lod1_Building.fgb -pf -pk -P
For layer 0, using name "21201_gifushi_lod1_Buildingfgb"
detected indexed FlatGeobuf: assigning feature IDs by sequence
251941 features, 100340746 bytes of geometry and attributes, 307188731 bytes of string pool, 0 bytes of vertices, 0 bytes of nodes
  61.1%  11/1801/808 

FlatGeobuf と PMTiles のファイルサイズを確認すると PMTiles の方が小さいことが分かります。

  • 21201_gifu-shi_lod1_Building.fgb:727 MB
  • 21201_gifu-shi_lod1_Building.pmtiles:272 MB

tippecanoe で使用するコマンド オプションについては、ベクターデータからPMTiles を生成する方法の「FlatGeobuf から PMTiles を生成」を参考にしました。

-P:並列読み込み
 入力ファイルが GeoJSONSeq(行区切りGeoJSON)の場合、-P をつけるだけで、入力ファイルの読み込みが並列化されます。
-pf:地物数制限を無視する(1 タイルあたり 200,000 フィーチャに制限しない)
-pk:ファイルサイズ制限を無視する(1 タイルあたり 500 K バイトに制限しない)
-z, -Z:ズームレベル指定
 -Z2 -z10 とすると、ズームレベル 2 - 10 の範囲でタイルを生成します。指定しない場合は自動的に設定されます。大文字の Z が最小ズーム、小文字の z が最大を示すことに注意が必要です。

その他、ベクトルタイルのつくりかた(2022年版)も参考にさせていただきました。 qiita.com

作成した PMTiles の確認

作成した PMTiles の確認には、PMTiles Viewer が便利です。 protomaps.github.io

PMTiles をドラッグ & ドロップすることで、フィーチャ の表示を確認することができます。

PMTiles - ArcGIS

また、shi-works さんが作成した PMTiles と MapLibre GL JS で作成したデモサイトを下記の GitHub にて公開しているため、MapLibre GL JS も参考にて使用させていただきました。 PMTiles は通常は S3 などのストレージに配置することになるのですが、今回はローカルに配置して使用しました。

github.com

MapLibre GL JS で PMTiles を以下のように表示することができました。 MapLibre GL JS - ArcGIS

背景地図だけは、Esri 社の ArcGIS を使用しました。背景地図のスタイルは、道路地図やナビゲーションなど様々なスタイルの地図を利用することができます。今回はこちらの Outdoor Map を使用しました。language パラメータとして ja を指定することで、日本語表記のラベルを表示することもできます。
その他、多くの背景地図のスタイルを提供しています。背景地図のスタイルや言語などの詳細は Basemap styles service (v2) を参照してください。また、実装方法については、チュートリアルDisplay a map が参考になるかと思います。

// PLATEAU ベクトルタイル
let PMTiles_URL = "./21201_gifu-shi_lod1_Building.pmtiles";

// APIKey を指定
const apiKey = "API Key";

const basemapEnum = "arcgis/outdoor";
const map = new maplibregl.Map({
  container: "map", // the id of the div element
  style: `https://basemapstyles-api.arcgis.com/arcgis/rest/services/styles/v2/styles/${basemapEnum}?token=${apiKey}&language=ja`,
  zoom: 15, // starting zoom
  center: [136.7606, 35.4232], // starting location [longitude, latitude]
  hash: true,
  pitch: 76,
  maxPitch: 85,
  bearing: -115.2,
  attributionControl: false
}).addControl(
  new maplibregl.AttributionControl({
    compact: true // reduces the copyright attributions view
  })
);

最後に

ようやく、PMTiles について触れることができました。これまでのベクトルタイルなどをひとつのファイルとして扱えるようになったのはとても便利だと思いました。PMTiles の作成に関してもそれほどハードルは高くはなく、フリーのツールでここまできてしまうのはすごいと思いました。ラスタータイルや複数の FlatGeobuf から PMTiles も作成することができるようですので次回はそれらも試してみたいと思います。

以上、参考となれば幸いです。