はじめに
ここ最近、Twitter(旧X)のGISクラスタの間でモダンなベクターファイルフォーマットに関しての言及を見かけました。モダンなフォーマットは様々あるなか、脱シェープ!とは言うものの「どこに行けば」という問いに対しては十人十色のアンサーを持っている状態だと思います。本記事では、主な選択肢を紹介してみて、筆者の意見を述べます。
ESRI Shapefile
ESRI社の名を冠する、歴史あるファイルフォーマット。現在でも世界で最も広く使われている形式でしょう。歴史があるゆえ、大概のGISソフトウェアがサポートしているというメリットがありつつ、下記のような典型的なデメリットがあります・
- shp/shx/dbf、また様々なオプショナルなファイル群と「まとめて」使わなければならない
- 各ファイルについて2GBというファイルサイズ上限がある
- 任意の文字コードをサポートしている(文字化けの原因であり、昨今はUTF-8に統一が進んでいる)
これらのデメリットを解決できるフォーマットが多数存在している昨今、新たに作成・頒布するデータがESRI Shapefileである必要はないでしょう。ただし頒布においては「そのフォーマットが一般に利用可能であるか」という点には留意すべきです(ただし無料で利用できるQGISで読めるならリスクはないと考えます)。
以降、ESRI Shapefileを代替しうるファイルフォーマットをいくつか紹介します。
モダンなフォーマットたち
GeoJSON
所定の構造をもつJSON形式のテキストフォーマットです。以下のようなJSONファイルのことを特にGeoJSONと呼んでいます。
{
"type": "FeatureCollection",
"features": [{
"type": "Feature",
"geometry": {
"type": "Point",
"coordinates": [102.0, 0.5]
},
"properties": {
"prop0": "value0"
}
}]
}
平文ゆえ相互運用性は高い一方、圧縮効率などのパフォーマンスは他のフォーマットに大きく劣ります。なので大きなデータの保管には向いておらず、REST-APIをはじめとして、Webアプリケーションでよく利用されます。
GeoPackage
QGISにおけるデフォルトのファイルフォーマットです。SQLiteを拡張した形式であるためデータの取り出しで有利なうえ、「空間インデックス」をサポートしているため、一部領域のデータの抽出を得意とします。
参考
FlatGeobuf
Cloud Optimizedなベクター形式のファイルフォーマットです。GeoPackageと同様、空間インデックスを持つため一部領域のデータの抽出が有利なうえ、この行為を「リモートサーバーにあるFlatGeobufに対して(=HTTPリクエストを通じて)」実行出来るという、Cloud Optimized形式としての利点を持っています。これにより、元データが巨大だったとしても、その一部分のデータを最小の通信で取得することが可能となります(demo。
GeoParquet
Apache Parquet形式をベースに、Geometry型に関する仕様を追加しているものです。Geometryは所定のカラムにWKB形式で保存され、そのカラムに関する情報をParquetのメタデータとして保持するというつくり。列志向フォーマットゆえの高効率性の恩恵を受けられるうえ、DuckDBとの高い親和性があります。Overture MapsやFoursquareが公開したデータセットなどの大規模データの配信に用いられていることを観測しています。ただし「空間インデックスは持っていない」という点には注意が必要です。なので、たとえば「GISソフトウェアで大きなデータの一部分だけを描画する」というタスクでは、他の空間インデックスを持つフォーマットよりも遅い可能性があります。
注意点として、QGISでもmacOS版だとこの形式を開けないという問題があります。
GeoParquetはv1.1で地物のbboxを保持するなどの最適化が入っており、ソフトウェア側の対応が進むと読み出し性能が改善しそうです。今後も動向を注視したいですね。@yoshizowさん情報提供ありがとうございました。
https://medium.com/radiant-earth-insights/geoparquet-1-1-coming-soon-9b72c900fbf2
番外編:タイルストレージ
タイルストレージの形式を紹介する前にまず、もしかしたらあるかもしれない「PMTilesなどのタイル形式があればほかのフォーマットはいらないのでは」という誤解に対して、「地図タイルは不可逆圧縮である」という理解を持つ必要があると述べます。ベクトルタイルについていうと、たとえば座標については各タイル内で(デフォルトで)4096x4096の格子点にエンコードされますし、細かすぎる頂点(あるいは地物まで!)が間引かれます。タイル形式とその他のフォーマットを単純比較することは出来ないということでした。
作り方は下記を参照してください
ディレクトリ形式
./tiles/0/0/0.pbf
./tiles/1/0/0.pbf
./tiles/1/0/1.pbf
...
タイルを「1タイル1ファイル」として保存する手法。配信インフラがシンプルで安く済む一方、ファイルのアップロードコストが大きく、取り回しづらいので、PMTiles全盛の昨今では利用されることがめっきり少なくなっている。
MBTiles
1ファイルにすべてのファイルを格納したフォーマット。SQLiteをバックエンドとしている。タイルサーバーを作るときに利用すべきファイルフォーマット第1位…だったが、PMTiles全盛の昨今では利用されることがめっきり少なくなっている。
PMTiles
Cloud Optimizedなタイルストレージです。Cloud Optimizedの特徴は「HTTPリクエストで巨大なデータの一部分を取り出せること」です。これはタイル配信と非常に相性が良く、というのはタイルはそれ自体が分割済みの「チャンク」であるため、HTTPリクエストで部分取得する際のオーバーヘッドが小さく、機能面でのデメリットがほぼありません(Cloud Optimized形式はクライアント・サーバー間で多くのリクエスト・レスポンスが発生するため、パフォーマンスに気を付けなければなりませんが、PMTilesはそういうことがない)。その他のファイルフォーマットと比べ運用コストが非常に小さくなる一方で乗り換えが容易なので、ここ1,2年で広く普及しました。
じゃあどれを使おうか?
タイル形式ならPMTiles一択でよいでしょう。ただしPMTilesファイルをパブリックに晒すことを私はあまりお勧めしておらず(PMTiles自体がダウンロードされてしまう・PMTilesのクライアント実装が必要)、何らかのサーバーを書くのがよいと考えています。開発元のProtomapsがAWSなどでの実装方法を示しているので、実装は難しくありません(コストはストレージ代くらいでしょう)。
保管形式としてですが、QGISを利用してデータを閲覧したり編集するならGeoPackageをお勧めします。SQLiteバックエンドゆえのデータ読み書きのパフォーマンスや、空間インデックスがあることと、表形式ゆえDuckDBやその他のツールで操作する際に便利だとかなどの理由です。それ以外で、DuckDBでデータをコネコネするときや、空間インデックスよりも優先すべきことがある場合(ファイルサイズなどで)は、GeoParquetを利用するのがよいでしょう。高いパフォーマンスが得られるはずです。
その他「巨大なデータから」「一部のデータを」「無劣化で」「サーバーレス環境下で」「配信したい」場合などはFlatGeobufを利用すると幸せになれるかもしれません。