谷歌地球引擎GEE将多个遥感影像作为多个波段合并成一张图像并下载的方法

  本文介绍在谷歌地球引擎(Google Earth Engine,GEE)中,下载多年的逐日ERA5土壤湿度数据,并在下载时,将每年同月份内的每一天的图像作为一个波段加以合并的方法。

  在之前的文章GEE谷歌地球引擎批量下载逐日ERA5气象数据的方法(https://blog.csdn.net/zhebushibiaoshifu/article/details/148050136)中,提到了在GEE中下载每一天ERA5土壤湿度数据的方法。但是,如果我们要下载的时间跨度比较大,那么要生成、运行的任务数量,以及要下载的遥感影像文件数量,就会非常多——比如假设要下载10年的数据,那相当于就要提交3650(左右,因为还有闰年)个任务,然后再批量运行任务,从而下载这大约3650个遥感影像文件。这样就很容易出现任务丢失、文件下载不全的问题,甚至还有可能因为短时间提交大量任务,导致自己的GEE账号被制裁。

  所以,本文希望在实现上述需求的同时,减少提交任务的数量——将每一年的同一个月份内的所有数据,都整合成一张图像;其中这个月内每一天的数据,都是这一张图像中的一个波段。例如,202001月的图像,就会有31个波段,每一个波段分别表示0101日、02日、03日,一直到31日的数据,以此类推。

  当然,和本文需求类似的场景,比如下载其他时间分辨率、或下载其他遥感数据等,都可以参考本文代码。

  本文所用代码如下。

/*jshint loopfunc:true */

var ERA5 = ee.ImageCollection('ECMWF/ERA5_LAND/DAILY_AGGR').select(['volumetric_soil_water_layer_1']);
var region = ee.Geometry.Polygon([[[180, 90], [-180, 90], [-180, -90], [180, -90]]], null, false);
var startYear = 2020;
var endYear = 2021;

for (var year = startYear; year <= endYear; year++) {
  for (var month = 1; month <= 12; month++) {
    var startDate = ee.Date.fromYMD(year, month, 1);
    var endDate = startDate.advance(1, 'month');
    var monthlyImages = [];
    
    var dailyImages = ERA5.filter(ee.Filter.date(startDate, endDate));
    // print(dailyImages);
    
    var dailyImagesList = dailyImages.toList(dailyImages.size());
    for (var i = 0; i < dailyImagesList.size().getInfo(); i++) {
      var dailyImage = ee.Image(dailyImagesList.get(i));
      var date = ee.Date(dailyImage.get('system:time_start'));
      var formattedDate = date.format('YYYYMMdd');
      monthlyImages.push(dailyImage.rename(formattedDate));
    }
    
    var multiBandImage = ee.Image.cat(monthlyImages);
    // print(multiBandImage);
    
    Export.image.toDrive({
      image: multiBandImage,
      description: 'ERA5_Soil_Moisture_' + startDate.format('YYYY_MM').getInfo(),
      folder: 'ERA5_Monthly',
      scale: 55659.7,
      region: region,
      maxPixels: 1e13
    });
  }
}

  代码整体的思路也比较简单。

  首先,我们定义数据集与研究区域,这个在本文开头提及的那篇文章中已经介绍过了,所以这里就不赘述。

  接下来,设置时间范围,通过startYearendYear变量设定需要下载的时间范围——这里需要注意,年份不要设置的跨度太大了,否则会非常卡,建议每次运行代码就选择3年左右的跨度即可。

  随后,循环遍历每个年份和月份。其中,外层循环遍历年份,内层循环遍历月份。对于每一个月份,首先确定该月的第一天作为startDate,并计算下个月的第一天作为endDate

  紧接着,获取并处理每日影像。使用filter方法基于日期过滤出每月的每日影像,并将每日影像列表化,然后遍历这个列表,对每张影像进行重命名(以影像的日期格式命名),并将它们添加到monthlyImages数组中。不过这里需要提一句,在此我们是给每一日的数据重命名的,换句话说也就是给后续下载的遥感影像文件中的每一个波段重命名——而GEE中导出的这个波段名称,是无法直接在ArcGIS或者ENVI等软件中看到的;但基于GDAL用代码读取栅格文件的属性,或者据说用QGIS打开图像文件,则是可以看到这个波段名称的属性的。

  最后,即可生成多波段影像并导出。首先,使用ee.Image.cat方法将当前年份与月份的每日影像合并成一个包含多个波段的影像,每个波段对应一天的数据;使用Export.image.toDrive方法将这个多波段影像导出至Google Drive中的ERA5_Monthly文件夹内,导出时设置像素大小scale、研究区域region和最大像素数量maxPixels等参数。

  执行上述代码,还是同样的,即可在GEE右侧的Tasks一栏中看到自己的导出任务。可以看到,导出时每一个月份就是一个任务,如下图所示;点击RUN即可运行任务,下载的图像也是一个月份一个图像文件

  如果要下载的数据比较多,手动一个一个点击RUN比较麻烦,可参考文章Google Earth Engine谷歌地球引擎计算遥感影像在每个8天间隔内的多年平均值(https://fkxxgis.blog.csdn.net/article/details/138588432)中提到的批量点RUN方法来运行任务。

  至此,大功告成。

欢迎关注:疯狂学习GIS

在Google Earth Engine (GEE) 中,如果你拥有多个单独的单波段影像集合,你可以通过创建一个包含每个影像集合中相同空间坐标和时间戳的元数据数组(metadata array),然后使用 `ee.ImageCollection.concatenate()` 或 `ee.ImageCollection.merge()` 函数来合并它们,形一个多波段影像集。 例如,假设你有三个单波段影像集合,分别是 `imageCollectionA`, `imageCollectionB`, 和 `imageCollectionC`,每张图像是一个单独的波段。首先,你需要确保这三个集合在空间和时间上是配对的,然后可以这样做: ```javascript // 获取每个集合的第一个图像作为参考,获取其几何和时间信息 var firstImageA = imageCollectionA.first(); var firstImageB = imageCollectionB.first(); var firstImageC = imageCollectionC.first(); // 创建一个数组,包括三个集合的元数据 var metadataArray = ee.List.repeat([firstImageA.geometry(), firstImageA.date(), 'collection_name'], 3).cat( ee.List.repeat([firstImageB.geometry(), firstImageB.date(), 'collection_name'], 3) ).cat(ee.List.repeat([firstImageC.geometry(), firstImageC.date(), 'collection_name'], 3)); // 使用metadata数组合并影像 var multiBandImageCollection = ee.ImageCollection.fromImages(metadataArray.map(function(metadata) { var collectionName = metadata.get(2); switch (collectionName) { case 'imageCollectionA': return imageCollectionA.get(metadata.get(0), metadata.get(1)); case 'imageCollectionB': return imageCollectionB.get(metadata.get(0), metadata.get(1)); case 'imageCollectionC': return imageCollectionC.get(metadata.get(0), metadata.get(1)); default: throw new Error('Invalid collection name'); } })); ``` 这将返回一个新的多波段影像集合,其中每一行是一个包含来自不同来源的单波段影像的组合。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯狂学习GIS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值