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 を持つ ImageManifest を指定できます。この場合、生成されるアセットの各バンドは、Tileset のいずれかのバンドによってバックアップされます。これは、異なるバンドで解像度やデータ型が異なる場合に便利です。バンドは、使用可能な任意の 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 ユーザーに表示されない場合は、「gs://my-bucket/my-object#123456 の GeoTIFF の読み込みに失敗しました」という形式のエラーが返されます(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 Legacy Bucket Reader」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 圧縮、Cloud 最適化 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 ベースのアセットを作成する

注: 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))