Cloud GeoTiff ベースの Earth Engine アセット

Earth Engine は、Cloud Optimized GeoTIFF(COG)でバックアップされたアセットをサポートしています。COG 対応アセットの利点は、画像の空間フィールドとメタデータ フィールドがアセットの作成時にインデックス登録されるため、コレクション内の画像のパフォーマンスが向上することです。COG でサポートされているアセットのパフォーマンスは、一般的なユースケースでは取り込まれたアセットのパフォーマンスと同等です。

1 つのアセットが複数の COG によってバックアップされることがあります(たとえば、帯域ごとに 1 つの COG が存在することがあります)。ただし、1 つのバンドに多数の COG タイルを使用することはサポートされていません。

(または、Earth Engine は Google Cloud Storage の COG から画像を直接読み込むことができます(詳細)。ただし、ee.Image.loadGeoTIFF を介して読み込まれ、画像コレクションに追加された画像では、コレクションに対するフィルタリング オペレーションのために GeoTiff の読み取りが必要になります。

COG 対応アセットを作成するには、

  1. COG ファイルを GCS バケットに配置します(許可されているリージョンについては、ロケーションをご覧ください)。
  2. 画像アップロード マニフェストを作成する
  3. earthengine コマンドライン ユーティリティを使用して、アップロード コマンドを送信します。
earthengine upload external_image --manifest my_manifest.json

1 つの Tileset を含むサンプル画像マニフェスト

最も単純な ImageManifest は、1 つの Tileset を持つものです。バンドが指定されていない場合、結果のアセットには、GeoTIFF にエンコードされたバンド名(この例では「vis-red」、「vis-green」、「vis-blue」)を持つ GeoTIFF のすべてのバンドが含まれます。

request = {
  'imageManifest': {
    'name': f'projects/{ee_project}/assets/cogdemo1',
    'tilesets': [
      { 'id': '0', 'sources': [ { 'uris': [
        'gs://ee-docs-demos/COG_demo.tif'] } ] }
    ],
    'properties': {
      'version': '1.1'
    },
    'startTime': '2016-01-01T00:00:00.000000000Z',
    'endTime': '2016-12-31T15:01:23.000000000Z',
  },
}

pprint(request)

Tileset が複数ある

tilesetId フィールドと tilesetBandIndex フィールドを使用して、結果のアセットの各バンドが Tileset のバンドの 1 つによってバックアップされる複数の Tileset を持つ ImageManifest を指定できます。これは、バンドごとに解像度やデータ型が異なる場合に便利です。バンドは、使用可能な任意の Tileset から任意の順序でリストできます。下記の例で、

  • 「b4b3b2.tif」は 10 m スケール、「b5b6b7」は 20 m スケールです。
  • 結果として得られるアセットのバンド順序は、入力 COG から混合されます(出力バンド 0 は Tileset 0 から、出力バンド 1 は Tileset 1 からなど)。
request = {
  'imageManifest': {
    'name': f'projects/{ee_project}/assets/cogdemo2',
    'uriPrefix': 'gs://ee-docs-demos/external_image_demo/',
    'tilesets': [
      { 'id': '0', 'sources': [ { 'uris': ['b4b3b2.tif'] } ] },
      { 'id': '1', 'sources': [ { 'uris': ['b5b6b7.tif'] } ] },
    ],
    'bands': [
      { 'id': 'red', 'tilesetId': '0', 'tilesetBandIndex': 0 },
      { 'id': 'rededge3', 'tilesetId': '1', 'tilesetBandIndex': 2 },
      { 'id': 'rededge2', 'tilesetId': '1', 'tilesetBandIndex': 1 },
      { 'id': 'green', 'tilesetId': '0', 'tilesetBandIndex': 1 },
      { 'id': 'blue', 'tilesetId': '1', 'tilesetBandIndex': 0 },
      { 'id': 'rededge1', 'tilesetId': '0', 'tilesetBandIndex': 2 },
    ],
  },
}

pprint(request)

COG バックアップ アセットの詳細

ロケーション

Cloud Storage バケットのロケーションは次のいずれかである必要があります。

  • 米国のマルチリージョン
  • US-CENTRAL1 を含む米国のデュアルリージョン
  • リージョン US-CENTRAL1

ストレージ クラス

バケットのストレージ クラスは「Standard Storage」である必要があります。

共有の権限

COG でサポートされている Earth Engine アセットと基盤となるデータの ACL は個別に管理されます。COG でバックアップされたアセットを共同編集者と共有して読み取りを行う場合、Earth Engine アセットと基盤となる COG ファイルの両方に読み取りアクセス権が付与されていることを確認するのは所有者の責任です。

1. 読み取り用の Google Cloud Storage バケット権限を付与する

共同編集者が COG 対応アセットを読み取るには、まず Google Cloud Storage バケット内の基盤となる COG ファイルに対する読み取りアクセス権が必要です。これらの権限がないと、Earth Engine はデータを取得できません。Google Cloud Storage のデータが Earth Engine ユーザーに表示されない場合、Earth Engine は「Failed to load the GeoTIFF at gs://my-bucket/my-object#123456」という形式のエラーを返します(123456 はオブジェクトの世代です)。

具体的には、共同編集者には次の権限が必要です。

  • バケットに対する storage.buckets.get(バケットのメタデータとロケーションを取得し、Earth Engine がアセットのソースを適切に解決できるようにします)。
  • バケットに対する storage.objects.get(実際の COG バックアップ アセットデータを読み取るため)。

これらの権限は、「Storage Legacy Bucket Reader」ロールと「Storage Legacy Object Reader」ロールによってそれぞれ提供されます。

これらのロールを共同編集者に割り当てるには:

  1. バケットの権限ページに移動します。 https://console.cloud.google.com/storage/browser/{MY-BUCKET};tab=permissions
  2. [アクセスを許可] をクリックします。
  3. 読み取りアクセス権を付与するすべてのプリンシパル(ユーザー、グループ、サービス アカウントなど)を追加します。
  4. 次のロールを割り当てます。
    • 「Storage レガシー バケット読み取り」storage.buckets.get とその他のバケットレベルの読み取り権限を提供します)。
    • 「Storage レガシー オブジェクト読み取り」storage.objects.get を提供します)。
    • (または、storage.buckets.get 権限と storage.objects.get 権限のみを持つ新しいカスタムロールを作成して割り当てることもできます)。
  5. 保存

2. 読み取り用の Earth Engine アセットを共有する

基盤となる GCS バケットとオブジェクトに対する必要な権限が共同編集者に付与されていることを確認したら、Earth Engine アセット自体も共有する必要があります。Earth Engine アセットの権限の設定について詳しくは、Earth Engine アセット管理ガイドをご覧ください。

世代

COG 対応アセットが作成されると、Earth Engine はマニフェストで指定された TIFF のメタデータを読み取り、アセット ストア エントリを作成します。そのエントリに関連付けられた各 URI には世代を設定できます。世代の詳細については、オブジェクトのバージョニングに関するドキュメントをご覧ください。世代が指定されている場合(例: gs://foo/bar#123)、Earth Engine はその URI をそのまま保存します。世代が指定されていない場合、Earth Engine は ImportExternalImage が呼び出された時点の TIFF の世代で URI を保存します。

つまり、GCS の外部アセットを構成する TIFF が更新されると(世代が変更されると)、Earth Engine は「gs://my-bucket/my-object#123456 で GeoTIFF を読み込めませんでした」というエラーを返します。これは、想定されるオブジェクトが存在しなくなったためです(バケットで複数のオブジェクト バージョンが有効になっていない場合)。このポリシーは、アセットのメタデータをオブジェクトのメタデータと同期するように設計されています。

構成

COG の構成方法については、TIFF は次の要件を満たさなければなりません。

  • タイル形式。タイルのサイズは次のいずれかです。

    • 256x256
    • 512x512
    • 1024 x 1024
    • 2,048x2,048
  • すべての IFD が先頭になるように配置されています。

最適なパフォーマンスを得るには:

  • タイルのサイズは 512x512 以上にします。
  • 2 の累乗の概要を含めます。

ユースケースによっては、'INTERLEAVE' 作成オプションがパフォーマンスに影響する可能性があります。BAND インターリーブは、あらゆる状況で使用することをおすすめします。

最適化された構成の詳細については、こちらのページをご覧ください。

次の gdal_translate コマンドは、ラスターをバンド インターリーブ形式の zstd 圧縮されたクラウド最適化 GeoTIFF に変換します。この形式は Earth Engine で優れたパフォーマンスを発揮します。

gdal_translate in.tif out.tif \
  -co COPY_SRC_OVERVIEWS=YES \
  -co TILED=YES \
  -co BLOCKXSIZE=512 \
  -co BLOCKYSIZE=512 \
  -co COMPRESS=ZSTD \
  -co ZSTD_LEVEL=22 \
  -co INTERLEAVE=BAND \
  -co NUM_THREADS=ALL_CPUS

予測子(整数データ型の場合は -co PREDICTOR=2、浮動小数点データ型の場合は -co PREDICTOR=3)を指定すると、出力ファイル サイズをさらに縮小できる場合があります。

GDAL >= 3.11 のユーザーの場合、COG ドライバは、概要の作成と保存を気にすることなくファイルを作成できます。

gdal_translate in.tif out.tif \
  -of COG \
  -co OVERVIEWS=IGNORE_EXISTING \
  -co COMPRESS=ZSTD \
  -co LEVEL=22 \
  -co PREDICTOR=2 \
  -co INTERLEAVE=BAND \
  -co NUM_THREADS=ALL_CPUS \

REST API を使用して Cloud GeoTiff-Backed アセットを作成する

注: REST API には、すべてのユーザーに適していない可能性のある新しい高度な機能が含まれています。Earth Engine を初めて使用する場合は、JavaScript ガイドから始めることをおすすめします。

REST API を使用して COG バックアップ アセットを作成するには、Earth Engine の ImportExternalImage エンドポイントPOST リクエストを送信します。次の例に示すように、このリクエストは、ユーザー フォルダにアセットを作成する権限が必要です。

承認済みセッションを開始する

ユーザー フォルダに Earth Engine アセットを作成するには、リクエストを行うときに自分自身として認証できる必要があります。Earth Engine 認証システムの認証情報を使用して、AuthorizedSession を開始できます。その後、AuthorizedSession を使用して Earth Engine にリクエストを送信できます。

import ee
import json
from pprint import pprint
from google.auth.transport.requests import AuthorizedSession

ee.Authenticate()  #  or !earthengine authenticate --auth_mode=gcloud

# Specify the cloud project you want associated with Earth Engine requests.
ee_project = 'your-project'

session = AuthorizedSession(
    ee.data.get_persistent_credentials().with_quota_project(ee_project)
)

リクエストの本文

リクエストの本文は ImageManifest のインスタンスです。ここでは、COG のパスとその他の便利なプロパティを指定します。

ImageManifest の構成方法について詳しくは、こちらのガイドをご覧ください。1 つ以上の を定義できます。各 Tileset は 1 つ以上のバンドをサポートします。ImportExternalImage の場合、Tileset ごとに最大 1 つの ImageSource がサポートされます。

COG のエクスポートの詳細については、こちらのドキュメントをご覧ください。

リクエストを送信する

Earth Engine の projects.images.importExternal エンドポイントに POST リクエストを送信します。

url = f'https://earthengine.googleapis.com/v1alpha/projects/{ee_project}/image:importExternal'

response = session.post(
  url = url,
  data = json.dumps(request)
)

pprint(json.loads(response.content))