みなさんは COG と呼ばれるデータを聞いたことがありますでしょうか?COG は Cloud Optimized GeoTIFF の略で、直訳するとクラウドに最適化された GeoTIFF となります。
GeoTIFF はラスター データです。ラスター データは画像の持つピクセル値が大きな意味を持っており、その値が様々な解析に利用されます。今日、画像データは観測する機械の性能の向上などによって質・量ともに大きくなっていますが、たとえばクラウド環境を活用する場合のように必要なデータを都度取得する運用をしたいケースでは、大容量のデータをそのまま扱うことは現実的ではありません。そこで生まれたのが COG です。COG は元のラスター データの持つピクセル値は維持したまま、HTTP リクエストで必要な範囲を切り出して取得することができます。これにより大容量のデータであっても、必要分だけ取り出すことでクラウド環境でも無理なくラスター データを使用することができるようになりました。
COG については以前に ESRIジャパンの運営している ArcGISブログでも紹介をしているので (Cloud Optimized GeoTIFF (COG) と Sentinel-2 オープンデータ)、詳しくはそちらをご確認いただくとして、本記事では実際に COG を扱う (作成・利用) ことに注目してみます。
それでは ArcGIS で COG を作成してみましょう。COG の作成には ArcGIS Pro を使用します。今回使用する画像データは国土地理院の提供する基盤地図情報よりダウンロードした富士山周辺の数値標高モデル(5m)です。基盤地図情報よりダウンロードしたデータはそのままでは ArcGIS で利用することができないので、ArcGIS Pro のアドイン ツールとして用意している変換ツール (国内データ) for ArcGIS Pro を使用して画像データに変換します。変換ツールの使用方法については、以下のページをご確認ください。
変換が完了すると画像データとして作成され ArcGIS Pro で利用できるようになります(地図上で空白の箇所は NoData 値となっている箇所です)。
画像データの準備ができたら COG を作成します。ArcGIS Pro では [ラスターのコピー] ツールを使用することで、既存のラスター データを COG 形式でコピーすることができます。
念のため [ラスターのコピー] ツールで出力された画像データが COG 形式になっているかを確認してみます。画像データが COG 形式であるかどうかは、validate_cloud_optimized_geotiff.py を使って確認できます。 本スクリプトの利用方法など、詳細については cogeo.org の紹介している開発者向けの資料となる Utilizing Cloud Optimized GeoTIFF を参照してください。
validate_cloud_optimized_geotiff.py を実行したところ “~~ is a valid cloud optimized GeoTIFF” と出力されているので、無事 COG 形式の画像をつくることができました。
ここまでの手順で COG を用意することができたので、ここからは作成できた COG をArcGIS Maps SDK for JavaScript を使用した Web アプリケーションから利用してみます。
※ ArcGIS Pro では AWS をはじめとしたクラウド ストレージにデータを格納し、接続することで、COG を利用できます。
ArcGIS Maps SDK for JavaScript ではバージョン 4.25 よりベータ版の機能として ImageryTileLayer クラスから COG を参照できるようになりました。まずは 2D のマップに ImageryTileLayer クラスとして COG データを追加してみます。
require([
"esri/config",
"esri/Map",
"esri/views/MapView",
"esri/layers/ImageryTileLayer"
], (
esriConfig,
Map,
MapView,
ImageryTileLayer
) => {
// API キーを設定
esriConfig.apiKey = "<API キー>";
// Map / MapView クラスを用意
const mapMain = new Map({
basemap:{
style:{
id:"arcgis/topographic",
language:"ja"
}
}
});
const mapView = new MapView({
container:"viewDiv",
map:mapMain,
center:[138.6569276, 35.3380013],
zoom:11
});
// COG を参照する ImageryTileLayer クラスを定義し、マップに追加
const cogTile = new ImageryTileLayer({
// COG 形式の TIFF 画像の URL
url:location.href + "image/dem5m.tif"
});
// Map クラスにレイヤーを追加
mapMain.add(cogTile);
});
無事 ArcGIS Maps SDK for JavaScript アプリケーションの 2D マップに COG データを表示することができました。もちろんこのままでも良いのですが、もう少しアプリケーションに手を加えてみます。まずはレイヤーのシンボル設定を変更し、陰影起伏を表現してみます。
require([
"esri/config",
"esri/Map",
"esri/views/MapView",
"esri/layers/ImageryTileLayer"
], (
esriConfig,
Map,
MapView,
ImageryTileLayer
) => {
// API キーを設定
esriConfig.apiKey = "<API キー>";
// Map / MapView クラスを用意
const mapMain = new Map({
basemap:{
style:{
id:"arcgis/topographic",
language:"ja"
}
}
});
const mapView = new MapView({
container:"viewDiv",
map:mapMain,
center:[138.6569276, 35.3380013],
zoom:11
});
// COG を参照する ImageryTileLayer クラスを定義し、マップに追加
const cogTile = new ImageryTileLayer({
// COG 形式の TIFF 画像の URL
url:location.href + "image/dem5m.tif"
});
// Map クラスにレイヤーを追加
mapMain.add(cogTile);
// ★ 追加
// RasterShadedReliefRenderer (陰影起伏レンダラー) をオブジェクトとして定義し、ImageryTileLayer にセット
const rasterShadedReliefRenderer = {
type:"raster-shaded-relief"
}
// レンダラーを ImageryTileLayer にセット
cogTile.renderer = rasterShadedReliefRenderer;
});
RasterShadedReliefRenderer クラスを使用することで、陰影起伏として地表面の凹凸を強調して表現することができました。
さて、この画像データは標高のデータのため、各ピクセル値は標高の値になっています。最後に、標高値を確認する目的でレイヤーをクリックした際のポップアップを設定してみます。
require([
"esri/config",
"esri/Map",
"esri/views/MapView",
"esri/layers/ImageryTileLayer"
], (
esriConfig,
Map,
MapView,
ImageryTileLayer
) => {
// API キーを設定
esriConfig.apiKey = "<API キー>";
// Map / MapView クラスを用意
const mapMain = new Map({
basemap:{
style:{
id:"arcgis/topographic",
language:"ja"
}
}
});
const mapView = new MapView({
container:"viewDiv",
map:mapMain,
center:[138.6569276, 35.3380013],
zoom:11
});
// COG を参照する ImageryTileLayer クラスを定義し、マップに追加
const cogTile = new ImageryTileLayer({
// COG 形式の TIFF 画像の URL
url:location.href + "image/dem5m.tif"
});
// Map クラスにレイヤーを追加
mapMain.add(cogTile);
// RasterShadedReliefRenderer (陰影起伏レンダラー) をオブジェクトとして定義し、ImageryTileLayer にセット
const rasterShadedReliefRenderer = {
type:"raster-shaded-relief"
}
// レンダラーを ImageryTileLayer にセット
cogTile.renderer = rasterShadedReliefRenderer;
// ★ 追加
// ImageryTileLayer にポップアップを設定
cogTile.popupTemplate = {
title:"ピクセル情報",
content:[{
type:"fields",
fieldInfos:[{
fieldName:"Raster.ServicePixelValue",
label:"ピクセル値 (標高)"
}]
}]
}
});
マップをクリックすることで、ラスター データの持つピクセル値にアクセスし、標高値を確認することができるようになりました。
また、ここまでは 2D マップとして動きを確認してみましたが、もちろん 3D シーン上でも同じように表示することができます。
これまで ArcGIS Maps SDK for JavaScript で画像データを利用しようとすると、ArcGIS Enterprise のオプショナル サーバーとなる ArcGIS Image Server や ArcGIS Online に追加してご利用いただく ArcGIS Image for ArcGIS Online といった、追加のコンポーネントを用意する必要があり、少しハードルが高いのが実情でした。COG はこのハードルを低くするためのデータ形式として期待できそうです。もちろん ArcGIS Image Server や ArcGIS Image for ArcGIS Online では多数の画像データを一元的に管理することができる (モザイク データセット) などCOG にないメリットも多いため、用途に応じた使い分けを検討できるようになると良いですね。