たぶん動く...

多分GIS系の人。あくまで個人的見解であり、所属団体を代表するものではありません。

COGをソースにしてタイルサーバをホストする(2)

前回は、rio-tilerを利用してモノクロの1レイヤーのCOGをQGIで表示するところまでしました。今回はバンド合成したカラー画像を表示するところまでやっていきます。

前回

COGをソースにしてタイルサーバをホストする(1) - たぶん動く...

単バンドグレー表示

前回は表示できてもグレーで濃淡のない表示になってしまいました。これはCOGがFloat型で持っているのに対し、出力するPNGがInt型(0〜255)に無理に変換しようとした結果、グレー一色になっているようです。
ヒストグラムを確認すると、0.2以下に山があるので、値を1000倍してそのままInt型に変換すれば良さそうです。 適切に濃淡が表示されるようにapp.pyを修正します。

タイルのレスポンスを以下に変更しました。 19行目でCOGから切り出した値を0.255より大きい値は0.255とし、その状態が1000倍にすることで、全ピクセルを255以下の値にします。
その後PNGを返します。

@app.get(
    r"/{z}/{x}/{y}.png",
    responses={
        200: {
            "content": {"image/png": {}}, "description": "Return an image.",
        }
    },
    response_class=Response,
    description="Read COG and return a tile",
)
def tile(
    z: int,
    x: int,
    y: int,
    url: str = Query(..., description="Cloud Optimized GeoTIFF URL."),
):
    """Handle tile requests."""
    with Reader(url) as cog:
        img = cog.tile(x, y, z,256)
        img.data=np.where(img.data>0.255,0.255,img.data)*1000
        img.data=img.data.astype('uint8')
    content = img.render(img_format="PNG", **img_profiles.get("png"))
    return Response(content, media_type="image/png")

では実行してみます。

uvicorn app:app --reload --host 0.0.0.0

砂漠地域なので、赤色に対応するバンドだとほとんど白くなりますが、単バンドで濃淡が表現されるタイルになりました。

カラーバンドを表示する

まず、RGBバンドを持つGeoTIFFを作成してから、COGファイル化します。
rio-tilerは、コードを読んだところ複数バンドを持つCOGを読み取ることができるようです。 必要なバンドを指定し、カラーになる順番で抽出します。 9行目に引数を追加しました。

def tile(
    z: int,
    x: int,
    y: int,
    url: str = Query(..., description="Cloud Optimized GeoTIFF URL."),
):
    """Handle tile requests."""
    with Reader(url) as cog:
        img = cog.tile(x, y, z,256,[1,2,3])
        img.data=np.where(img.data>0.255,0.255,img.data)*1000
        img.data=img.data.astype('uint8')
    content = img.render(img_format="PNG", **img_profiles.get("png"))
    return Response(content, media_type="image/png")

では実行してみます。

uvicorn app:app --reload --host 0.0.0.0

表示できました。 湖水域がNodataなので黒く表示されています。

参考文献

rio-tiler

GitHub - cogeotiff/rio-tiler: User friendly Rasterio plugin to read raster datasets.