Cloud Optimized GeoTIFF (COG)による航空写真GeoTiffのレンダリングの高速化
- 425枚の航空写真タイルをVRTでモザイク化し、無圧縮GeoTIFF・JPEG圧縮GeoTIFF・COG形式の3パターンで書き出し比較
- ファイルサイズは無圧縮3.87GB→圧縮245MB(約1/16)→COG 466MB(約1/9、圧縮のみの約1.8倍)
- QGISでのレンダリング速度は「圧縮GeoTIFF < 無圧縮GeoTIFF < COG」の順で、COGが内部タイル化とオーバービューにより広域・ズームアウト表示時に圧倒的に高速

はじめに
航空写真をGISソフトで扱う際、ファイルサイズが大きくなるほど表示が遅くなる問題に直面する。今回は425枚のオルソ化済み航空写真タイル※(1枚2000×1500px、解像度0.2m/px、座標系EPSG:6676)を1枚のGeoTIFFに統合し、通常のGeoTIFF・圧縮GeoTIFF・Cloud Optimized GeoTIFF (COG) の3パターンで書き出し、ファイルサイズと表示速度への影響を比較した。
※VIRTUAL SHIZUOKA 静岡県 中・西部 点群データ LPデータ オルソ画像データより取得
Cloud Optimized GeoTIFFとは
詳細は過去記事参照
COGは通常のGeoTIFFフォーマットの内部構造を工夫したもので、次の2つの特徴を持つ。
- 内部タイル化:画像をストリップではなく小さな正方形タイル単位で格納するため、画面に表示されている範囲のタイルだけを読み込める
- オーバービュー(低解像度版)の内蔵:縮小した解像度のピラミッド画像をあらかじめファイル内に持たせることで、広域表示・ズームアウト時にフル解像度のデータを読む必要がない
この2つにより、GISソフトやWebブラウザはファイル全体をダウンロード・デコードすることなく、必要な部分だけをHTTP Range Requestや部分読み込みで取得できるため、表示が速くなる。
手順
ソースコードのファイルはこちら
1. 個別タイルをVRTでモザイク化
425枚のtifをまとめて仮想的な1枚の画像(VRT)として扱う。
※originalフォルダに425枚のtifが入っている
gdalbuildvrt -srcnodata -9999 -vrtnodata -9999 -a_srs EPSG:6676 photo.vrt original/*.tif
from osgeo import gdal import glob import os fpath = r"original" g = glob.glob(os.path.join(fpath, '*.tif')) gdal.UseExceptions() d = gdal.BuildVRT( 'photo.vrt', g, srcNodata=-9999, VRTNodata=-9999, outputSRS='EPSG:6676' ) d = None
2. 通常のGeoTIFFに書き出し(無圧縮・比較基準)
※処理時間がかなり長いので注意
gdal_translate -of GTiff photo.vrt photo.geotiff
from osgeo import gdal gdal.UseExceptions() translate_options = gdal.TranslateOptions(format="GTiff") d = gdal.Translate( destName='photo.geotiff', srcDS='photo.vrt', options=translate_options ) d = None
3. JPEG圧縮付きGeoTIFFに書き出し
※処理時間がかなり長いので注意
gdal_translate -of GTiff -co COMPRESS=JPEG -co QUALITY=85 -co PHOTOMETRIC=YCBCR photo.vrt photo_compressed.geotiff
from osgeo import gdal gdal.UseExceptions() translate_options = gdal.TranslateOptions( format="GTiff", creationOptions=[ "COMPRESS=JPEG", "QUALITY=85", "PHOTOMETRIC=YCBCR" ] ) d = gdal.Translate( destName='photo_compressed.geotiff', srcDS='photo.vrt', options=translate_options ) d = None
4. COG形式(JPEG圧縮+タイル+オーバービュー)に書き出し
※処理時間がかなり長いので注意
gdal_translate -of COG -co COMPRESS=JPEG -co QUALITY=85 -co PHOTOMETRIC=YCBCR photo.vrt photo_cog.geotiff
from osgeo import gdal gdal.UseExceptions() translate_options = gdal.TranslateOptions( format="COG", creationOptions=[ "COMPRESS=JPEG", "QUALITY=85", "PHOTOMETRIC=YCBCR" ] ) d = gdal.Translate( destName='photo_cog.geotiff', srcDS='photo.vrt', options=translate_options ) d = None
-of COG を指定するだけで、gdal_translateが内部タイル化とオーバービュー生成を自動的に行ってくれる。
結果:ファイルサイズの比較
| ファイル | フォーマット | サイズ | 無圧縮比 |
|---|---|---|---|
| photo.geotiff | GeoTIFF(無圧縮) | 約3.87 GB (4,158,504,411 bytes) | 1.0倍 |
| photo_compressed.geotiff | GeoTIFF(JPEG圧縮) | 約245 MB (256,875,773 bytes) | 約1/16 |
| photo_cog.geotiff | COG(JPEG圧縮+タイル+オーバービュー) | 約445 MB (466,309,368 bytes) | 約1/9 |
JPEG圧縮だけで無圧縮の約16分の1までサイズが縮む。COGはこれにオーバービューを追加するため、圧縮のみのGeoTIFFより約1.8倍大きくなるが、この増加分は「広域表示・ズームアウト時に読み込むべき低解像度データをあらかじめ内蔵しておく」ためのコストであり、レンダリング速度とのトレードオフになっている。
結果:レンダリング速度の比較
QGISで表示状況を下のアニメーションで比較した。左から順に、無圧縮GeoTIFF・圧縮GeoTIFF・COG形式の表示である。 表示速度は、圧縮GeoTIFF < 無圧縮GeoTIFF < COG形式の順に速くなることが確認できる。 COG形式は他形式よりも明らかに高速で、ズームアウトして広域表示する際の待ち時間がほとんどなく、スムーズにレンダリングされることが確認できた。

なぜCOGだと表示が速くなるのか
- 圧縮のみのGeoTIFFは内部タイル化・オーバービューを持たない場合、ズームアウトして広域表示するときでもフル解像度データをデコードして間引く必要があり、ファイルサイズが小さくても表示のたびに重い処理が発生しうる
- COGはあらかじめ複数解像度のピラミッドを内蔵しているため、表示倍率に応じて最適な解像度のタイルだけを読み込めばよく、また表示範囲外のタイルは読み込まれない
- この仕組みはQGISなどのローカルGISソフトでの表示だけでなく、Webサーバー越しにHTTP Range Requestで部分読み込みする用途(タイル配信サーバーなど)でも有効に機能する
まとめ
分割された航空写真は、VRTでモザイク化した後にCOG形式へ変換することで、無圧縮時と比べて約9分の1のファイルサイズに抑えつつ、内部タイル化とオーバービューによって表示範囲・表示倍率に応じた部分読み込みが可能になり、GIS上でのレンダリングが高速化される。単純なJPEG圧縮のみのGeoTIFFと比べるとファイルサイズは大きくなるが、その分オーバービューによる高速表示のメリットが得られるため、配布・公開用途ではCOG形式を選ぶ価値がある。
GitHub
参考サイト
- gif作成はScreenToGifを使用