TiTilerでCloud Optimized GeoTIFF(COG)を利用した動的タイルサーバーを構築してみた

![img](https://memo.dayjournal.dev/images/try-107_00.png)
![img](https://memo.dayjournal.dev/images/try-107_01.gif)

:::note info
この記事は、「[MIERUNE Advent Calendar 2023](https://qiita.com/advent-calendar/2023/mierune)」の13日目の記事です。
昨日は[@chizutodesign](https://twitter.com/chizutodesign)さんによる[『地図とか路線図とか @chizutodesign』の出版記念イベントをやった話](https://note.com/mierune/n/n20bd69140ff3)でした。
:::

https://qiita.com/advent-calendar/2023/mierune

#### TiTilerでCloud Optimized GeoTIFF(COG)を利用した動的タイルサーバーを構築してみました！

近年、海外の[FOSS4G](https://foss4g.org)コミュニティで注目を集めている[TiTiler](https://devseed.com/titiler)を試してみました。

TiTilerは[FastAPI](https://fastapi.tiangolo.com)と[Rasterio](https://rasterio.readthedocs.io)/[GDAL](https://gdal.org)を基盤として構築された動的なタイルサーバーです。その主な特徴には、[Cloud Optimized GeoTIFF(COG)](https://www.cogeo.org)のサポート・複数の投影法のサポート・様々な出力フォーマット(JPEG、JP2、PNG、WEBP、GTIFF、NumpyTile)・WMTSのサポート・バーチャルモザイクのサポートなどが含まれます。また、AWS CDKを利用したLambdaやECSのデプロイ環境も提供されています。

今後、日本でも利用が広がるツールになってくると思いますので、ぜひチェックしてみてください！

## 事前準備

今回利用するサンプルデータは、AWSが提供している[Registry of Open Data on AWS](https://registry.opendata.aws)から取得できるCloud Optimized GeoTIFF(COG)形式です。

![img](https://memo.dayjournal.dev/images/try-107_02.png)

「Sentinel-2」のCOGを選択しました。
[https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/54/T/WN/2023/8/S2A_54TWN_20230815_0_L2A/TCI.tif](https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/54/T/WN/2023/8/S2A_54TWN_20230815_0_L2A/TCI.tif)

![img](https://memo.dayjournal.dev/images/try-107_03.png)

## TiTilerのインストール & 起動

TiTilerをインストールします。今回はDockerを利用しローカルで起動します。  

TiTilerのリポジトリをクローンします。

```sh
git clone https://github.com/developmentseed/titiler.git
cd titiler
```

TiTilerを起動します。

```sh
docker-compose up --build titiler
```

![img](https://memo.dayjournal.dev/images/try-107_04.png)

起動後に「 http://localhost:8000 」にアクセスします。TiTilerのトップページが表示されるとOKです！
![img](https://memo.dayjournal.dev/images/try-107_05.png)

APIドキュメントを見ると実際の利用方法が確認できます。
![img](https://memo.dayjournal.dev/images/try-107_06.png)

## データの基本情報取得

はじめに、データの基本情報を取得します。  

「/cog/info」の項目選択 → Dataset URLにCOGのURL入力 → 「Execute」をクリック。
![img](https://memo.dayjournal.dev/images/try-107_10.png)

対象データの基本情報がJSONで取得できます。

```json
{
  "bounds": [
    140.99975320947394,
    42.356322389620374,
    142.3544473299751,
    43.35285539188815
  ],
  "minzoom": 7,
  "maxzoom": 13,
  "band_metadata": [
    [
      "b1",
      {}
    ],
    [
      "b2",
      {}
    ],
    [
      "b3",
      {}
    ]
  ],
  "band_descriptions": [
    [
      "b1",
      ""
    ],
    [
      "b2",
      ""
    ],
    [
      "b3",
      ""
    ]
  ],
  "dtype": "uint8",
  "nodata_type": "Nodata",
  "colorinterp": [
    "red",
    "green",
    "blue"
  ],
  "driver": "GTiff",
  "count": 3,
  "width": 10980,
  "height": 10980,
  "overviews": [
    2,
    4,
    8,
    16
  ],
  "nodata_value": 0
}
```

## ビューアーでデータ表示

次に、ビューアーで対象データを表示します。TiTilerには標準でデータを表示するビューアーが用意されています！  

「/cog/viewer」の項目を選択します。そして「 http://localhost:8000/cog/viewer 」に直接アクセスすることでビューアー画面が表示されます。
![img](https://memo.dayjournal.dev/images/try-107_07.png)

ビューアーにアクセス → COGのURLを入力 → 「Apply」をクリック。
![img](https://memo.dayjournal.dev/images/try-107_08.png)

対象のデータがビューアー上に表示されます。ズームイン・アウトや各パラメーターの設定を試すこともできます。
![img](https://memo.dayjournal.dev/images/try-107_09.png)

## GeoJSON形式の基本情報取得

次に、GeoJSON形式の基本情報を取得しQGISで表示します。  

「/cog/info.geojson」のAPIを利用しGeoJSON形式のデータをQGISで読み込みます。

```url
http://localhost:8000/cog/info.geojson?url=https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/54/T/WN/2023/8/S2A_54TWN_20230815_0_L2A/TCI.tif
```

![img](https://memo.dayjournal.dev/images/try-107_11.png)

対象データの範囲ポリゴンと属性に基本情報が入っているのを確認できます。
![img](https://memo.dayjournal.dev/images/try-107_12.png)

## XYZ Tilesを取得

次に、XYZ Tiles形式のラスタタイルを取得しQGISで表示します。

「/cog/tiles」のAPIを利用しXYZ Tiles形式のラスタタイルをQGISで読み込みます。

```url
http://localhost:8000/cog/tiles/WebMercatorQuad/{z}/{x}/{y}.png?url=https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/54/T/WN/2023/8/S2A_54TWN_20230815_0_L2A/TCI.tif
```

![img](https://memo.dayjournal.dev/images/try-107_13.png)

対象データがXYZ Tilesで動的に配信されているのを確認できます。
![img](https://memo.dayjournal.dev/images/try-107_14.png)

## WMTSを取得

最後に、WMTS形式のラスタタイルを取得しQGISで表示します。 

「/cog/WMTSCapabilities.xml」のAPIを利用しWMTS形式のラスタタイルをQGISで読み込みます。

```url
http://localhost:8000/cog/WMTSCapabilities.xml?url=https://sentinel-cogs.s3.us-west-2.amazonaws.com/sentinel-s2-l2a-cogs/54/T/WN/2023/8/S2A_54TWN_20230815_0_L2A/TCI.tif
```

![img](https://memo.dayjournal.dev/images/try-107_15.png)

対象データがWMTSで動的に配信されているのを確認できます。
![img](https://memo.dayjournal.dev/images/try-107_16.png)

<br>

TiTilerを利用すると、データURLを指定するだけで、さまざまな形式での動的タイル配信を手軽に実行できます！単純なラスタタイル配信には静的タイル配信が適していますが、さまざまな形式や特別な処理が必要な場合には、動的タイル配信もひとつの選択肢になります。

TiTilerには標準でビューアーが組み込まれており、すぐにデータの可視化を行うことが可能です。また、AWS CDKを利用してLambdaやECSへのデプロイ環境が整備されており、詳細なドキュメントも提供されています。

今回の記事で紹介できなかったその他の機能もたくさんあるので、ぜひ実際に試してみてください！

<br>
<br>

QGISについて、他にも記事を書いています。よろしければぜひ :bow:
<a href="https://day-journal.com/memo/tags/QGIS" target="_blank">tags - QGIS</a>

やってみたシリーズ :grinning:
<a href="https://day-journal.com/memo/tags/Try" target="_blank">tags - Try</a>

https://qiita.com/dayjournal/items/dc2009cf6c30aa7f978c

https://qiita.com/dayjournal/items/b2d9553f9db7574ae7a8

https://qiita.com/dayjournal/items/92d85e66c3003e647e4a

<br>
<br>

<a href="https://dayjournal.booth.pm" target="_blank"><img src="https://day-journal.com/memo/images/etc/book.png" alt="book"></a>