2020年厄瓜多尔帕武河流域的土地覆盖图。此图是使用Google Earth Engine Python API和Geemap创建的。数据来源如下:Friedl, M., Sulla-Menashe, D. (2022); Lehner, B., Grill G. (2013)及Lehner, B., Verdin, K., Jarvis, A. (2008)。
简介作为一名气候科学家来说,Google 地球引擎(GEE)是我工具箱里的一个强大工具。再也不需要把庞大的卫星图像下载到我的电脑上了。
GEE的主要API是使用Javascript,不过Python用户也可以使用一个强大的API来完成类似的任务。不幸的是,用Python学习GEE的资源较少。
然而,我特别喜欢Python。自从我知道了GEE有一个Python API后,我就想象了将GEE强大的云端处理功能与Python的强大功能结合所带来的可能性。
这五课来自我最近的一个项目,该项目涉及在厄瓜多尔的某个流域分析水资源平衡和干旱情况。不过,这些提示、代码片段和示例可以用于任何项目。
这个故事按数据分析项目的常规顺序呈现每一课:数据准备和规划、分析和数据可视化。
值得一提的是,我还会提供一些与你使用的语言无关的通用建议。
本文是为GEE(地球引擎)初学者准备的,假定读者已经熟悉Python和一些地理空间概念。
第1课:了解GEE功能:如果你懂 Python,但刚接触 GEE(就像我之前一样),你应该知道 GEE 有优化过的函数用于处理卫星图像。我们在这里不会详细讲解这些函数;你应该查看一下官方文档。
不过,建议你先看看GEE能否做你想要的分析。我刚开始用GEE时,主要是用它来找数据,就用了它的基本功能。大部分分析的代码我都是用Python写的。这种方法虽然行得通,但经常会遇到不少麻烦。后面我会讲讲这些问题。
不要仅仅局限于学习GEE的基础功能。如果你懂Python(或编程的话),这些功能的学习曲线相对平缓。尽可能多地使用它们吧——从效率角度看,这么做绝对值得。
最后一点:GEE 函数甚至可以帮助你进行机器学习任务。这些 GEE 函数容易实现,并可以帮助你解决许多问题。只有当你用这些函数无法解决问题时,才考虑从头编写 Python 代码来解决你的问题。
比如,在这节课中,考虑实现一个集群划分算法的例子。
使用GEE函数的示例代码 # 从图像中采样以供聚类使用
sample_points = clustering_image.sample(
region=galapagos_aoi,
scale=30, # 单位:米
numPixels=5000, # 采样点的数量
geometries=False # 不包含几何信息以节省内存
)
# 进行K-means聚类(无监督)
clusterer = ee.Clusterer.wekaKMeans(5).train(sample_points)
# 对图像进行聚类
result = clustering_image.cluster(clusterer)
代码示例:Python
import rasterio
import numpy as np
from osgeo import gdal, gdal_array
# 让GDAL抛出Python异常并注册所有驱动
gdal.UseExceptions()
gdal.AllRegister()
# 打开Sentinel-2_L2A_Galapagos.tiff文件
img_ds = gdal.Open('Sentinel-2_L2A_Galapagos.tiff', gdal.GA_ReadOnly)
if img_ds is None:
raise FileNotFoundError("无法打开指定的文件,请检查文件路径和权限.")
# 准备一个空数组来存储所有波段的图像数据
img = np.zeros(
(img_ds.RasterYSize, img_ds.RasterXSize, img_ds.RasterCount),
dtype=gdal_array.GDALTypeCodeToNumericTypeCode(img_ds.GetRasterBand(1).DataType),
)
# 读取每个波段到数组的相应切片中
for b in range(img_ds.RasterCount):
img[:, :, b] = img_ds.GetRasterBand(b + 1).ReadAsArray()
print("包含所有波段的图像的维度:", img.shape) # (高度, 宽度, 波段数)
# 重塑数据以进行处理
new_shape = (img.shape[0] * img.shape[1], img.shape[2]) # (像素数, 波段数)
X = img.reshape(new_shape)
print("所有波段数据重塑后的维度:", X.shape) # (像素数, 波段数)
第一个代码块不仅更短,而且因为GEE函数是为云扩展设计的,因此它会更高效地处理大型卫星数据。
虽然GEE的功能很强大,但在扩展项目时,了解云处理的限制很重要。
第2课:了解GEE云处理能力的局限性免费获取云计算资源来处理卫星图像是一种福气。然而,这并不奇怪,GEE(Google 地球引擎)为确保资源公平分配而设限。如果你打算将其用于非商业的大规模项目(例如研究亚马逊地区的森林砍伐),并且希望完全在免费层级的限制内完成,你需要提前做好详细的计划。我的一些建议是:
- 限制你各个区域的大小,将它们分割开来,分批次处理。在我的项目中,由于我只处理一个小的流域,所以我不需要这样做。然而,如果你的项目涉及较大的地理区域,这将是第一步的逻辑选择。
- 优先采用GEE函数来优化你的脚本(参见第1课)。
- 选择那些能够优化计算能力的数据集。例如,在我最后一个项目中,我使用了气候危害小组红外降水与站点数据(CHIRPS)。原始数据集具有每日的时间分辨率。然而,它提供了一个替代版本叫做“PENTAD”,每五天提供一次数据,对应这五天的降水量总和。使用这个数据集让我在处理紧凑版本时不牺牲结果质量的同时节省了计算能力。
- 检查你数据集的描述,因为其中可能包含可以节省计算能力的缩放因子。例如,在我的水文平衡项目中,我使用了中分辨率成像光谱仪(MODIS)数据。具体来说,我使用了MOD16数据集,这是一个现成的蒸散发(ET)数据产品。根据文档,我可以将我的结果乘以0.1的缩放因子。缩放因子有助于通过调整数据类型来减少存储空间需求。
- 如果情况最坏的话,准备好妥协。如果研究标准允许,降低分析的分辨率要求。例如,“reduceRegion” GEE函数可以帮助你总结某区域的数据(如总和、平均值等)。它有一个叫做“scale”的参数,允许你改变分析的尺度。例如,如果你的卫星数据分辨率为10米,而GEE无法处理你的分析,你可以将“scale”参数调整到更低的分辨率(例如50米)。
这里有一个来自我抗旱项目中的水资源平衡的例子,看看下面这段代码:
# 将集合缩减为单个图像(时间跨度内的MSI均值)
MSI_mean = MSI_collection.select('MSI').mean().clip(pauteBasin)
# 使用reduceRegion计算最小值和最大值
stats = MSI_mean.reduceRegion(
reducer=ee.Reducer.minMax(), # 计算最小值和最大值的缩减器
geometry=pauteBasin, # 指定区域
scale=500, # 尺度(以米为单位)
maxPixels=1e9 # 最大处理的像素数
)
# 将结果作为字典获取
min_max = stats.getInfo()
# 打印最小值和最大值是:
print('最小值和最大值:', min_max)
在我的项目里,我用了一张来自Sentinel-2卫星的图片来计算土壤湿度指数(Moisture Soil Index, MSI)。然后,我使用了“reduceRegion”GEE函数,这个函数会计算该区域内的数据总结,比如平均值和总和。
就我而言,我需要找到MSI值的最高和最低,以确保我的结果是合理的。下面的图显示了研究区域内MSI值的空间分布。
2010–2020年帕图流域(厄瓜多尔)的月平均土壤湿度指数值。使用Google Earth Engine Python API和Geemap生成的图像。数据来源:欧洲空间局(注:原文中的年份为2025年,这里可能有误);Lehner, B., Grill G. (2013) 和 Lehner, B., Verdin, K., Jarvis, A. (2008)。
原始图像的分辨率为10米。GEE难以处理数据。因此,我调整了scale参数,将分辨率从10米降到500米。调整参数后,GEE就能处理数据了。
第3课:优先使用现成的分析产品我对数据质量特别上心。所以,虽然我经常用数据,但很少会完全信任未经验证的数据。我喜欢花时间确保数据分析前已经准备妥当。不过,别让图像修正的问题拖慢了你的进度。
我花太多时间在图像校正上,这源于通过传统方法学习遥感和图像校正。这样说的意思是,我使用了一些软件来进行大气和几何校正。
如今,支持卫星任务的科研机构可以提供高度预处理的图像。实际上,GEE的一大特点是其目录功能,这使得查找即用的分析产品变得非常容易,用户可以轻松上手。
预处理是任何数据科学项目中耗时最多的任务。所以,它需要被妥善规划和管理。
在开始一个项目之前,最好的做法是建立数据质量标准。根据这些标准,确保有足够的时间找到最佳产品(GEE可以帮助找到这样的产品),并仅进行必要的修正(例如,进行云层掩膜)。
第4课:彻底检查GEE目录以避免从零开始如果你跟我一样热爱用 Python 编程,你可能会发现自己经常从零开始编写所有东西。
作为一名刚开始接触编程的博士生,我编写了一个脚本,在研究区域内进行t检验。后来,我发现了一个Python库,可以完成相同任务。当我比较我的脚本结果与使用该库得到的结果时,结果一致。不过,如果一开始就用这个库,会节省不少时间。
我分享这个经验是为了帮助你避免在使用GEE时犯这些常见的错误。我将举我在水资源平衡项目中的两个例子。
例子1为了计算我流域的水平衡,我需要ET数据。ET不是一个可以直接观测到的变量(如降水),它需要通过计算来获得。
ET的计算其实挺复杂的。你可以查教科书中的方程式,并用Python来实现这些方程。然而,一些研究人员已经发表了一些与这个计算相关的论文,并将他们的研究成果分享给了社区。
这时就轮到GEE登场了。GEE目录不仅提供了观测数据(正如我最初所想),而且还提供了许多派生产品和模型数据集(比如再分析数据、土地覆盖、植被指数等)。你知道吗?我在GEE目录中找到了一个现成的全球蒸散发数据集——简直是个救星!
例子二:我也算是一个GIS的专业人士。多年来,我为我的工作积累了大量的GIS数据,比如以Shapefile格式保存的水系边界。
在我的水资源平衡项目中,我感觉应该将我的流域边界 shapefile 上传到我的 GEE 项目中。然后,我将其转换为 Geopandas 对象并继续进行后续分析。
在这种情况下,我没有那么幸运。我浪费了许多宝贵的时间使用这个Geopandas对象,但无法很好地将其与GEE融合。最终,这样做没有意义。GEE确实提供了一个易于使用的水系边界数据产品。
因此,尽量让工作流程留在GEE里,如果可能的话。
第五课:使用Geemap绘图正如本文开头提到的,将GEE与Python库结合使用可以非常有力量。
然而,即使是简单的分析和绘图,这种整合也不显得容易。
这里就是 Geemap 的用武之地。Geemap 是一个专为在 GEE 上进行交互式地理空间分析和可视化的 Python 工具包。
此外,我还发现它还可以帮助在Python中创建静态图。在我的水资源平衡和干旱项目中,我用GEE和Geemap制作了图。本文中的图片都是用这些工具制作的。
概要:
GEE是一个强大的工具,然而,作为初学者,遇到困难是不可避免的。本文提供了一些建议和技巧来帮助你用GEE Python API开始学习得更好。
参考文献欧洲航天局 (2025). 哨兵-2多光谱成像仪(MSI):2A级数据产品。
Friedl, M., Sulla-Menashe, D. (2022). MODIS/Terra+Aqua 全球 yearly L3 500m SIN Grid V061 [数据集]. NASA EOSDIS 地表过程分布式主动存档中心. 2025年1月15日访问https://doi.org/10.5067/MODIS/MCD12Q1.061
Lehner, B., Verdin, K., Jarvis, A. (2008): 基于空间高度数据的新全球水文图。Eos, 89(10): 93–94.
Lehner, B., Grill G. (2013): 全球河流水文数据及网络路径规划:基础数据及研究世界上的大型河流系统的新方法。《水文过程》,27(15): 2171–2186。数据可以在[www.hydrosheds.org]找到。
共同学习,写下你的评论
评论加载中...
作者其他优质文章