迭代图像集合 Google Earth Engine

Iterate over Image Collection Google Earth Enigne

我编写了处理所有 Landsat 图像和计算 NDVI 的函数。但是,我有 59 个 GPS 点,我想要每个 GPS 点的 NDVI 时间序列输出。在 运行 我的代码之后,生成的 NDVI 值似乎不是每个点,而是每个图像的单个值。我猜是自动创建了某种边界框并用于计算,而不是使用 GPS 点。因此,我需要在所有 59 个点上迭代我的函数,并将输出保存到 table 中。

GPS 文件是 ESRI 点形状文件。

最好的方法是什么?

这是我的一些代码:

// import GPS locations from asset
GPS = GPS.geometry();

// Calculates the median NDVI and add value to image properties.
var meanNDVI = ndviLandsatCol.map(function(img) {
  var obs = img.reduceRegion({
    geometry: GPS,
    reducer: ee.Reducer.median(),
    scale: 30
  });
  return img.set('NDVI', obs.get('NDVI'));
});

ndviLandsatCol 变量是经过预处理的图像集合,其中添加了 NDVI 作为波段。 我对编码和 Google Earth Engine 还是个新手。有人可以建议如何在我所有的 GPS 点上迭代这个过程吗?我应该如何阅读GPS文件、字典?以及如何在不绘制点和下载随附文件的情况下将其保存到 .CSV 中。

如有任何帮助,我们将不胜感激。

如果您想要特征集合中每个点的图像值,您需要 reduceRegions,而不是 reduceRegion。这将 return 一个功能集合。类似于:

var allObs = ndviLandsatCol.map(function(img) {
  var obsAtTime = img.reduceRegions({
    collection: GPS,
    reducer: ee.Reducer.median(),
    scale: 30
  });
  return obsAtTime.map(function (feature) {
    return feature.copyProperties(img, ['system:time_start']);
  });
}).flatten();

请注意,您应该删除您拥有的行GPS = GPS.geometry();,因为这会丢弃要素集合的结构并将其变成一个几何图形。

这将为您提供一个平面 table suitable 用于导出到 CSV,但您必须自己将这些行分组到时间序列中。

如果您需要在 Earth Engine 中进一步处理时间序列,可以使用以下两种不同的方式对它们进行分组:

  1. 使用一个ee.Join.saveAll。这会让你得到一个 FeatureCollectionGPS 但有一个额外的 属性 其中包含时间序列中的 Features,并且每个特征都具有与来自 ndviLandsatCol.

    print(
      ee.Join.saveAll('series')  // 'series' is the name of the time series property.
        .apply(
          allObs.distinct('.geo').select([]),  // Determines properties of outer features (here, none but the geometry).
          allObs,
          ee.Filter.equals({leftField: '.geo', rightField: '.geo'})));
    
  2. 使用分组减速器。这将为您提供一个数字列表的字典列表,每个数字列表都是从原始 ndviLandsatCol 中明确选择的一个波段的时间序列。在我看来,这有点混乱,但可能会让您使用起来更简单。

    print(allObs.reduceColumns(
      ee.Reducer.toList().setOutputs(['NDVI'])
        .combine(ee.Reducer.toList().setOutputs(['time']))
        .group(0),
      [
        '.geo',               // select geometry for the group() operation
        'NDVI',               // first toList reducer
        'system:time_start',  // second toList reducer
      ]));
    

这是最终的解决方案:

// Collect GPS, image, NDVI triplets.
var triplets = NDVILandsatCol.map(function(image) {
  return image.select('NDVI').reduceRegions({
    collection: GPS.select(['Site_ID']), 
    reducer: ee.Reducer.mean(), 
    scale: 30
  }).filter(ee.Filter.neq('mean', null))
    .map(function(f) { 
      return f.set('imageId', image.id());
    });
}).flatten();
print(triplets.first());

// Format a table of triplets into a 2D table of rowId x colId.
var format = function(table, rowId, colId) {
  var rows = table.distinct(rowId);
  var joined = ee.Join.saveAll('matches').apply({
    primary: rows, 
    secondary: table, 
    condition: ee.Filter.equals({
      leftField: rowId, 
      rightField: rowId
    })
  });

  return joined.map(function(row) {
      var values = ee.List(row.get('matches'))
        .map(function(feature) {
          feature = ee.Feature(feature);
          return [feature.get(colId), feature.get('mean')];
        });
      return row.select([rowId]).set(ee.Dictionary(values.flatten()));
    });
};

// Export table
var table1 = format(triplets, 'imageId', 'Site_ID');
var desc1 = 'Table_demo'; 
Export.table.toDrive({
  collection: table1, 
  description: desc1, 
  fileNamePrefix: desc1,
  fileFormat: 'CSV'
});