专栏名称: GEE遥感训练营
专注GEE遥感算法,包括遥感影像下载、遥感影像制图、遥感GIS空间分析、遥感生态评价、遥感影像融合、遥感去干扰等多元遥感云计算
目录
相关文章推荐
51好读  ›  专栏  ›  GEE遥感训练营

GEE前沿教程|在 Google Earth Engine 中进行大规模分块处理

GEE遥感训练营  · 公众号  ·  · 2024-11-26 21:49

正文

请到「今天看啥」查看全文


在 Google Earth Engine(GEE)中导出大数据集时,尤其是高分辨率影像或大范围区域的数据,往往会超出系统的导出任务限制。 对大规模导出进行分块(Tiling)处理是绕过这些限制的常用方法。 从 GEE导出大规模栅格数据时,建议将导出数据分割为若干较小的分块。在本文中,我将分享在目标投影中创建分块导出的最佳实践,以确保这些分块在后期拼接时不会出现像素间的缝隙或重叠。 核心概念是利用 crsTransform 参数,确保每个分块都位于相同的像素网格上。

01

理论基础


在导出全球或国家尺度的高分辨率影像时,任务可能需要数小时甚至数天才能完成。为了加快超大规模导出任务的处理速度,推荐的做法是将影像划分为较小的分块,并将每个分块作为单独的任务进行导出。

正确执行上述操作需要对 Earth Engine 中投影的细节有深入理解,并确保所有与投影相关的操作在 GEE 中保持一致。以下是将大规模影像分割为多个分块的推荐工作流程:

  1. 使用 Earth Engine 中的 coveringGrid() 函数,在所需的坐标参考系(CRS)中创建一个分块网格。

  2. 计算一个 CRS Transform,用于定义目标像素网格,并确保每个导出分块使用相同的像素网格。

  3. 对像素进行重新采样或聚合操作(Resample 或 Aggregate Pixels)。

  4. 设置一个 NoData 值,标识无效数据区域。

  5. 使用相同的 CRS Transform 导出每个分块。

接下来,我们将通过一个示例及相关代码来详细展示这一流程。示例中,我们将使用 ESA WorldCover 土地覆盖数据集,导出覆盖整个爱沙尼亚国家范围的影像分块。

对于这类需要创建和启动多个导出任务的批量导出操作,建议优先使用 Earth Engine 的 Python API.

02

数据准备


我们选择一个国家,并为该区域创建裁剪后的 ESA WorldCover 2020 分类数据。随后,我们使用 geemap 可视化显示该影像。
worldcover = ee.ImageCollection("ESA/WorldCover/v100")lsib = ee.FeatureCollection("USDOS/LSIB_SIMPLE/2017") # Select the countrycountry = lsib.filter(ee.Filter.eq('country_na', 'Estonia'))geometry = country.geometry() # Select the image for exportimage = worldcover.first().clip(geometry) m = geemap.Map(width=800)m.addLayer(image, {}, 'Input Image');m.centerObject(country, 7)m

03

创建格网


我们创建了一个网格并计算了 CRS Transform 的相关参数。网格中的每个分块将按照选定的像素网格导出为单独的影像。如果导出的影像尺寸超过 10,000 x 10,000 像素,Earth Engine 会将输出自动分割为多个文件。为避免这种情况,建议将分块尺寸设置为不超过 10,000 像素。由于我们的输入影像像素分辨率为 10 米,因此我们将网格大小设置为 100,000 x 100,000 米。
# Choose the export CRScrs = 'EPSG:3301' # Choose the pixel size for export (meters)pixelSize = 10 # Choose the export tile size (pixels)tileSize = 10000 # Calculate the grid size (meters)gridSize = tileSize * pixelSize # Create the grid covering the geometry boundsbounds = geometry.bounds(**{  'proj': crs, 'maxError': 1}) grid = bounds.coveringGrid(**{  'proj':crs, 'scale': gridSize}) m.addLayer(grid, {'color': 'blue'}, 'Grid')m

04

计算 CRS Transform(坐标参考系变换参数)


当栅格数据被重投影到另一个坐标参考系(CRS)时,会生成一个目标像素网格,并根据输入栅格的像素值计算每个输出像素的值。输出像素网格由 crsTransform 参数决定,该参数指定网格的起始点(即左上角像素的坐标)和每个像素的大小(分辨率)。在 Google Earth Engine 中,可以在所有与投影相关的函数中指定 crsTransform 参数,以确保所有计算在指定的像素网格上进行。请记住,在 Google Earth Engine 中,通常无需担心影像的输入投影。您可以直接混合和组合具有不同投影的影像,而无需先对它们进行重投影。只有在执行计算或导出数据时,才需要指定输出投影。GEE 会在内部将所有输入数据自动重投影到指定的目标投影,以确保计算的正确性和一致性。
# Calculate the coordinates of the top-left corner of the gridbounds = grid.geometry().bounds(**{  'proj': crs, 'maxError': 1}); # Extract the coordinates of the gridcoordList = ee.Array.cat(bounds.coordinates(), 1) xCoords = coordList.slice(1, 0, 1)yCoords = coordList.slice(1, 1, 2) # We need the coordinates of the top-left pixelxMin = xCoords.reduce('min', [0]).get([0,0])yMax = yCoords.reduce('max', [0]).get([0,0]) # Create the CRS Transform # The transform consists of 6 parameters:# [xScale, xShearing, xTranslation, #  yShearing, yScale, yTranslation]transform = ee.List([    pixelSize, 0, xMin, 0, -pixelSize, yMax]).getInfo()print(transform)

05

重采样或聚合像素


默认情况下,影像会使用最近邻方法(Nearest Neighbor)重新采样到目标像素网格。这种方式适用于大多数影像类型,但在某些操作中,您可能需要更改这种行为。

何时需要重采样像素?

当原始像素大小与目标像素大小相近时,重采样是适合的选择。

  • 对于离散栅格 (例如土地覆盖分类数据),默认的最近邻方法是合适的,因为它可以保留原始的类别值。

  • 对于连续栅格 (例如高程模型或气候数据),建议使用双线性(bilinear)或双三次(bicubic)重采样方法,以获得更平滑的结果。可以通过以下方法实现:

    • image.resample('bilinear') 使用双线性重采样。

    • image.resample('bicubic') 使用双三次重采样。

何时需要聚合像素?

当目标像素的大小远大于原始像素时,需要使用适当的统计函数将输入像素聚合成更大的像素。

  • 对于离散栅格 ,使用众数(mode)聚合,例如 ee.Reducer.mode()

  • 对于连续栅格 ,使用平均值(mean)聚合,例如 ee.Reducer.mean()

  • 对于人口栅格 ,使用求和(sum)聚合,例如 ee.Reducer.sum()

重采样和聚合像素的相关内容可以参考 GEE 用户指南,或者参考我们关于聚合人口栅格的文章以获取更多详细信息。

在我们的例子中,由于输入的是像素大小相同的离散栅格,因此这一步骤无需额外处理。

06

设置 NoData 值(无效数据值)


这是一个重要的步骤。如果影像中存在被掩膜的像素,导出的分块可能会出现尺寸不一致的情况。为了确保每个分块具有相同的尺寸且没有像素间的缝隙或重叠,应对所有被掩膜的像素使用 unmask() 方法,并设置一个 NoData 值(无效数据值)。

noDataValue = 0exportImage = image.unmask(**{    'value':noDataValue,    'sameFootprint': False})

07

分块导出


现在,我们可以使用网格图层将影像导出为分块数据。通过遍历每个网格要素,获取其几何信息,并使用指定的投影坐标系(CRS)和 CRS Transform 参数导出影像。利用 ee.batch.Export API,可以为每个分块自动创建并启动导出任务。

tile_ids = grid.aggregate_array('system:index').getInfo();print('Total tiles', len(tile_ids)) # Export each tilefor i, tile_id in enumerate(tile_ids):    feature = ee.Feature(grid.toList(1, i).get(0))    geometry = feature.geometry()    task_name = 'tile_' + tile_id.replace(',', '_')    task = ee.batch.Export.image.toDrive(**{        'image': exportImage,        'description': f'Image_Export_{task_name}',        'fileNamePrefix': task_name,        'folder':'earthengine',        'crs': crs,        'crsTransform': transform,        'region': geometry,        'maxPixels': 1e10    })    task.start()    print('Started Task: ', i+1)

您可以查看完整的代码,其中包含将大影像分割为分块并单独导出每个分块的完整可复现示例。生成的影像分块完美对齐,没有缝隙或像素重叠。

Google Colab Notebook: https://colab.research.google.com/github/spatialthoughts/projects/blob/master/ee-python/large_gridded_exports.ipynb

GEE-Javascript: https://code.earthengine.google.co.in/022063d17caeb0868d806ee2ca457e93

往期回顾

1. 北京大学在Nature Food在优化亚洲稻田灌溉模式研究中取得新进展
2. ISPRS前沿|1991–2023年青藏高原九千座湖泊全尺度演变的年度精细化制图
3. GEE+ChatGPT科研必备|科研论文搞起来!!!







请到「今天看啥」查看全文