本文介绍在谷歌地球引擎(Google Earth Engine,GEE)中,求取多年时间中,遥感影像在每1
个8
天时间间隔内的多年平均值的方法。
本文是谷歌地球引擎(Google Earth Engine,GEE)系列教学文章的第24
篇,更多GEE文章请参考专栏:GEE学习与应用。
首先,来明确一下本文的需求。我们现在希望,计算Landsat 7与Landsat 8这2
个遥感影像,在指定的研究区域中,于2014
年至2020
年里,从每1
年的第1
天开始,到每1
年的最后1
天结束,其中每1
个8
天时间间隔内的平均值。换句话说,我们希望计算研究区域中,2014
年至2020
年这7
年中,每1
年的第001
天至008
天这8
天内,所有遥感影像的平均值(相当于先对每1
年的这8
天内的遥感影像求平均,然后再对这7
年里的7
个结果进一步做平均;随后,计算这7
年中,每1
年的第009
天至016
天这8
天内,所有遥感影像的平均值;再计算这7
年中,每1
年的第017
天至024
天这8
天内,所有遥感影像的平均值,以此类推。
因为这个需求涉及到大量的遥感影像,如果我们在本地操作的话需要下载大量的遥感影像数据,较为不便。因此,这里就介绍一下在GEE中实现这一需求的方法。本文所需代码如下。
var selectedDays = ee.List.sequence(1, 366, 8);
var roi = ee.Geometry.Rectangle(101, 31, 103.5, 33.5);
var landsat_7 = ee.ImageCollection("LANDSAT/LE07/C02/T1_L2")
.filterDate("2014-01-01", "2021-01-01")
.select(["SR_B1", "SR_B2", "SR_B3", "SR_B4"])
.map(function(image) {
return image.clip(roi).rename(["B1", "B2", "B3", "B4"]);
});
var landsat_8 = ee.ImageCollection("LANDSAT/LC08/C02/T1_L2")
.filterDate('2014-01-01', '2021-01-01')
.select(["SR_B2", "SR_B3", "SR_B4", "SR_B5"])
.map(function(image) {
return image.clip(roi).rename(["B1", "B2", "B3", "B4"]);
});
var landsat = landsat_7.merge(landsat_8);
// Map.addLayer(landsat, {}, "Landsat 7 and 8");
var filterAndClip = function(day) {
var start = ee.Number(day);
var end = start.add(7);
var filtered = landsat.filter(ee.Filter.calendarRange(start, end, 'day_of_year'));
// Map.addLayer(filtered, {}, 'Landsat');
var filtered_mean = filtered.mean();
// Map.addLayer(filtered_mean, {}, "Landsat Mean");
// print(filtered_mean);
return filtered_mean;
};
for (var i = 0; i < selectedDays.length().getInfo(); i++) {
var day = selectedDays.get(i);
var filtered = filterAndClip(day);
var exportParams = {
image: filtered,
description: ee.Number(day).format('%03d').getInfo(),
folder: "landsat_ref_8_days",
scale: 30,
region: roi,
maxPixels: 10000000000000
};
Export.image.toDrive(exportParams);
}
其中,我们创建了一个名为selectedDays
的变量,它是一个包含了从1
到366
的列表,步长为8
;这表示选择了每年的第1
、9
、17
天等等,作为处理的开始日期。接下来,我们创建了一个名为roi
的变量,它表示感兴趣区域的范围。
随后,我们创建了两个变量landsat_7
和landsat_8
,分别表示LANDSAT 7和LANDSAT 8的图像集合;通过filterDate
方法来筛选指定日期范围内的图像,并使用select
方法选择特定的波段,且使用map
方法对每个图像进行剪裁与重命名。这里之所以需要重命名,是因为接下来我们将使用merge
方法将2
个图像集合合并为1
个;而merge
方法需要保证待合并的2
个ImageCollection
具有相同的波段名称。
接下来,创建了一个名为filterAndClip
的函数,用于对Landsat影像进行过滤和剪裁,并返回过滤后图像的平均值。这个函数具体的功能如下——首先,其接受一个参数day
,表示处理的日期;随后,创建一个名为start
的变量,使用ee.Number
将day
转换为数字类型;同时创建一个名为end
的变量,使用start.add(7)
计算start
加上7的结果,表示8
天的时间段。接下来,使用calendarRange
方法对landsat
数据集进行过滤,根据start
和end
的日期范围,筛选出满足条件的影像;这里使用'day_of_year'
表示按照1
年中的天数进行筛选;创建一个名为filtered
的变量,将过滤后的影像集合赋值给它。接下来,通过.mean()
方法计算过滤后影像集合的平均值,创建一个名为filtered_mean
的变量来存储结果。最后,返回filtered_mean
,即过滤后影像集合的平均值。
接下来,使用for
循环遍历selectedDays
列表中的每1
个日期;在循环内部,使用filterAndClip
函数对指定日期的影像进行过滤和剪裁,得到过滤后的影像的平均值。同时,创建一个exportParams
对象,其中包含导出图像所需的参数,包括图像、描述、保存位置、像元分辨率、区域范围和最大像素数等。最后,使用Export.image.toDrive
方法将图像导出到Google Drive。
其中,我们可以将上述代码中所有Map.addLayer()
函数取消注释,并通过Inspector方法对地图数据加以查看。
首先对于Landsat 7 and 8
这个图层(也就是第1
个.addLayer()
函数),可以看到其为研究区域中的所有Landsat遥感影像,如下图所示。
其次对于Landsat
这个图层(也就是第2
个.addLayer()
函数),可以看到其为研究区域中,各年中所有落入当前8
天时间间隔内的Landsat遥感影像;如下图所示,这里就是每1
年中处于001
天至008
天的遥感影像。
而如下图所示,这里就是每1
年中处于073
天至081
天的遥感影像。
其次对于Landsat Mean
这个图层(也就是第3
个.addLayer()
函数),可以看到其为研究区域中,7
年里当前8
天时间间隔内的所有Landsat遥感影像的平均值;具体如上图与上上图所示。
执行上述代码,我们将在Tasks栏看到自动生成的遥感影像导出任务,其中各任务导出的遥感影像就以其所代表8
天时间间隔的开始日期为名称;如下图所示。
由于要导出的遥感影像文件比较多,即任务比较多;我们可以在GEE网页中,按下F12
按钮,选择“Console”,并将下方的代码复制到下图下方的紫色框内。
要复制的就是以下代码。
runTasks = function() {
const evt = new MouseEvent('click', {bubbles: true, cancelable: true, ctrlKey: true})
$$('.run-button' ,$$('ee-task-pane')[0].shadowRoot).forEach(function(e) {
e.dispatchEvent(evt)
})
}
runTasks()
复制完毕后,按下回车键,即可批量提交任务,无需手动提交了。
待任务都处理完毕后,我们进入Google Drive即可在指定文件夹下看到刚刚导出的结果图像。
至此,大功告成。