GEE Training:qualityMosaic和max的区别 | iterate迭代(3)

① var median = collection.reduce(ee.Reducer.median());

② var median = collection.median();

这两个表达完全一致,只是写法不同,最后得到的都是一张image。reducing:在collection的所有数据中逐像元地进行统计并归纳到一张单图层的图像上。

注意:通过reduce imagecolletion产生的composite image可以根据指定投影产生各种pixel,所以它本身是没有投影的。相反composites的默认投影是WGS-84,分辨率1°

compositing and mosaicking:

 Landsat8影像去云代码:建议直接用.

// Define a function that scales and masks Landsat 8 surface reflectance images.
function prepSrL8(image) {
  // Develop masks for unwanted pixels (fill, cloud, cloud shadow).
  var qaMask = image.select('QA_PIXEL').bitwiseAnd(parseInt('11111', 2)).eq(0);
  var saturationMask = image.select('QA_RADSAT').eq(0);

  // Apply the scaling factors to the appropriate bands.
  var getFactorImg = function(factorNames) {
    var factorList = image.toDictionary().select(factorNames).values();
    return ee.Image.constant(factorList);
  };
  var scaleImg = getFactorImg([
    'REFLECTANCE_MULT_BAND_.|TEMPERATURE_MULT_BAND_ST_B10']);
  var offsetImg = getFactorImg([
    'REFLECTANCE_ADD_BAND_.|TEMPERATURE_ADD_BAND_ST_B10']);
  var scaled = image.select('SR_B.|ST_B10').multiply(scaleImg).add(offsetImg);

  // Replace original bands with scaled bands and apply masks.
  return image.addBands(scaled, null, true)
    .updateMask(qaMask).updateMask(saturationMask);
}

qualityMosaic和max的区别:

GEE学习笔记 五十九:GEE中mosiac、qualityMosiac、max区别_qualitymosaic_无形的风(知乎)的博客-CSDN博客

二者都是对imagecollection操作,max后是变成image(每个pixel上看一遍 取最大值),是默认选第一个波段 / 指定一个波段的信息。qualityMosaic不是取最大值,它返回的是最大值对应的原始数据。

比如, 一个collection有7个波段,max是各波段都算了max;但后者按ndvi值排序的话,结果是最绿像元所对应时刻的地表反射率的值(只是用ndvi做一个索引)。如果是单波段数据 / colletion中只有一张影像,区别不大。

应用场景:计算全中国ndvi最大值出现的时间 (https://code.earthengine.google.com/a30f907a809a2e6abb2d631ad5ab2f60?noload=1)。collection要有时间戳,把时间放在波段上,再对NDVI进行qualityMosaic,就得到doy了。如果对时间排序则是最新的。官网的例子(https://developers.google.com/earth-engine/guides/ic_composite_mosaic)是NDVI最大值(最绿)像元的合成以及最新时间的合成。

【董老师 直观比较二者的区别】https://code.earthengine.google.com/bc3208123a98779e1326830fe8bc4aaf

比如在这个代码中,结果有显著差异,因为max后, 是在img的每个像元上三个波段都是最大。


iterate:累加(类似for循环)。

GEE 学习笔记 9:for,while,map,evaluate,iterate的异同 - 知乎

👆 利用 landsat8,用map / iterate的方法计算 2013-2020 年武汉市年平均 NDVI 值, 并导出 GIF.

其中, 这段代码也可以学习一下: ​导入自己的数据(矢量), 筛选出某个geometry. 

var roi = ee.FeatureCollection("users/comingboy1118/China/CH_shi");

var roi = roi.filter(ee.Filter.eq("市","武汉市")).geometry()
Map.addLayer(roi,{"color":'red',},"roi")
Map.centerObject(roi, 8)

① nanshan分区的代码

选了10个候选特征,缓冲区,设置时间、算指数、去云。得到原始数据集,是1564个elements。

中值合成:advances其实就是0、60、120的list,从0-60、60-120、120-180进行map对这三个间隔中值合成。结果seasonalS2就是合成后的,是包含3张images(doy分别是109、169、229)的List。

那么接着,seasonals是对seasonalS2(list)进行iterate操作。其中,mergeBands是个function,后面的image[]则是个空的初始值。结果是有30个波段的image(3×10)。

【总结:每加一个新数要把原来的和(赋初始值0)也加上,再迭代,出来一个新数就加一个。

上面代码中,element是新数,previous是前面的和,按照顺序处理每一个,直到下一个。】

② 官方代码: 计算EVI的累加值。

计算了EVI的2011-2014年每景影像 减去 十年EVI均值的结果,增加了时间戳属性,称之为“EVI anomaly”, 然后累加这个anomaly (即series).   

“ 对 iterate ()的每次调用都会将anomaly添加到正在运行的sum中,并将结果添加到list中。最后的结果传递给 ImageCollection 构造函数,以获得一个新的image序列。”

// Load MODIS EVI imagery.
var collection = ee.ImageCollection('MODIS/006/MYD13A1').select('EVI');

// Define reference conditions from the first 10 years of data.
var reference = collection.filterDate('2001-01-01', '2010-12-31')
  // Sort chronologically in descending order.
  .sort('system:time_start', false);

// Compute the mean of the first 10 years.
var mean = reference.mean();

// Compute anomalies by subtracting the 2001-2010 mean from each image in a
// collection of 2011-2014 images. Copy the date metadata over to the
// computed anomaly images in the new collection.
var series = collection.filterDate('2011-01-01', '2014-12-31').map(function(image) {
    return image.subtract(mean).set('system:time_start', image.get('system:time_start'));
});

// Display cumulative anomalies.
Map.setCenter(-100.811, 40.2, 5);
Map.addLayer(series.sum(),
    {min: -60000, max: 60000, palette: ['FF0000', '000000', '00FF00']}, 'EVI anomaly');

累加函数是accumulate. 累加方式: 在原来list的基础上, 再加上当前image的值. 

再下一段cumulative是应用iterate, 里面是accumulate函数, 以及first初始值(空的EVI). 

具体来看, 主要是累加的函数: 当前的image加上previous的和. 从first开始迭代. 另外, 他是把list作为初始的迭代, 所以后面还要把list转为imagecollection. 

// Get the timestamp from the most recent image in the reference collection.
var time0 = reference.first().get('system:time_start');

// Use imageCollection.iterate() to make a collection of cumulative anomaly over time.
// The initial value for iterate() is a list of anomaly images already processed.
// The first anomaly image in the list is just 0, with the time0 timestamp.
var first = ee.List([
  // Rename the first band 'EVI'.
  ee.Image(0).set('system:time_start', time0).select([0], ['EVI'])
]);

// This is a function to pass to Iterate().
// As anomaly images are computed, add them to the list.
var accumulate = function(image, list) {
  // Get the latest cumulative anomaly image from the end of the list with
  // get(-1).  Since the type of the list argument to the function is unknown,
  // it needs to be cast to a List.  Since the return type of get() is unknown,
  // cast it to Image.
  var previous = ee.Image(ee.List(list).get(-1));
  // Add the current anomaly to make a new cumulative anomaly image.
  var added = image.add(previous)
    // Propagate metadata to the new image.
    .set('system:time_start', image.get('system:time_start'));
  // Return the list with the cumulative anomaly inserted.
  return ee.List(list).add(added);
};

// Create an ImageCollection of cumulative anomaly images by iterating.
// Since the return type of iterate is unknown, it needs to be cast to a List.
var cumulative = ee.ImageCollection(ee.List(series.iterate(accumulate, first)));

// Predefine the chart titles.
var title = {
  title: 'Cumulative EVI anomaly over time',
  hAxis: {title: 'Time'},
  vAxis: {title: 'Cumulative EVI anomaly'},
};

// Chart some interesting locations.
var pt1 = ee.Geometry.Point(-65.544, -4.894);
print('Amazon rainforest:',
    ui.Chart.image.series(
      cumulative, pt1, ee.Reducer.first(), 500).setOptions(title));

var pt2 = ee.Geometry.Point(116.4647, 40.1054);
print('Beijing urbanization:',
    ui.Chart.image.series(
      cumulative, pt2, ee.Reducer.first(), 500).setOptions(title));

var pt3 = ee.Geometry.Point(-110.3412, 34.1982);
print('Arizona forest disturbance and recovery:',
    ui.Chart.image.series(
      cumulative, pt3, ee.Reducer.first(), 500).setOptions(title));

上图是anomaly的多年值,但我们常用累加的anomaly, 因此要用到iterate.

[师兄提问: 为什么要用list作为空的first]: first必须是个list. 因为series是个collection, 它迭代时输出的是list, 所以初始的必须也是list.  可以理解为只能在list或者collection上迭代.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值