Вычислите NDVI для региона, месяца и года с помощью Google Earth Engine? - PullRequest
0 голосов
/ 13 ноября 2018

Я хочу рассчитать среднее значение NDVI для региона (уровень администратора 3, также называемый woreda), месяц и год. Поэтому мой конечный результат будет выглядеть примерно так:

regions    year    month   NDVI   
---------------------------------
region_1     2010       1     0.5  
region_1     2010       2    -0.6  
region_1     2010       3     0.7  
region_1     2010       4    -0.3  
region_1     2010       5     0.4  
region_1     2010       6    -0.5  
region_1     2010       7     0.5  
region_1     2010       8    -0.7  
region_1     2010       9     0.8  
region_1     2010       10   -0.55  
region_1     2010       11   -0.3  
region_1     2010       12   -0.2  
region_2     2010       1     0.5  
region_2     2010       2    -0.6  
region_2     2010       3     0.7  
region_2     2010       4    -0.3  
region_2     2010       5     0.4  
region_2     2010       6    -0.5  
region_2     2010       7     0.5  
region_2     2010       8    -0.7  
region_2     2010       9     0.8  
region_2     2010       10   -0.55  
region_2     2010       11   -0.3  
region_2     2010       12   -0.2  
...          ...       ...    ...

Мой код в основном делает это для заданной области в var modisNDVI. Однако я хочу, чтобы мой код мог делать это с 2010 по 2015 год, для каждого месяца для каждого региона.

Как я могу сделать это, не записывая больше для циклов (итерации по годам и месяцам)?

Должен ли я использовать reduRegion или .map (), чтобы пропустить (все) циклы for?

Я предпринял попытку использовать reduRegion s , но не смог применить это к коллекции изображений.

// import data
var region = ee.FeatureCollection("ft:1zRUOJL1LYCPJj-mjP6ZRx8sxYKNH8EwDw3EPP66K"),
modisNDVI = ee.ImageCollection("MODIS/MCD43A4_006_NDVI");

// Get NDVI 
var modisNDVI = ee.ImageCollection(modisNDVI.filterDate('2015-01-01', '2015-06-01'));
var woredaNames = region.aggregate_array("HRpcode")

// do something so I can get monthly data for each year (2010-2015) for earch woreda (690)
// I don't want to write another for loop for the year and month what is a more optimized way?

// Processing all the 690 takes long, for this example I've used 10 woreda's
for (var woreda=0; woreda < 10 ;woreda++){

    // Focus on one region:
    var focusRegion = region.filter(ee.Filter.eq('system:index', String(woreda)));

    // Clip modis image on focused region:
    var focus_NDVI_clip = modisNDVI.mean().clip(focusRegion);

    // aggregate mean over geometry from focused region:
    var mean_dict = focus_NDVI_clip.reduceRegion({
    reducer: ee.Reducer.mean(),
    geometry: focusRegion.geometry(),
    scale: 500,
    });

    // Append index to mean_dictionary and print it (eventually this should turn into a list):
    var woreda_code = ee.List(woredaNames).get(woreda);
    mean_dict = mean_dict.set('Woreda_code', ee.String(woreda_code));
    print(mean_dict);}

1 Ответ

0 голосов
/ 05 декабря 2018

Прежде всего, вам следует избегать использования циклов for на Earth Engine любой ценой, он просто тормозит систему и не подходит для всех (см. Раздел «Циклы» на этой странице ).Вы можете использовать вложенное отображение , чтобы циклически перебирать коллекцию объектов, а затем все периоды времени для извлечения необходимой вам информации:

// import data
var region = ee.FeatureCollection("ft:1zRUOJL1LYCPJj-mjP6ZRx8sxYKNH8EwDw3EPP66K"),
modisNDVI = ee.ImageCollection("MODIS/MCD43A4_006_NDVI");

var startDate = ee.Date('2010-01-01'); // set analysis start time
var endDate = ee.Date('2010-12-31'); // set analysis end time

// calculate the number of months to process
var nMonths = ee.Number(endDate.difference(startDate,'month')).round();

var result = region.map(function(feature){
  // map over each month
  var timeDict = ee.List.sequence(0,nMonths).map(function (n){
    // calculate the offset from startDate
    var ini = startDate.advance(n,'month');
    // advance just one month
    var end = ini.advance(1,'month');
    // filter and reduce
    var data = modisNDVI.filterDate(ini,end).mean().reduceRegion({
      reducer: ee.Reducer.mean(),
      geometry: feature.geometry(),
      scale: 1000
    });
    // return zonal mean with a time key
    return data.combine(ee.Dictionary({'time':ini}));
  });
  // return feature with a timeseries property and results
  return feature.set('timeseries',timeDict);
});

// print to see if it is doing what we expect...
print(result.select(["HRpcode",'timeseries']));

// Export the data to a table for further analysis
Export.table.toDrive({
  collection:result,
  description:"tester",
  fileFormat:"CSV",
  selectors:["HRpcode","timeseries"]
})

Ссылка на код: https://code.earthengine.google.com/abf5eeb5c203310c11bf45c6714ae731

Форматирование результатов может быть немного странным в этой реализации, в результате получается коллекция объектов со словарями в качестве свойств, а не массив или таблица ... но, надеюсь, это либо даст вам то, что вам нужно, либо даст вам возможностьполучите то, что вам нужно.

...