如要將圖片上傳至 Google Earth Engine (EE),但需要比程式碼編輯器 UI 或 「earthengine」指令列工具的 upload 指令更具彈性的方式,可以使用稱為「資訊清單」的 JSON 檔案描述圖片上傳作業,並使用指令列工具的 upload image --manifest 指令。
如需已完成樣本,請參閱這個 Colab 筆記本,其中示範如何使用資訊清單,將圖片圖塊上傳為單一資產。
一次性設定
- 上傳資訊清單時,只能使用位於 Google Cloud Storage 的檔案。如要開始使用 Google Cloud Storage,請建立 Google Cloud 專案 (如果尚未建立)。請注意,設定時必須指定用於帳單的信用卡。EE 本身目前不會向任何人收費,但將檔案轉移至 Google Cloud Storage,再上傳至 EE,會產生少量費用。以一般上傳資料大小 (數十或數百 GB) 來說,費用會相當低。
- 在專案中啟用 Cloud Storage API 並建立 bucket。
- 安裝 Earth Engine Python 用戶端。其中包含
earthengine指令列工具,我們將使用這項工具上傳資料。 - 如要自動上傳,建議您使用與專案相關聯的 Google Cloud 服務帳戶。測試時不需要服務帳戶,但有空時,請開始熟悉如何使用服務帳戶。
如果將非常大的來源檔案 (100 GB 以上) 拆分成多個圖塊,上傳速度可能會更快。
資產 ID 和名稱
如果是雲端專案擁有的資產,請使用下列資產名稱慣例: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 提及兩次的名稱:projects/earthengine-legacy/assets/projects/some_projects/some_asset。這點雖然令人困惑,但為了符合 Google Cloud API 標準,必須這麼做。
使用資訊清單
下列程式碼區塊顯示基本資訊清單。這個函式會從名為 gs://earthengine-test 的 Google Cloud Storage bucket 上傳名為 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 的資訊清單結構有點複雜,但這是為了提供足夠的彈性,解決常見的上傳難題:如何描述將多個來源檔案中的像素合併為單一素材資源的所有可能方式。具體來說,有兩種獨立的方式可以將檔案分組:
- 馬賽克。有時多個檔案代表多個圖塊 (例如,每個圖塊都是 1x1 度的正方形)。這類檔案必須鑲嵌 (合併) 至 EE 資產中的相同波段。
- 拆開錶帶。有時,多個檔案代表多個波段。這類檔案必須堆疊在一起,做為 EE 資產中的波段。
(可能需要同時使用這兩種方法,但這種情況很少見)。
為了描述這些選項,資訊清單引入了圖塊集的概念。一個圖塊集對應一個 GDAL 來源。 因此,單一圖塊集中的所有來源都必須具有相同的 GDAL 結構 (波段數量和類型、投影、轉換、缺少值)。由於 GDAL 來源可以有多個波段,因此一個圖塊集可能包含多個 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 僅用於攝入,以區分堆疊的圖塊集。
頻帶
第二個重要概念是將來源檔案與 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」。我們只想擷取「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 元件控制。
支援三種可能的遮罩設定 (但遮罩波段一律會假設為特定檔案中的最後一個波段)。
- 同一檔案中所有資料頻帶的遮罩。
- 遮蓋來自所有其他檔案的所有資料波段。
- 遮蓋部分資料波段。
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 做為另一個檔案中特定波段的遮罩,請使用下列資訊清單 (與前一個案例的差異在於 maskBands 中的 bandIds 欄位已設定):
{
"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 圖塊集的兩個波段,但只對其中一個波段 (data_band) 套用遮罩,如唯一提供的 maskBands 清單物件的 bandIds 欄位所指定。
請注意,只有 maskBands 中提及的圖塊集最後一個波段會做為遮罩波段。
金字塔式政策
Earth Engine 在擷取期間建構圖片金字塔時,必須重複將 2x2 像素網格縮減為單一像素,並以某種方式轉換像素值。根據預設,系統會計算像素值的平均值,如果光柵帶代表大致連續的資料,這在大多數情況下都是正確的做法。不過,在以下兩種情況下,依賴預設值會產生不正確的結果,此時必須設定頻帶定義中的 pyramidingPolicy 欄位 (如未設定,其值預設為「MEAN」)。
如要分類光柵圖片 (例如土地覆蓋分類),最合理的像素金字塔化方式是取四個值中的多數值,產生下一個值。這項操作是使用「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」一律會從每個 2x2 網格中擷取左上角像素的值。以下範例將「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"
}
]
}開始與結束時間
所有資產都應指定開始和結束時間,為資料提供更多背景資訊,尤其是納入集合的資產。這些欄位並非必要,但強烈建議您盡可能使用。
開始和結束時間通常是指觀測時間,而非來源檔案的產生時間。
為求簡化,結束時間會視為不含在內的邊界。舉例來說,如果資產的時間範圍正好是一天,請使用連續兩天的午夜 (例如 1980-01-31T00:00:00 和 1980-02-01T00:00:00) 做為開始和結束時間。如果資產沒有時間長度,請將結束時間設為與開始時間相同。 資訊清單中的時間應以 ISO 8601 字串表示。建議您假設結束時間不包含在內 (例如每日素材資源的隔天午夜),以簡化日期值。
範例:
{
"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": [ <stringn>> ], "affineTransform": { "scaleX": <double>, "shearX": <double>, "translateX": <double>, "shearY": <double>, "scaleY": <double>, "translateY": <double> } } ] } ], "bands": [ { "id": <string>, "tilesetId": <string>, "tilesetBandIndex": <int32>, "missingData": { "values": [<doublen>>] }, "pyramindingPolicy": <string> } ], "maskBands": [ { "tilesetId": <string>, "bandIds": [ <stringn>> ] } ], "footprint": { "points": [ { "x": <double>, "y": <doublen>> } ], "bandId": <string> }, "missingData": { "values": [<double>] }, "pyramidingPolicy": <string>, "uriPrefix": <string>, "startTime": { "seconds": <integer> }, "endTime": { "seconds": <integer> }, "properties": { <unspecified> } }
資訊清單欄位定義
名稱
string
要建立的資產名稱。
name 的格式為「projects/*/assets/**」(例如「projects/earthengine-legacy/assets/users/USER/ASSET」)。
圖塊集
list
定義圖塊集屬性的字典清單。
詳情請參閱下列 tilesets 字典元素欄位。
tilesets[i].dataType
string
指定資料的數值資料類型。預設值為 GDAL 回報的類型,在這種情況下,您不需要定義。
| 資料類型 | 值 |
|---|---|
| 未指定 | "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。主要物件應為清單的第一個元素,後續列出的則是附屬物件。如果已設定 ImageManifest.uriPrefix,每個 URI 都會加上這個前置字串。
tilesets[i].sources[j].affineTransform
dictionary
選用的仿射轉換。只有在 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
代表波段中沒有資料的值清單 (雙精度浮點數類型)。
bands[i].pyramidingPolicy
string
金字塔式政策。詳情請參閱這個連結。選項包括:
- "MEAN" (預設)
- "MODE"
- "SAMPLE"
maskBands
list
字典清單,定義來自圖塊集的單一遮罩波段屬性。
最多只能提供 1 個遮罩波段。
詳情請參閱下列 maskBands 字典元素欄位。
maskBands[i].tilesetId
string
與遮罩波段對應的圖塊集 ID。圖塊集的最後一個波段一律會做為遮罩波段。
maskBands[i].bandIds
list of strings
遮罩波段套用目標波段的 ID 清單。如果留空,遮罩波段會套用至資產中的所有波段。每個波段只能有一個對應的遮罩波段。
footprint
dictionary
定義圖片中所有有效像素足跡屬性的字典。
如果留空,預設足跡會是整張圖片。詳情請參閱下列 footprint 字典元素欄位。
footprint.points
list
定義圖片中所有有效像素足跡的點清單。點是由字典定義,其中「x」和「y」鍵具有浮點值。點清單用於描述構成簡單多邊形外部的環,該多邊形必須包含圖片所有有效像素的中心。這必須是線性環:最後一個點必須與第一個點相同。座標位於 bandId 指定的波段投影中。
注意:請使用非整數座標 (例如每個像素的中心),因為如果像素 (1x1 矩形) 與足跡相交,系統會將 footprint 視為包含像素。為避免不小心選取相鄰像素,請勿使用整數值座標,因為這些是像素之間的邊界。沿著像素中心繪製足跡,可避免納入非預期的像素,因為當預期像素與地圖邊界 (例如反子午線或極點) 相鄰時,可能會發生錯誤。
舉例來說,如果 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
波段 ID,其 CRS 定義了足跡的座標。如果留空,則會使用第一個波段。
missingData.values
list
代表圖片所有波段中沒有資料的值清單 (雙精度類型)。適用於所有未指定 missingData 的頻帶。
pyramidingPolicy
string
金字塔式政策。如未指定,系統預設會套用「MEAN」政策。適用於所有未指定專屬設定的頻帶。 詳情請參閱這個連結。選項包括:
- "MEAN" (預設)
- "MODE"
- "SAMPLE"
uriPrefix
string
選用的前置字串,會加在資訊清單中定義的所有 uris 前面。
startTime
integer
與資產相關聯的時間戳記 (如有)。這通常對應至拍攝衛星圖的時間。如果是對應到時間間隔的資產 (例如一個月或一年的平均值),這個時間戳記會對應到該間隔的開始時間。以秒和 (選用) 奈秒為單位,從 Epoch (1970-01-01) 起算。假設時區為世界標準時間。
endTime
integer
如果資產對應的是一段時間間隔 (例如一個月或一年的平均值),這個時間戳記會對應到該間隔的結束時間 (不含)。以秒和 (選用) 奈秒為單位,自 Epoch (1970-01-01) 起算。假設時區為世界標準時間。
屬性
dictionary
任意平面字典,內含鍵/值組合。鍵必須是字串,值則可以是數字或字串。使用者上傳的素材資源目前不支援清單值。
限制
JSON 資訊清單大小
JSON 資訊清單檔案大小上限為 10 MB。如果您要上傳許多檔案,請考慮減少描述資料集所需的字元數。舉例來說,使用 uriPrefix 欄位,就不必為 uris 清單中的每個 URI 提供 Google Cloud bucket 路徑。如果需要進一步縮減大小,請嘗試縮短檔案名稱。
圖片檔案格式
每個圖片檔都必須是 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)。