1

I created a code in Google Earth Engine to calculate monthly VCI. The official equation for VCI is the following:

VCI = 100*(NDVI - NDVImin)/(NDVImax - NDVImin)

My problem is that I don't know how to relate the placeholders (NDVI, NDVImin, NDVImax) to the right images and data from my image collection.

Because I have an Image Collection with 126 monthly NDVI Images And I have two Image Collections (one for max and one for min NDVI values) with 6 images. From April to September one Image per month. Now I have to calculate with the 6 images of the two extreme Image Collections to the monthly Image Collection.

It is difficult to explain but attached you can find my code. The problem should be in the almost last lines.

The GEE Code can be found here: https://code.earthengine.google.com/?scriptPath=users%2Fjohanneswilk%2Ftest%3ATest_13%20MODIS%20VCI%202


//preprocessing steps...


// ---------------------------------------------------------------------------------------------
///// MODIS Monthly NDVI Anomaly Calculation I /////


// Monatliche NDVI Kompisition erstellen von April bis September für jedes Jahr
// Create NDVI composite for every month
var monthlyNDVI =  ee.ImageCollection.fromImages(
  years.map(function (y) { 
    return months.map(function(m) {
      var monthly = ndviCollection
        .filter(ee.Filter.calendarRange(y, y, "year"))
        .filter(ee.Filter.calendarRange(m, m, "month"))
        .mean(); 
      return monthly
        .set("year", y) 
        .set("month", m) 
        .set("system:time_start", ee.Date.fromYMD(y, m, 1));}); })
  .flatten());
print (monthlyNDVI, 'monthly NDVI')





// Für jeden Monat werden die NDVI Maximal Werte ausgerechnet --> somit bekommen wir eine
// MAX Value Composition
// Calculate mean values for each month over all years
var MonthlyMAX =  ee.ImageCollection.fromImages(months
  .map(function (m) {
    var maxNDVI = monthlyNDVI
      .filter(ee.Filter.eq("month", m))
      .select("NDVI")
      .reduce(ee.Reducer.percentile({percentiles: [90]}))
      .rename("max_NDVI");
  return maxNDVI
    .set("month", m);})
  .flatten());
print (MonthlyMAX, 'MonthlyMAX');
Map.addLayer (MonthlyMAX.first().select('max_NDVI').clip(roi),  {min:0, max:1,  'palette': ['red','yellow', 'green']}, 'MonthlyMAX')

// Für jeden Monat werden die NDVI Minimal Werte ausgerechnet --> somit bekommen wir eine
// MIN Value Compisition
var MonthlyMIN =  ee.ImageCollection.fromImages(months
  .map(function (m) {
    var minNDVI = monthlyNDVI
      .filter(ee.Filter.eq("month", m))
      .select("NDVI")
      .reduce(ee.Reducer.percentile({percentiles: [10]}))
      .rename("min_NDVI");
  return minNDVI
    .set("month", m);})
  .flatten());
print (MonthlyMIN, 'MonthlyMIN');
Map.addLayer (MonthlyMIN.first().select('min_NDVI').clip(roi), {min:0, max:1,  'palette': ['red','yellow', 'green']}, 'MonthlyMIN')


//Create a list to calulate the Index for each image related to each month
var vci_list = [];

for(var j = startyear; j <=endyear; j++){
  for(var i = startmonth; i <=endmonth; i++) {
  

  var current_vci = 100 * (monthlyNDVI[j][i] - MonthlyMIN[i]) / (MonthlyMAX[i] - MonthlyMIN[i]);
 // var current_vci = 100 * ('NDVI'[j][i] - 'min_NDVI'[i]) / ('max_NDVI'[i] - 'min_NDVI'[i]);
    vci_list.push(current_vci); 
  }
}

print(vci_list);


1
  • I am looking to do the same code as you, Could you please share it again? Thanks
    – hugo p
    Commented Mar 27, 2023 at 9:52

1 Answer 1

0

You can try for loop as below. You can also rename band and select specific band to print.

var vci_list = [];
for(var j = startyear; j <=endyear; j++){
  for(var i = startmonth; i <=endmonth; i++) {
   var current = monthlyNDVI.filterMetadata('year','equals',j)
                            .filterMetadata('month','equals',i)
                            .mean().clip(roi);
    var min = MonthlyMIN.filterMetadata('month','equals',i).mean().clip(roi);
    var max = MonthlyMAX.filterMetadata('month','equals',i).mean().clip(roi);
    var current_vci = (current.subtract(min)).divide(max.subtract(min))
    });
    vci_list.push(current_vci);
  }
}
print(vci_list);

Hope it helps.

1
  • Thank you very much. It helps a lot. I have found a similar solution but not as short and efficient as yours. Commented May 9, 2021 at 11:57

Your Answer

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

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