GEE:批量下载每日数据集

遇到最大的困难就是GEE的客户端和服务端的数据处理问题,不过好在解决了。

我的问题是如何在GEE平台下载每天的哨兵5号(Sentinel-5P)的臭氧影像?

代码链接(挂):https://code.earthengine.google.com/86171ff00fd095da3f0da02e5872ecd6

01 代码说明

首先,自定义参数。

// 自定义参数
var start_time = '2022-07-01'
var end_time = '2022-08-31'
var province_name = '四川省'

接着,研究区选取。

//加载自己的研究区
var roi = ee.FeatureCollection("projects/ee-chaoqiezione/assets/china_admin_province");
roi = roi.filter(ee.Filter.eq('省', province_name)).first();

需要说明的,你需要将"projects/ee-chaoqiezione/assets/china_admin_province"替换为自己的云盘Assets中的矢量文件路径或者GEE平台上的矢量文件,并针对其修改province_name.

接着,生成start_time到end_time之间每一天日期的列表。

// 生成日期列表
var dates = ee.List.sequence(
  ee.Date(start_time).millis(),   // 将开始日期转化为毫秒级的unix时间戳(1970年至start_time毫秒数)
  ee.Date(end_time).millis(),   // 如此亦是
  24*60*60*1000  // 一天的毫秒数
).map(function(dateMillis){
  return ee.Date(dateMillis).format('YYYY-MM-dd')  // 将unix时间戳转化为年月日的字符串
})

这里是非常重要的内容,且代码不可随意更改,说明如下:
1. 对于字符串日期转化为Date对象是为了方便后续列表的生成,因为字符串不具备这些方法或者函数;

2. 将起始和结束日期转化为unix时间戳,我感觉这个和ENVI IDL的儒略日十分相似,大家可以参考;

3. 步长设置为一天的毫秒时间数;

4. 将然后将生成的起始日期到结束日期的每天的unix时间戳转化为正常的date对象,然后将date对象转化为字符串。

这里最大的疑惑就是为什么需要将处理好的date对象转化为字符串?

实际上与后面的客户端和服务端的一些东西相关,后面我们再说明,主要原因是循环不是在服务端并行运算的,而是在客户端进行的。

接着, 迭代时间==>处理并导出影像;

// 迭代时间 ==> 处理和导出影像
dates.evaluate(function(dates) {
  dates.map(function(date){
    var start = ee.Date(date);
    var stop = start.advance(1, 'day');

    var scol= ee.ImageCollection("COPERNICUS/S5P/NRTI/L3_O3")
              .filterBounds(roi)
              .filterDate(start,stop)
              .select("O3_column_number_density");
    
    var before = scol.qualityMosaic("O3_column_number_density").clip(roi);
    before = before.set({name:ee.String(start.format('YYYY-MM-dd'))});
    
    Export.image.toDrive({
      image: before.select("O3_column_number_density"),
      region: roi.geometry(),
      scale:1000,
      description: "O3_column_number_density_1000m_" + province_name + "_" + date,
      folder: 'O3_column_number_density',
    });
  })
})

我们使用了evaluate函数,evaluate() 方法允许你在客户端执行代码,这有别于大部分 Earth Engine 方法,它们是在服务器端执行。关键是理解 Earth Engine 的计算模型是延迟的,并行的,并且在服务器端执行的。

如果尝试使用map解决以上内容,即不使用evaluate函数,那么导出存在问题,因为GEE使用map函数是在服务端并行运算的,,但是GEE限制一次只能发送最多三次导出任务,这就是为什么在map中尝试导出多个任务时,实际上只有三幅影像被导出。

evaluate实际上就是异步操作,当你要使用某函数去执行dates中的某些变量时,然而这些变量还在服务端进行并行运算还没有处理好,如果我们使用了evaluate,那么一旦变量被处理好,那么该函数就会去执行这些变量,异步就在于当变量还没有处理好时,程序不会一直等待,而是继续执行其它代码,然后一边等待变量处理好。

 至于其它细节这里由于时间不再一一阐述,记住一点即可。

当你想要在map函数里面使用print、toDrive等方法,那么外嵌一个evaluate是一个不错的选择,尤其是当你需要在服务器端完成复杂的计算并获取结果时。

由于单纯地使用map速度很快,这是因为它是并行执行任务,所以当你使用evaluate方法时程序运行速度会稍稍减慢。

完整代码如下:
(又稍微做了修改,自行查看区别)

// 自定义参数
var start_time = '2022-07-01'
var end_time = '2022-08-31'
var province_name = '四川省'


//加载自己的研究区
var roi = ee.FeatureCollection("projects/ee-chaoqiezione/assets/china_admin_province");
roi = roi.filter(ee.Filter.eq('省', province_name));
print('行政区划', roi)
// 生成日期列表
var dates = ee.List.sequence(
  ee.Date(start_time).millis(),   // 将开始日期转化为毫秒级的unix时间戳(1970年至start_time毫秒数)
  ee.Date(end_time).millis(),   // 如此亦是
  24*60*60*1000  // 一天的毫秒数
).map(function(dateMillis){
  return ee.Date(dateMillis).format('YYYY-MM-dd')  // 将unix时间戳转化为年月日的字符串
})
Map.addLayer(roi.style({fillColor: "00000000"}), {width: 2}, province_name)
Map.centerObject(roi, 6)
// 迭代时间 ==> 处理和导出影像
dates.evaluate(function(dates) {
  dates.map(function(date){
    var start = ee.Date(date);
    var stop = start.advance(1, 'day');

    var scol= ee.ImageCollection("COPERNICUS/S5P/NRTI/L3_O3")
              .filterBounds(roi)
              .filterDate(start,stop)
              .select("O3_column_number_density");
    
    var before = scol.qualityMosaic("O3_column_number_density").clip(roi).unmask(-9999);
    before = before.set({name:ee.String(start.format('YYYY-MM-dd'))});
    
    print(before)
    Export.image.toDrive({
      image: before.select("O3_column_number_density"),
      region: roi.geometry(),
      scale:1000,
      description: "O3_column_number_density_1000m_" + province_name + "_" + date,
      folder: 'O3_column_number_density',
    });
  })
})

猜你喜欢

转载自blog.csdn.net/m0_63001937/article/details/131019052