GDALでタイル画像を作る

gdal

先日、GDALなるライブラリを使ってGeoJSONファイルをGoogle Mapに埋め込み表示するためのタイル画像に変換する方法を調べる機会がありました。

GDAL(Geospatial Data Abstraction Library)とは、ラスターおよびベクター地理空間情報データフォーマットのための変換用ライブラリです。

https://gdal.org/

またGeoJSONは、JSONを用いて空間データをエンコードし非空間属性を関連付けるためのもので、簡単に言うとある3次元の空間情報を、点や線、ポリゴンなどの2次元の情報を羅列して管理するためのフォーマットです。

今回はそのGeoJSONに埋め込まれた空間情報(以下、ベクター)を、GDALを用いてタイル画像に変換する方法を紹介します。

必要なもの

  • GDAL(バージョン2.4.4以上)
  • GDAL python(GDALのバージョンに対応したもの)
  • Python(GDAL pythonのバージョンに一致するもの)

1.GeoJSONをラスタ化する

まず、”gdal_rasterize”コマンドでGeoJSONのベクターをラスタ画像に変換します。

gdal_rasterize -ot Byte -a zindex -ts 4950 4090 -init 0 <変換元GeoJSON> <変換先Tiff>
  • -ot …Gtiffに出力するデータ型を指定。
  • -a … Gtiffに書き込む属性フィールド名を指定。
  • -ts … 出力ファイルのサイズをピクセルで設定。
  • -init … 出力画像の初期値を設定。
  • <変換元GeoJSON> … GeoJSONファイルをパス付で設定。
  • <変換先Tiff> … ラスタ変換出力ファイルをパス付で設定。

2.ラスタ画像をフルカラーに変換する

2.1 VRTファイルを生成する

1.で変換したラスタ画像のままでは、GeoJSONに埋め込まれたカラー情報が反映されず白黒画像となってしまいます。そのため、”gdalbuildvrt”コマンドでカラー情報をラスタ画像に埋め込むためのVRTファイルを生成します。

gdalbuildvrt -srcnodata 0 <出力VRT> <ラスタ画像>
  • -srcnodata … ラスタ画像をタイル画像に変換時に使用する初期値を設定。
  • <出力VRT> … 出力するVRTファイルをパス付で設定。
  • <ラスタ画像> … 1.で出力したラスタ画像をパス付で設定。

2.2 VRTにカラーテーブルを追加する

生成したVRTファイルにGeoJSONの色情報に基づいたカラーテーブルを編集します。

編集前

…
<ColorInterp>Gray</ColorInterp>
<ComplexSource>
…

編集後

…
<ColorInterp>Palette</ColorInterp>
<ColorTable>
   <Entry c1="0" c2="0" c3="0" c4="0" />
   <Entry c1="255" c2="0" c3="0" c4="0" />
   <Entry c1="0" c2="255" c3="0" c4="0" />
   <Entry c1="0" c2="0" c3="255" c4="0" />
</ColorTable>
<ComplexSource>
…

2.3 ラスタ画像をフルカラーに変換する

“gdal_translate”コマンドで編集したカラー情報をラスタ画像に埋め込みます。

gdal_translate -expand <VRT> <カラーラスタ画像>
  • -expand … 公開する色形式を設定。
  • <VRT> … カラーテーブルを編集したVRTファイルをパス付で設定。
  • <カラーラスタ画像> … 出力するラスタ画像をパス付で設定。

3.ラスタ画像をタイル画像に変換

最後に、”gdal2tiles.py”コマンドでフルカラーになったラスタ画像をタイル画像に変換します。

gdal2tiles.py --zoom=8-16 -r antialias <カラーラスタ画像> <タイル出力先フォルダ>
  • --zoom … タイル画像を生成するズームレベルの範囲を設定。
  • -r … サンプリングの方法を設定
  • <カラーラスタ画像> … タイル画像にしたいラスタ画像をパス付で設定。
  • <タイル出力先フォルダ> … タイル画像の出力先ディレクトリを設定。

最後に

GeoJSONのベクターをラスタ化するところまでは割と早くたどり着いたのですが、カラー情報を保ったままの状態にするまでがかなり時間がかかってしまいました。ちなみに、今回はGeoJSONのzindex属性ごとに色情報が異なっていたので上記の方法でフルカラーでタイル化できましたが、色情報がzindexで分けられていない場合はどうしたらいいのか、もっと調べる必要がありそうです。

機会があれば、調べてみたいと思います。

以上