清单上传
如果您需要更多的灵活性上传图片到谷歌地球引擎(EE),比 代码编辑器UI 或upload
在命令 “earthengine”命令行工具 提供,您可以通过描述使用被称为一个JSON文件“的图片上传这么做manifest”并使用upload image --manifest
命令行工具的命令。
请参阅此 Colab 笔记本中的完整示例, 该示例 演示使用清单将图像图块作为单个资产上传。
一次性设置
- 清单上传仅适用于位于Google Cloud Storage 中的文件 。要开始使用 Google Cloud Storage,请 创建一个 Google Cloud 项目(如果您还没有)。请注意,设置需要指定用于计费的信用卡。EE 本身此时不会向任何人收费,但在将文件上传到 EE 之前将文件传输到 Google Cloud Storage 的 成本很小。对于典型的上传数据大小(数十或数百 GB),成本将非常低。
- 在您的项目中, 打开 Cloud Storage API并 创建一个存储桶。
- 安装 Earth Engine Python 客户端。它包括
earthengine
命令行工具,我们将使用它来上传数据。 - 对于自动上传,您可能需要使用 与您的项目关联的GCP 服务帐号。您不需要服务帐户进行测试,但是当您有时间时,请开始熟悉使用它们。
资产 ID 和名称
清单中的资产名称需要与 Earth Engine 中其他地方可见的资产 ID 略有不同。要上传资产 ID 以users/some_user
或开头projects/some_project
的资产,清单中的资产名称必须projects/earthengine-legacy/assets/
在 ID 前添加字符串 。例如,EE 资产 ID users/username/my_geotiff
应使用 name 上传 projects/earthengine-legacy/assets/users/username/my_geotiff
。
是的,这意味着像 ID 这样的 IDprojects/some_projects/some_asset
被转换为名称,其中projects
提到了两次: projects/earthengine-legacy/assets/projects/some_projects/some_asset
。这令人困惑,但对于符合 Google Cloud API 标准是必要的。
使用清单
最简单的清单如下所示。它上传一个名为small.tif
.google 云存储存储桶的文件gs://earthengine-test
。
{
"name": "projects/earthengine-legacy/assets/users/username/some_folder/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 资产中的条带堆叠在一起。
(可能必须同时使用这两种方式,但这种情况很少见。)
为了描述这些选项,清单引入了tileset的概念。单个图块集对应于单个 GDAL 源。因此,单个瓦片集中的所有源必须具有相同的 GDAL 结构(波段的数量和类型、投影、变换、缺失值)。由于一个 GDAL 源可以有多个波段,一个图块集可能包含多个 EE 波段的数据。
对于马赛克摄取,清单将如下所示:
代码语言:javascript复制{
"name": "projects/earthengine-legacy/assets/users/username/some_folder/some_asset_id",
"tilesets": [
{
"sources": [
{
"uris": [
"gs://bucket/N30W22.tif"
]
},
{
"uris": [
"gs://bucket/N31W22.tif"
]
}
]
}
]
}
对于单独的 band,清单将如下所示(您还需要添加一个bands
部分,如下所述):
{
"name": "projects/earthengine-legacy/assets/users/username/some_folder/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
部分可以省略,在这种情况下,首先从第一个tileset中的文件创建band,然后从下一个tileset中创建,依此类推。默认情况下,波段被命名为“b1”、“b2”等。要覆盖默认波段名称,请在末尾包含一个“波段”部分,如下所示:
{
"name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
"tilesets": [
{
"sources": [
{
"uris": [
"gs://bucket/rgb.tif"
]
}
]
}
],
"bands": [
{
"id": "R",
"tileset_band_index": 0
},
{
"id": "G",
"tileset_band_index": 1
},
{
"id": "B",
"tileset_band_index": 2
}
]
}
EE 波段的数量必须与所有瓦片集中的波段总数相同。
如果您不想从文件中摄取所有波段,您可以使用该 tileset_band_index
字段来指示应该摄取哪个 GDAL 波段。第一个波段的 tileset_band_index 为 0。
例子:
假设源文件有四个波段:“tmin”、“tmin_error”、“tmax”、“tmax_error”。我们只想摄取“tmin”和“tmax”。相关清单部分将如下所示:
代码语言:javascript复制{
"name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
"tilesets": [
{
"id": "temperature",
"sources": [
{
"uris": [
"gs://bucket/temperature.tif"
]
}
]
}
],
"bands": [
{
"id": "tmin",
"tileset_band_index": 0,
"tileset_id": "temperature"
},
{
"id": "tmax",
"tileset_band_index": 2,
"tileset_id": "temperature"
}
]
}
面膜带
带掩蔽由mask_bands
清单的组件控制。掩码带可以应用于所有带或特定带。以下两个示例描述了差异。
要使用 geotiff 作为所有波段的掩码,请使用以下结构:
代码语言:javascript复制{
"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",
"tileset_id": "data_tileset"
},
{
"id": "qa_band",
"tileset_id": "data_tileset"
}
],
"mask_bands": [
{
"tileset_id": "mask_tileset"
}
]
}
要使用 geotiff 作为特定波段的掩码,请使用以下结构(不同之处在于设置了band_ids
字段 in mask_bands
):
{
"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",
"tileset_id": "data_tileset"
},
{
"id": "qa_band",
"tileset_id": "data_tileset"
}
],
"mask_bands": [
{
"tileset_id": "mask_tileset",
"band_ids": "data_band"
}
]
}
正如您在第二个示例中所看到的,我们正在使用data_tileset
图块集中的两个波段,但仅将遮罩应用于其中一个波段 ( data_band
),如band_ids
唯一提供的mask_bands
列表对象的字段所指定的那样。
请注意,只有 中提到的图块集的最后一个带mask_bands
用作遮罩带。
金字塔政策
当 Earth Engine 在摄取过程中构建图像金字塔时,它必须反复将 2x2 像素网格减少为单个像素,以某种方式转换像素值。默认情况下,像素值是平均的,当栅格带表示或多或少的连续数据时,在大多数情况下这是正确的做法。但是有两种情况依赖默认会产生不正确的结果,在这种情况下pyramiding_policy
必须设置band定义中的字段(如果不设置,则默认其值为“MEAN”)。
对于光栅图像的分类(例如土地覆盖分类),金字塔像素最合乎逻辑的方法是取四个值中的大部分来生成下一个值。这是通过“MODE”金字塔策略完成的:
代码语言:javascript复制{
"name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
"tilesets": [
{
"sources": [
{
"uris": [
"gs://bucket/landcover.tif"
]
}
]
}
],
"bands": [
{
"id": "landcover",
"pyramiding_policy": "MODE"
}
]
}
对于“MEAN”和“MODE”都没有意义的光栅带(例如,位打包像素),应该使用“SAMPLE”金字塔策略。“SAMPLE”总是从每个 2x2 网格中获取左上角像素的值。以下示例将“MEAN”金字塔策略分配给表示连续变量 (“NDVI”) 的波段,并将“SAMPLE”分配给数据的“QA”波段。
代码语言:javascript复制{
"name": "projects/earthengine-legacy/assets/users/username/some_folder/some_id",
"tilesets": [
{
"sources": [
{
"uris": [
"gs://bucket/ndvi.tif"
]
}
]
}
],
"bands": [
{
"id": "NDVI",
"tileset_band_index": 0,
"pyramidingPolicy": "MEAN"
},
{
"id": "QA",
"tileset_band_index": 1,
"pyramidingPolicy": "SAMPLE"
}
]
}
开始和结束时间
所有资产都应指定开始和结束时间,以便为数据提供更多上下文,尤其是当它们包含在集合中时。这些字段不是必需的,但我们强烈建议您尽可能使用它们。
开始和结束时间通常是指观察的时间,而不是源文件产生的时间。
为简单起见,结束时间被视为唯一的边界。例如,对于恰好跨越一天的资产,使用连续两天的午夜(例如,1980-01-31T00:00:00 和 1980-02-01T00:00:00)作为开始和结束时间。如果资产没有持续时间,请将结束时间设置为与开始时间相同。将清单中的时间表示为 ISO 8601 字符串。我们建议假设结束时间是唯一的(例如,每日资产的第二天午夜)以简化日期值。
例子:
代码语言:javascript复制{
"name": "projects/earthengine-legacy/assets/users/username/some_folder/some_asset_id",
"tilesets": [
{
"sources": [
{
"uris": [
"gs://bucket/img_20190612.tif"
]
}
]
}
],
"start_time": "1980-01-31T00:00:00Z",
"end_time": "1980-02-01T00:00:00Z"
}
清单结构参考
以下 JSON 结构包括所有可能的图像上传清单字段。在以下 清单字段定义部分中查找字段定义。
代码语言:javascript复制{
"name": <string>,
"tilesets": [
{
"data_type": <string>,
"id": <string>,
"crs": <string>,
"sources": [
{
"uris": [
<string>
],
"affine_transform": {
"scale_x": <double>,
"shear_x": <double>,
"translate_x": <double>,
"shear_y": <double>,
"scale_y": <double>,
"translate_y": <double>
}
}
]
}
],
"bands": [
{
"id": <string>,
"tileset_id": <string>,
"tileset_band_index": <int32>,
"missing_data": {
"values": [<double>]
},
"pyraminding_policy": <string>
}
],
"mask_bands": [
{
"tileset_id": <string>,
"band_ids": [
<string>
]
}
],
"footprint": {
"points": [
{
"x": <double>,
"y": <double>
}
],
"band_id": <string>
},
"missing_data": {
"values": [<double>]
},
"pyramiding_policy": <string>,
"uri_prefix": <string>,
"start_time": {
"seconds": <integer>
},
"end_time": {
"seconds": <integer>
},
"properties": {
<unspecified>
}
}
清单字段定义
名称
string
要创建的资产的名称。 name
格式为“projects/*/assets/**”(例如,“projects/earthengine-legacy/assets/users//”)。
图块集
list
定义图块集属性的字典列表。有关tilesets
更多信息,请参阅以下字典元素字段。
图块集[i] . 数据_类型
string
指定数据的数值数据类型。默认是GDAL上报的类型,这种情况不需要定义。
数据类型 | 价值 |
---|---|
未指定 | "DATA_TYPE_UNSPECIFIED" |
8 位有符号整数 | “INT8” |
8 位无符号整数 | “UINT8” |
16 位有符号整数 | “INT16” |
16 位无符号整数 | “UINT16” |
32 位有符号整数 | “INT32” |
32 位无符号整数 | “UINT32” |
32 位浮点数 | “浮动32” |
64 位浮点数 | “FLOAT64” |
图块集[i] . ID
string
图块集的 ID。在资产清单中指定的tilesets 中必须是唯一的。这个 ID 在处理步骤中被丢弃;它仅用于将图块集链接到带。空字符串是有效的 ID。
图块集[i] . crs
string
像素网格的坐标参考系统,在可能的情况下指定为标准代码(例如 EPSG 代码),否则指定为 WKT 格式。
图块集[i] . 来源
list
定义图像文件及其边车属性的字典列表。有关sources
更多信息,请参阅以下字典元素字段。
图块集[i] . 来源[j] . URIs
string
要摄取的数据的 URI。目前,仅支持 Google Cloud Storage URI。每个 URI 必须按以下格式指定:“gs://bucket-id/object-id”。主要对象应该是列表的第一个元素,然后列出边车。每个 URI 都以ImageManifest.uri_prefix
if 设置为前缀 。
图块集[i] . 来源[j] . 仿射_变换
dictionary
一个可选的仿射变换。仅当来自uris
(包括任何边车)的数据不足以放置像素时才应指定 。作为具有以下键的字典提供:“scale_x”、“shear_x”、“translate_x”、“shear_y”、“scale_y”、“translate_y”。有关更多信息,请参阅 此参考资料。
示例键和值:
代码语言:javascript复制{
"scale_x": 0.1,
"shear_x": 0.0,
"translate_x": -180.0,
"shear_y": 0.0,
"scale_y": -0.1,
"translate_y": 90.0
}
乐队
list
定义来自瓦片集的单个波段的属性的字典列表。请注意,资产的波段顺序与 的顺序相同bands
。有关bands
更多信息,请参阅以下字典元素字段。
乐队[i] . ID
string
乐队的 ID(名称)。
乐队[i] . 地形设置_ ID
string
与band对应的tileset的ID。
乐队[i] . 图块集_带_索引
int32
来自与波段对应的图块集中的从零开始的波段索引。
乐队[i] . 丢失_数据。价值观
list
表示带区中没有数据的值列表(双精度型)。
乐队[i] . 金字塔式_政策
string
金字塔政策。有关更多信息,请参阅 此链接。选项包括:
- “平均值”(默认)
- “模式”
- “样本”
mask_bands
list
定义来自瓦片集的单个遮罩带属性的字典列表。目前最多可以提供1个遮罩带。有关mask_bands
更多信息,请参阅以下字典元素字段。
面具_乐队[i] 。地形设置_ ID
string
mask band对应的tileset的ID。图块集的最后一个带始终用作遮罩带。
面具_乐队[i] 。带_ IDS
list of strings
掩码波段适用的波段 ID 列表。如果为空,则遮罩带将应用于资产中的所有带。每个波段可能只有一个对应的掩码波段。
脚印
dictionary
定义图像中所有有效像素的足迹属性的字典。如果为空,则默认封装是整个图像。有关footprint
更多信息,请参阅以下字典元素字段。
足迹。积分
list
定义图像中所有有效像素的足迹的点列表。点由具有浮点值的“x”和“y”键的字典定义。点列表用于描述形成简单多边形外部的环,该环必须包含图像的所有有效像素的中心。这必须是一个线性环:最后一个点必须等于第一个点。坐标在由 指定的波段的投影中band_id
。
注意:使用非整数坐标,例如每个像素的中心,因为 footprint
如果像素(1x1 矩形)与足迹相交,则将其视为包含一个像素。为避免意外选择相邻像素,请勿使用整数值坐标,因为这些是像素之间的边界。沿着像素中心绘制足迹可防止包含非预期的像素,当预期的像素与地图边界(如反子午线或极点)相邻时,这可能会导致错误。
例如,对于具有所有四个有效像素的 2x2 图像,以下是一种可能的环:
代码语言:javascript复制[
{
"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
}
]
足迹。带_ ID
string
其 CRS 定义足迹坐标的频段的 ID。如果为空,则使用第一个波段。
丢失_数据。价值观
list
表示图像所有波段中没有数据的值列表(双精度型)。适用于所有没有指定自己的频段missing_data
。
金字塔式_政策
string
金字塔政策。如果未指定,则默认应用策略“MEAN”。适用于所有没有指定自己的频段。有关更多信息,请参阅 此链接。选项包括:
- “平均值”(默认)
- “模式”
- “样本”
uri _前缀
string
uris
在清单中定义的所有前缀的可选前缀。
开始_时间
integer
与资产关联的时间戳(如果有)。这通常对应于拍摄卫星图像的时间。对于与时间间隔相对应的资产,例如一个月或一年的平均值,此时间戳对应于该时间间隔的开始。指定为自纪元 (1970-01-01) 以来的秒和(可选)纳秒。假定在 UTC 时区。
结束_时间
integer
对于与时间间隔相对应的资产,例如一个月或一年的平均值,此时间戳对应于该时间间隔的结束(不包括)。指定为自纪元 (1970-01-01) 以来的秒和(可选)纳秒。假定在 UTC 时区。
特性
dictionary
键值对的任意平面字典。键必须是字符串,值可以是数字或字符串。用户上传的资产尚不支持列表值。