[GIS] Calculating EVI in Sentinel 2-2A

evigoogle-earth-enginesentinel

I am trying to calculate EVI for a Sentinel 2 Level 2A image collection. I have applied the Sentinel cloud mask provided by GEE but am not sure I am applying EVI correctly because my range is not between -1 and 1 and when I try to visualize it is a single color.

This is what I see when I inspect the bands using the Console.

"EVI", double, EPSG:32616, 10980×10980 px

My question is if I am already dividing by the scale factor (10000) in the cloud mask do I still need to divide each band by 10000 in my EVI equation? Any insight into why the EVI I'm producing is not usable?

//Area of interest
  var roi = /* color: #d63000 */ee.Geometry.Polygon(
        [[[-89.88191416015627, 14.139636998051515],
          [-90.32686044921877, 13.737115730837438],
          [-89.87916757812502, 13.526248029454758],
          [-89.60176279296877, 13.982444096452182]]]);
/**
 * Function to mask clouds using the Sentinel-2 QA band
 * @param {ee.Image} image Sentinel-2 image
 * @return {ee.Image} cloud masked Sentinel-2 image
 */
function maskS2clouds(image) {
  var qa = image.select('QA60');

          
  // Bits 10 and 11 are clouds and cirrus, respectively.
  var cloudBitMask = 1 << 10;
  var cirrusBitMask = 1 << 11;
  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
      .and(qa.bitwiseAnd(cirrusBitMask).eq(0));

  return image.updateMask(mask).divide(10000);
}

// Add EVI using an expression.
var addEVI=function(image){
var EVI = image.expression(
      '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', {
      'NIR' : image.select('B8').divide(10000),
      'RED' : image.select('B4').divide(10000),
      'BLUE': image.select('B2').divide(10000)}).rename('EVI');
      return image.addBands(EVI);
};

var Nov19= ee.ImageCollection('COPERNICUS/S2_SR')
            .filterBounds(roi)
                  .filterDate('2019-11-01', '2019-11-30')
                  // Pre-filter to get less cloudy granules.
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE',10))
                  .map(addEVI)
                  .map(maskS2clouds);
                  
                  
print(Nov19);

Map.addLayer(Nov19.select('EVI').median().clip(roi), {min:-1,max:1,palette:['red', 'green']}, 'EVI Nov19');

Best Answer

Because you map maskS2clouds onto your image collection after addEVI, you end up dividing your EVI band by 10000. Decide whether you want to re-scale your images earlier in your script or on a case-by-case basis (e.g. when calculating EVI).