画像マニフェストのアップロード

Code Editor UIearthengine コマンドライン ツールupload コマンドよりも柔軟に Google Earth Engine(EE)に画像をアップロードする必要がある場合は、マニフェストと呼ばれる JSON ファイルを使用してイメージのアップロードを記述し、コマンドライン ツールの upload image --manifest コマンドを使用します。

マニフェストを使用して画像タイルを単一のアセットとしてアップロードする完全な例については、こちらの Colab ノートブックをご覧ください。

1 回限りの設定

  1. マニフェストのアップロードは、Google Cloud Storage にあるファイルでのみ機能します。Google Cloud Storage の使用を開始するには、Google Cloud プロジェクトを作成します(まだ作成していない場合)。設定には、お支払い用のクレジット カードの指定が必要です。EE 自体は現時点では料金を請求していませんが、EE にアップロードする前にファイルを Google Cloud Storage に転送すると、少額の費用が発生します。一般的なアップロード データサイズ(数十ギガバイトまたは数百ギガバイト)の場合、費用は非常に低くなります。
  2. プロジェクト内で、Cloud Storage API を有効にして、バケットを作成します。
  3. Earth Engine Python クライアントをインストールします。これには、データのアップロードに使用する earthengine コマンドライン ツールが含まれています。
  4. 自動アップロードの場合は、プロジェクトに関連付けられた Google Cloud サービス アカウントを使用することをおすすめします。テストにはサービス アカウントは必要ありませんが、時間があるときに、サービス アカウントの使用方法を学習してください。

非常に大きなソースファイル(100 GB 以上)は、複数のタイルに分割すると、アップロードが速くなる場合があります。

アセット ID と名前

Cloud プロジェクト所有のアセットの場合は、アセット名に projects/some-project-id/assets/some-asset-id という規則を使用します。

以前のプロジェクトとユーザー所有のアセットのアセット名について

古いレガシー プロジェクトの場合、マニフェスト内のアセット名は、Earth Engine の他の場所に表示されるアセット ID とは少し異なる必要があります。アセット ID が users/some_user または projects/some_project で始まるアセットをアップロードするには、マニフェストのアセット名の ID の前に文字列 projects/earthengine-legacy/assets/ を追加する必要があります。たとえば、EE アセット ID users/username/my_geotiff は、projects/earthengine-legacy/assets/users/username/my_geotiff という名前でアップロードする必要があります。

はい。つまり、projects/some_projects/some_asset などの ID は、projects が 2 回言及されている名前(projects/earthengine-legacy/assets/projects/some_projects/some_asset)に変換されます。これは混乱を招きますが、Google Cloud API の標準に準拠するために必要です。

マニフェストの使用

基本的なマニフェストを次のコードブロックに示します。gs://earthengine-test という名前の Google Cloud Storage バケットから small.tif という名前のファイルをアップロードします。

{
  "name": "projects/some-project-id/assets/some-asset-id",
  "tilesets": [
    {
      "sources": [
        {
          "uris": [
            "gs://earthengine-test/small.tif"
          ]
        }
      ]
    }
  ]
}

使用するには、manifest.json という名前のファイルに保存して、次のコマンドを実行します。

earthengine upload image --manifest /path/to/manifest.json

(ファイル gs://earthengine-test/small.tif は存在し、一般公開(読み取り可能)です。テストに使用できます)。

タイルセット

JSON のやや複雑なマニフェスト構造は、複数のソースファイルのピクセルを 1 つのアセットに組み合わせるすべての可能な方法を記述する方法という、一般的なアップロードの課題に対処するのに十分な柔軟性を提供するために必要です。具体的には、ファイルをグループ化する方法は次の 2 つです。

  • モザイク。複数のファイルが複数のタイルを表すこともあります(たとえば、各タイルが 1x1 度の正方形である場合)。このようなファイルは、EE アセットの同じバンドにモザイク化(統合)する必要があります。
  • バンドは別売りです。複数のファイルが複数のバンドを表すこともあります。このようなファイルは、EE アセット内のバンドとして積み重ねる必要があります。

(両方の方法を同時に使用しなければならない場合もありますが、これはまれな状況です)。

これらのオプションを記述するために、マニフェストではタイルセットの概念が導入されています。1 つのタイルは 1 つの GDAL ソースに対応します。このため、1 つのタイルシートのすべてのソースには同じ GDAL 構造(バンドの数とタイプ、投影、変換、欠落値)が必要です。GDAL ソースには複数のバンドが存在する可能性があるため、1 つのタイルシートに複数の EE バンドのデータが含まれる場合があります。

モザイクの取り込みの場合、マニフェストは次のようになります。

{
  "name": "projects/some-project-id/assets/some-asset-id",
  "tilesets": [
    {
      "sources": [
        {
          "uris": [
            "gs://bucket/N30W22.tif"
          ]
        },
        {
          "uris": [
            "gs://bucket/N31W22.tif"
          ]
        }
      ]
    }
  ]
}

別々のバンドの場合、マニフェストは次のようになります(下記で説明するように、bands セクションも追加する必要があります)。

{
  "name": "projects/some-project-id/assets/some-asset-id",
  "bands": ...,
  "tilesets": [
    {
      "id": "tileset_for_band1",
      "sources": [
        {
          "uris": [
            "gs://bucket/band1.tif"
          ]
        }
      ]
    },
    {
      "id": "tileset_for_band2",
      "sources": [
        {
          "uris": [
            "gs://bucket/band2.tif"
          ]
        }
      ]
    }
  ]
}

バンドを分割する場合は、わかりやすくするために各タイルマップに異なるタイルマップ ID を指定する必要があります。タイルセット ID は任意の文字列にできます。これらの文字列は、アップロードされたアセットには保持されません。タイルセット ID は、スタックされたタイルセットを区別するために取り込みでのみ使用されます。

バンド

2 つ目の重要なコンセプトは、ソースファイルを EE アセットバンドに照合することです。これは、マニフェストの bands セクションを使用して行います。

bands セクションは省略できます。この場合、バンドはまず最初のタイルのファイルから作成され、次に次のタイルのファイルから作成されます。デフォルトでは、バンドの名前は「b1」、「b2」などになります。デフォルトのバンド名をオーバーライドするには、最後に「bands」セクションを追加します。

{
  "name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
  "tilesets": [
    {
      "sources": [
        {
          "uris": [
            "gs://bucket/rgb.tif"
          ]
        }
      ]
    }
  ],
  "bands": [
    {
      "id": "R",
      "tilesetBandIndex": 0
    },
    {
      "id": "G",
      "tilesetBandIndex": 1
    },
    {
      "id": "B",
      "tilesetBandIndex": 2
    }
  ]
}

EE バンドの数は、すべてのタイルマップのバンドの合計数と同じにする必要があります。

ファイルからすべてのバンドを取り込む必要がない場合は、tilesetBandIndex フィールドを使用して、取り込む GDAL バンドを指定できます。最初のバンドの tilesetBandIndex は 0 です。

例:

ソースファイルに「tmin」、「tmin_error」、「tmax」、「tmax_error」の 4 つのバンドがあるとします。取り込むのは「tmin」と「tmax」のみです。関連するマニフェスト セクションは次のようになります。

{
  "name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
  "tilesets": [
    {
      "id": "temperature",
      "sources": [
        {
          "uris": [
            "gs://bucket/temperature.tif"
          ]
        }
      ]
    }
  ],
  "bands": [
    {
      "id": "tmin",
      "tilesetBandIndex": 0,
      "tilesetId": "temperature"
    },
    {
      "id": "tmax",
      "tilesetBandIndex": 2,
      "tilesetId": "temperature"
    }
  ]
}

マスク バンド

バンド マスキングは、マニフェストの maskBands コンポーネントで制御されます。3 つのマスク構成がサポートされています(ただし、マスクバンドは常に特定のファイルの最後のバンドであると想定されます)。

  1. 同じファイル内のすべてのデータバンドのマスク。
  2. 他のすべてのファイルから取得されたすべてのデータバンドのマスク。
  3. 一部のデータバンドをマスクします。

1. 最も一般的なケースは、最後のバンドが他のバンドのマスクとして使用される単一の GeoTIFF です。これは、Byte タイプの GeoTIFF でのみ機能します。次のマニフェストを使用します。

{
  "name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
  "tilesets": [
    {
      "id": "data_tileset",
      "sources": [
        {
          "uris": [
            "gs://bucket/data_file.tif"
          ]
        }
      ]
    }
  ],
  "bands": [
    {
      "id": "data_band",
      "tilesetId": "data_tileset"
    },
    {
      "id": "qa_band",
      "tilesetId": "data_tileset"
    }
  ],
  "maskBands": [
    {
      "tilesetId": "data_tileset"
    }
  ]
}

2. マスク GeoTIFF を別の GeoTIFF のすべてのバンドのマスクとして使用するには、次のマニフェストを使用します。

{
  "name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
  "tilesets": [
    {
      "id": "data_tileset",
      "sources": [
        {
          "uris": [
            "gs://bucket/data_file.tif"
          ]
        }
      ]
    },
    {
      "id": "mask_tileset",
      "sources": [
        {
          "uris": [
            "gs://bucket/mask_file.tif"
          ]
        }
      ]
    }
  ],
  "bands": [
    {
      "id": "data_band",
      "tilesetId": "data_tileset"
    },
    {
      "id": "qa_band",
      "tilesetId": "data_tileset"
    }
  ],
  "maskBands": [
    {
      "tilesetId": "mask_tileset"
    }
  ]
}

3. GeoTIFF を別のファイルの特定のバンドのマスクとして使用する場合は、次のマニフェストを使用します(前のケースとの違いは、maskBandsbandIds フィールドが設定されている点です)。

{
  "name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
  "tilesets": [
    {
      "id": "data_tileset",
      "sources": [
        {
          "uris": [
            "gs://bucket/data_file.tif"
          ]
        }
      ]
    },
    {
      "id": "mask_tileset",
      "sources": [
        {
          "uris": [
            "gs://bucket/mask_file.tif"
          ]
        }
      ]
    }
  ],
  "bands": [
    {
      "id": "data_band",
      "tilesetId": "data_tileset"
    },
    {
      "id": "qa_band",
      "tilesetId": "data_tileset"
    }
  ],
  "maskBands": [
    {
      "tilesetId": "mask_tileset",
      "bandIds": ["data_band"]
    }
  ]
}

最後の例では、data_tileset タイルマップの 2 つのバンドを使用していますが、指定された唯一の maskBands リスト オブジェクトの bandIds フィールドで指定されているように、マスクは 1 つのバンド(data_band)にのみ適用されています。

maskBands で指定されたタイルセットの最後のバンドのみがマスクバンドとして使用されます。

ピラミッド方式に関するポリシー

Earth Engine が取り込み中に画像ピラミッドを構築する場合、2x2 ピクセルのグリッドを繰り返し 1 つのピクセルに縮小し、なんらかの方法でピクセル値を変換する必要があります。デフォルトでは、ピクセル値が平均化されます。これは、ラスターバンドがほぼ連続的なデータを表す場合のほとんどの場合で適切な処理です。ただし、デフォルトに依存すると誤った結果が生成される場合が 2 つあります。この場合は、バンド定義の pyramidingPolicy フィールドを設定する必要があります(設定しない場合、デフォルトで値は「平均」と見なされます)。

ラスター画像の分類(土地被覆の分類など)の場合、ピクセルをピラミッド化する最も論理的な方法は、4 つの値の大部分を使用して次の値を生成することである。これは、「MODE」ピラミッド化ポリシーを使用して行われます。

{
  "name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
  "tilesets": [
    {
      "sources": [
        {
          "uris": [
            "gs://bucket/landcover.tif"
          ]
        }
      ]
    }
  ],
  "bands": [
    {
      "id": "landcover",
      "pyramidingPolicy": "MODE"
    }
  ]
}

「MEAN」も「MODE」も意味をなさないラスターバンド(ビットパック ピクセルなど)の場合は、「SAMPLE」ピラミッド化ポリシーを使用する必要があります。「SAMPLE」は、常に 2 x 2 グリッドの左上のピクセルの値を取得します。次の例では、「MEAN」ピラミッド化ポリシーを連続変数(「NDVI」)を表すバンドに割り当て、「SAMPLE」をデータの「QA」バンドに割り当てています。

{
  "name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
  "tilesets": [
    {
      "sources": [
        {
          "uris": [
            "gs://bucket/ndvi.tif"
          ]
        }
      ]
    }
  ],
  "bands": [
    {
      "id": "NDVI",
      "tilesetBandIndex": 0,
      "pyramidingPolicy": "MEAN"
    },
    {
      "id": "QA",
      "tilesetBandIndex": 1,
      "pyramidingPolicy": "SAMPLE"
    }
  ]
}

開始時刻と終了時刻

すべてのアセットで開始時間と終了時間を指定して、データのコンテキストを明確にする必要があります(特にコレクションに含める場合)。これらのフィールドは必須ではありませんが、可能な限り使用することを強くおすすめします。

通常、開始時間と終了時間は、ソースファイルが生成された時間ではなく、観測時間です。

便宜上、終了時間は境界として扱われます。たとえば、ちょうど 1 日にわたるアセットの場合は、開始時間と終了時間に 2 日連続の深夜(1980-01-31T00:00:00 と 1980-02-01T00:00:00 など)を使用します。アセットに時間が設定されていない場合は、終了時刻を開始時刻と同じに設定します。 マニフェスト内の時刻は ISO 8601 文字列で表します。日付値を簡素化するために、終了時間を除外(1 日単位のアセットの場合は翌日の午前 0 時など)と仮定することをおすすめします。

例:

{
  "name": "projects/some-project-id/assets/some-asset-id",
  "tilesets": [
    {
      "sources": [
        {
          "uris": [
            "gs://bucket/img_20190612.tif"
          ]
        }
      ]
    }
  ],
  "startTime": "1980-01-31T00:00:00Z",
  "endTime": "1980-02-01T00:00:00Z"
}

マニフェストの構造リファレンス

次の JSON 構造には、使用可能なすべての画像アップロード マニフェスト フィールドが含まれています。フィールドの定義については、 マニフェストのフィールドの定義をご覧ください。

{
  "name": <string>,
  "tilesets": [
    {
      "dataType": <string>,
      "id": <string>,
      "crs": <string>,
      "sources": [
        {
          "uris": [
            <string>
          ],
          "affineTransform": {
            "scaleX": <double>,
            "shearX": <double>,
            "translateX": <double>,
            "shearY": <double>,
            "scaleY": <double>,
            "translateY": <double>
          }
        }
      ]
    }
  ],
  "bands": [
    {
      "id": <string>,
      "tilesetId": <string>,
      "tilesetBandIndex": <int32>,
      "missingData": {
        "values": [<double>]
      },
      "pyramindingPolicy": <string>
    }
  ],
  "maskBands": [
    {
      "tilesetId": <string>,
      "bandIds": [
        <string>
      ]
    }
  ],
  "footprint": {
    "points": [
      {
        "x": <double>,
        "y": <double>
      }
    ],
    "bandId": <string>
  },
  "missingData": {
     "values": [<double>]
  },
  "pyramidingPolicy": <string>,
  "uriPrefix": <string>,
  "startTime": {
    "seconds": <integer>
  },
  "endTime": {
    "seconds": <integer>
  },
  "properties": {
    <unspecified>
  }
}

マニフェストのフィールドの定義

name

string

作成するアセットの名前。name の形式は「projects/*/assets/**」です(例:「projects/earthengine-legacy/assets/users/USER/ASSET」)。

タイルセット

list

タイルセットのプロパティを定義する辞書のリスト。詳細については、次の tilesets ディクショナリ要素フィールドをご覧ください。

tilesets[i].dataType

string

データの数値データ型を指定します。デフォルトは GDAL が報告するタイプです。この場合、定義する必要はありません。

データ型 Value
指定なし "DATA_TYPE_UNSPECIFIED"
8 ビット符号付き整数 "INT8"
8 ビットの符号なし整数 "UINT8"
16 ビット符号付き整数 "INT16"
16 ビット符号なし整数 "UINT16"
32 ビット符号付き整数 "INT32"
32 ビット符号なし整数 "UINT32"
32 ビット浮動小数点数 "FLOAT32"
64 ビット浮動小数点数 "FLOAT64"

tilesets[i].id

string

タイルの ID。アセット マニフェストで指定されたタイルマップ間で一意である必要があります。この ID は処理ステップで破棄されます。これは、タイルマップをバンドにリンクする場合にのみ使用されます。空の文字列は有効な ID です。

tilesets[i].crs

string

ピクセル グリッドの座標参照システム。可能であれば標準コード(EPSG コードなど)で指定し、そうでない場合は WKT 形式で指定します。

tilesets[i].sources

list

画像ファイルとそのサイドカーのプロパティを定義するディクショナリのリスト。詳細については、次の sources ディクショナリ要素フィールドをご覧ください。

tilesets[i].sources[j].uris

list

取り込むデータの URI のリスト。Google Cloud Storage URI のみがサポートされています。各 URI は gs://bucket-id/object-id の形式で指定する必要があります。プライマリ オブジェクトはリストの最初の要素にする必要があります。サイドカーはその後ろに記述します。各 URI の前に ImageManifest.uriPrefix が付いています(設定されている場合)。

tilesets[i].sources[j].affineTransform

dictionary

オプションの affine 変換。uris のデータ(サイドカーを含む)がピクセルの配置に不十分な場合にのみ指定してください。次のキーを持つ辞書として提供されます。 「scaleX」、「shearX」、「translateX」、「shearY」、「scaleY」、「translateY」。 詳細については、 こちらのリファレンスをご覧ください。

キーと値の例:

{
  "scaleX": 0.1,
  "shearX": 0.0,
  "translateX": -180.0,
  "shearY": 0.0,
  "scaleY": -0.1,
  "translateY": 90.0
}

バンド

list

タイルマップから取得した単一バンドのプロパティを定義する辞書のリスト。アセットのバンド順序は bands の順序と同じです。詳細については、次の bands ディクショナリ要素フィールドをご覧ください。

bands[i].id

string

バンドの ID(名前)。

bands[i].tilesetId

string

バンドに対応するタイルマップの ID。

bands[i].tilesetBandIndex

int32

バンドに対応するタイルマップからのゼロベースのバンド インデックス。

bands[i].missingData.values

list

バンド内にデータがないことを表す値のリスト(double 型)。

bands[i].pyramidingPolicy

string

ピラミッド型販売に関するポリシー。詳しくは、 こちらのリンクをご覧ください。次のオプションがあります。

  • 「MEAN」(デフォルト)
  • "MODE"
  • "SAMPLE"

maskBands

list

タイルマップから取得された単一のマスクバンドのプロパティを定義する辞書のリスト。指定できるマスクバンドは 1 つまでです。 詳細については、次の maskBands ディクショナリ要素フィールドをご覧ください。

maskBands[i].tilesetId

string

マスクバンドに対応するタイルマップの ID。タイルマップの最後のバンドは常にマスクバンドとして使用されます。

maskBands[i].bandIds

list of strings

マスクバンドが適用されるバンドの ID のリスト。空の場合、マスクバンドはアセット内のすべてのバンドに適用されます。各バンドには、対応するマスクバンドを 1 つだけ設定できます。

フットプリント

dictionary

画像内のすべての有効なピクセルのフットプリントのプロパティを定義するディクショナリ。空の場合、デフォルトのフットプリントはイメージ全体です。詳細については、次の footprint ディクショナリ要素フィールドをご覧ください。

footprint.points

list

画像内のすべての有効なピクセルのフットプリントを定義するポイントのリスト。ポイントは、浮動小数点値を持つ「x」キーと「y」キーを持つディクショナリで定義されます。ポイントのリストは、画像のすべての有効なピクセルの中心を含む単純なポリゴンの外側を形成するリングを記述します。線形リングである必要があります。最後のポイントは最初のポイントと同じである必要があります。座標は、bandId で指定されたバンドの投影です。

注: footprint は、ピクセル(1x1 の長方形)がフットプリントと交差する場合、ピクセルを含むと見なされるため、各ピクセルの中心など、整数以外の座標を使用します。隣接するピクセルを誤って選択しないように、整数値の座標は使用しないでください。整数値の座標はピクセルの境界です。ピクセル中心に沿ってフットプリントを描画すると、意図しないピクセルが含まれなくなります。意図したピクセルがアンチメリディアンや極点などの地図境界に接している場合にエラーが発生する可能性があります。

たとえば、4 つのピクセルがすべて有効な 2x2 画像の場合、次のようなリングが考えられます。

[
  {
    "x": 0.5,
    "y": 0.5
  },
  {
    "x": 0.5,
    "y": 1.5
  },
  {
    "x": 1.5,
    "y": 1.5
  },
  {
    "x": 1.5,
    "y": 0.5
  },
  {
    "x": 0.5,
    "y": 0.5
  }
]

footprint.bandId

string

CRS がフットプリントの座標を定義するバンドの ID。空の場合は、最初のバンドが使用されます。

missingData.values

list

画像のすべてのバンドにデータがないことを表す値のリスト(double 型)。独自の missingData を指定していないすべてのバンドに適用されます。

pyramidingPolicy

string

ピラミッド型販売に関するポリシー。指定しない場合、デフォルトでポリシー「MEAN」が適用されます。独自のバンドを指定していないすべてのバンドに適用されます。詳しくは、 こちらのリンクをご覧ください。次のオプションがあります。

  • 「MEAN」(デフォルト)
  • "MODE"
  • "SAMPLE"

uriPrefix

string

マニフェストで定義されているすべての uris の先頭に追加する省略可能な接頭辞。

startTime

integer

アセットに関連付けられているタイムスタンプ(存在する場合)。これは通常、衛星画像が撮影された時刻に対応します。1 か月または 1 年間の平均値など、期間に対応するアセットの場合、このタイムスタンプはその期間の開始に対応します。エポック(1970-01-01)からの秒数と(省略可)ナノ秒数で指定します。UTC タイムゾーンにあると想定されます。

endTime

integer

期間に対応するアセット(1 か月または 1 年間の平均値など)の場合、このタイムスタンプはその期間の終了時刻(除く)に対応します。エポック(1970-01-01)からの秒数と(省略可)ナノ秒数で指定します。UTC タイムゾーンにあると想定されます。

プロパティ

dictionary

Key-Value ペアの任意のフラット ディクショナリ。キーは文字列にする必要があります。値は数値または文字列にできます。ユーザーがアップロードしたアセットでは、リスト値はまだサポートされていません。

制限事項

JSON マニフェストのサイズ

JSON マニフェスト ファイルのサイズの上限は 10 MB です。アップロードするファイルが多い場合は、データセットの記述に必要な文字数を減らす方法を検討してください。たとえば、uriPrefix フィールドを使用すると、uris リスト内の各 URI の Google Cloud バケットパスを指定する必要がなくなります。サイズをさらに縮小する必要がある場合は、ファイル名を短くしてみてください。

画像ファイル形式

各画像ファイルは TIFF 画像である必要があります。マニフェストで CRS が指定されていない場合、ファイルは CRS が埋め込まれた GeoTIFF である必要があります。

TIFF ファイルは、DEFLATE、JPEG-XL/JXL、LERC、LERC_DEFLATE、LERC_ZSTD、LZMA、LZW、WEBP、ZSTD で圧縮できます。

大容量ファイルをスムーズにアップロードするための推奨事項:

  • 最適な選択: ZSTD は、速度と圧縮のバランスが取れています。
  • 使用しないでください: LZMA は、圧縮率は高いものの、非常に遅くなる可能性があります。
  • 未圧縮のファイル: ファイルサイズが大きくなり、アップロード時間が長くなります。
  • 非可逆圧縮(JPEG): ピクセル値が変更される可能性があります。ロスレス圧縮を使用する(DEFLATE、LZMA、LZW、ZSTD)は使用しないでください。