想要批量下载逐月的NDVI数据,需要建立两个for循环依次筛选年份和月份;
本文以Landsat 8数据集为例,实现逐月下载归一化后的NDVI数据;
大致步骤是:数据集去云处理——筛选所需要的月份并根据研究区裁剪——剔除无效数据——水体掩膜、计算NDVI并归一化——批量下载。
下文是逐月批量下载归一化后的NDVI完整代码:
// 定义成自己的研究区
var roi = table;
// 在图层上显示
Map.addLayer(roi, {}, 'yanjiuqu');
// 定义去云函数,阈值设置为5
var Cloudmask = function(image){
var clouds = ee.Algorithms.Landsat.simpleCloudScore(image).select(['cloud'])
return image.updateMask(clouds.lt(5))
};
// 定义L8数据集并进行去云处理
var imagecol = ee.ImageCollection('LANDSAT/LC08/C02/T1_TOA')
.filterBounds(roi)
.filterDate('2013-04-08', '2022-12-31')
.filterMetadata('CLOUD_COVER', 'less_than', 50)
.sort('CLOUD_COVER', true)
.map(function(image){
return image.set('year', ee.Image(image).date().get('year')).set('month', ee.Image(image).date().get('month'));
}) // 在影像属性里添加‘年’和‘月’字段,方便后期筛选
.map(Cloudmask);
print('CloudRemoved_Images', imagecol);
//_______________________________________________________________________________________
// 数据准备
// 利用for循环筛选出想要的月份数据并裁剪
var imgList = ee.List([]);
for (var year = 2013; year < 2023; year++) {
for (var month = 1; month <= 12; month++) { // 默认为1-12月,可以更改为特定某一月份
var img = imagecol.filterMetadata('year', 'equals', year)
.filterMetadata('month', 'equals', month)
.mosaic()
.clip(roi);
var image = img.set('year', year).set('month', month); // 在列表里增添多个字段的方法,默认按照字段名首字母排序
var imgList = imgList.add(image);
}
}
print('Filtered_Images', imgList);
// 利用函数将无效波段剔除掉
var validImgs = ee.ImageCollection(imgList)
.map(function(image) {
var bands = image.bandNames();
var hasBands = bands.size().gt(0);
return ee.Algorithms.If(hasBands, image, null);
},true);
print('Valid_Images', validImgs);
//_______________________________________________________________________________________
// 数据处理
// 定义水体掩膜函数
function waterMask(image) {
var ndwi = image.normalizedDifference(['B3', 'B5'])
var mask = ndwi.lt(0.1)
return image.updateMask(mask)
}
// 定义计算NDVI函数并保留年份和月份字段
function addTimeAndNDVI(image) {
var year = image.get('year');
var month = image.get('month');
var ndvi = image.normalizedDifference(['B5', 'B4']).rename('NDVI');
return ndvi.set('year', year).set('month', month);
}
// 定义归一化函数
function getNorm(image) {
var minMax = image.reduceRegion({
reducer: ee.Reducer.minMax(),
geometry: roi,
scale: 30,
crs: 'EPSG:4326',
bestEffort: true,
maxPixels: 1e13
});
var year = image.get('year');
var month = image.get('month');
var yearmonth = ee.String(year).cat('-').cat(ee.String(month));
var normalize = ee.ImageCollection.fromImages(
image.bandNames().map(function(name){
name = ee.String(name);
var band = image.select(name);
return band.unitScale(ee.Number(minMax.get(name.cat('_min'))), ee.Number(minMax.get(name.cat('_max'))));
})
).toBands().rename('Normed_NDVI').set('yearmonth', yearmonth);
return normalize;
}
// 计算归一化后的NDVI
var NormedNDVI_Imgs = ee.ImageCollection(validImgs)
.map(waterMask)
.map(addTimeAndNDVI)
.map(getNorm);
print('Normed_NDVI_Images', NormedNDVI_Imgs);
//_______________________________________________________________________________________
// 数据导出
// 定义批量下载函数
function exportImage(image, fileName) {
Export.image.toDrive({
image: image,
description: 'Image_' + fileName,
folder: 'GEE_export',
region: roi,
scale: 30,
crs: 'EPSG:4326',
maxPixels: 1e13 //最大像元素
});
}
// 生成列表,迭代下载
var indexList = NormedNDVI_Imgs.reduceColumns(ee.Reducer.toList(), ['system:index']).get('list');
indexList.evaluate(function(indexs) {
for (var i = 0; i < indexs.length; i++) {
var image = ee.Image(NormedNDVI_Imgs.filter(ee.Filter.eq('system:index', indexs[i])).first());
var name = parseInt(indexs[i]);
exportImage(image, name);
}
});
在以上代码中,批量下载代码参考了小郭学地信博主的代码,导出文件名以列表的索引号命名。
代码实现结果:
运行后的任务框试图如下:
很遗憾的是,由于本人菜鸡,实验了多种批量导出代码,最终未能实现以影像时间命名的方案,需要查对影像日期的话,可以去console对话框查看打印属性如下图:
欢迎有能力的大佬去解决导出时以文件日期命名的问题。
批量导出:
为了能让影像批量RUN,这里借鉴了一位博主的批量RUN代码http://t.csdn.cn/YBybz,代码如下:
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()
运行出现RUN图标后,按F12,点击console对话框,复制粘贴进去即可批量导出到指定位置。
批量导出的结果如下图:
影像展示:
导出到云盘后即可下载到本地,如下图:
用打开Image_65 影像(影像时间2018年6月),如下图:
对其进行统计计算,结果如下:
可以看到,影像的NDVI结果是归一化到了0 ~ 1之间!
注:由于云量等原因,可能会导致某些影像在区域内显示不完全!