4

I have written a code that is taking data from MODIS about NDVI, filter for March only , calculates the mean value for the whole month and clip it with geometry. The NDVI data is for period of years, for example, from 2000-2003.

The problem is that I need to run this process for few periods, 2000-2003, 2004-2007 and more and I dont want to use copy paste. So I want to create a loop but I'm coming from python and the exmples I have seen here in this forum confused me a little because I dont understand what the loop contains.

If someone can explain me the logic or how to put it inside a loop it will be very helpful.

This is the code I have worked on untill now:

var dataset = ee.ImageCollection('MODIS/006/MOD13A1')
.filter(ee.Filter.date('2000-03-01', '2003-03-31'))
.select('NDVI');

// filter the image collection to contain only images from March

var onlyMarch = dataset.filter(ee.Filter.calendarRange(3, 3,'month'));
print(onlyMarch);
// make a composite (mean image) of the images of March and clip to the geometry

var meanImage = onlyMarch.mean().clip(table).divide(10000);
print(meanImage);

var mean20002003 = meanImage.reduceRegion({
  reducer: ee.Reducer.mean(),
  geometry: table,
  scale:500
});

//var ndvi = dataset.select('NDVI')
var ndviParams = {min: 0, max: 1, palette: [
    'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901',
    '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01',
    '012E01', '011D01', '011301'
  ]};

Map.centerObject(table, 7);
Map.addLayer(meanImage,ndviParams,'NDVI20002003');
print(mean20002003,'mean NDVI 2000-2003')

1 Answer 1

3

First, you should make a list of dates to map over:

// settings for the years to filter on
var interval = 3;
var increment = 'year';
var start = '2000-01-01';
// make a list of start years
var startDate = ee.Date(start);
var secondDate = startDate.advance(interval, increment).millis();
var increase = secondDate.subtract(startDate.millis());
var list = ee.List.sequence(startDate.millis(), ee.Date('2020-01-01').millis(), increase);

Then you can map over that list and filter the image collection on the date range of 3 year. Note that I filtered the images on beforehand on March, as you did in your example:

// make a composite (mean image) of the images of March and clip to the geometry
var composites = ee.ImageCollection.fromImages(list.map(function(startYear){
  var filtCol = onlyMarch.filterDate(ee.Date(startYear), ee.Date(startYear).advance(interval, increment));
  var meanImage = filtCol.mean().clip(table).divide(10000);
  // add the mean to every image
  var meanVal = meanImage.reduceRegion({
    reducer: ee.Reducer.mean(),
    geometry: table,
    scale: 500
  });
  return ee.Image(meanImage.setMulti(meanVal)).set('system:time_start', ee.Date(startYear).millis());
}));

link code

3
  • Thank you for your answer, there is some things that are still not clear to me in the code you wrote: how the function millis() works here? I read it relates to minutes and seconds, why do we need it here? and in the variable "filtCol" there was an error, I changed the variable onlyMarch to composites but it had error.
    – ReutKeller
    May 7, 2019 at 16:30
  • I converted the ee.Date() to milliseconds from the 1st of January 1970. That returns a ee.Number() which enables to make the argument 'step' in ee.List.sequence() as a number (it does not accept an ee.Date() as input)
    – Kuik
    May 7, 2019 at 16:43
  • 1
    Hi @Kuik, thank you for your answer! It appears the link to your code is no longer active; when I click on it, it brings me to an empty code space. Does the code still exist?
    – Beck
    May 13, 2022 at 19:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.