1

I am trying to make a correction for the NDVI index calculated from Sentinel-2 using GEE. I found out that for pixels with NDVI meaning in the range (0.5, 0.6) it should be subtracted 0.122..., and for range (0.6, 0.8) it should be added this. But for pixels < 0.5 or > 0.8 it should stay without changes. So I put it to my function through if/else. But only the first condition is working: if I put any condition after if - it will work, but nothing works after else if or else.

Can you please help me find what the wrong with this?

var tiles = [

'20170601T060631_20170601T061510_T42TYM',
'20170601T060631_20170601T061510_T43TBG',
'20170608T055641_20170608T060226_T42TYM',
'20170608T055641_20170608T060226_T43TBG',
'20170621T060631_20170621T061507_T42TYM',
'20170621T060631_20170621T061507_T43TBG'

]

var ndvi_palette = 'FFFFFF, CE7E45, DF923D, F1B555, FCD163, 99B718, 74A901, 66A000, 529400, ' + '3E8601, 207401, 056201, 004C00, 023B01, 012E01, 011D01, 011301';

var S2_display = {bands: ['B4', 'B3', 'B2'], min: 0, max: 3000};

function addnd(input) {
 var nd = input.normalizedDifference(['B8', 'B4']).rename('ndvi');
 var nd_n;
 if (nd.gte(0.5).and(nd.lte(0.6))){
   nd_n = nd.expression(
   'nd-0.122869881',
   {'nd':nd});
 return input.addBands(nd_n)
}
else if (nd.gt(0.6).and(nd.lte(0.8))){
   nd_n = nd.expression(
   'nd+0.122869881',
   {'nd':nd})
 return input.addBands(nd_n);
}
 else {
   nd_n = nd
 return input.addBands(nd_n);
}
}

 
var S2_collection = ee.ImageCollection("COPERNICUS/S2")
 .filter(ee.Filter.inList('system:index', tiles))
 .filterBounds(geometry)
 .map(addnd);
 
print(S2_collection);

var S2_mosaic = S2_collection.mean().clip(geometry);
print(S2_mosaic);

var NDVI_mean = S2_mosaic.reduceRegion({
 reducer: ee.Reducer.mean(),
 geometry: geometry,
 scale:10
 
})

Map.addLayer(S2_mosaic, S2_display, "Sentinel-2");

var ndvi_S2 = S2_collection.select('ndvi').mean().clip(geometry);


Map.addLayer(ndvi_S2, {min: -0.1, max: 1, palette: ndvi_palette}, 'NDVI S2',false);

Map.centerObject(geometry);
print("NDVI",NDVI_mean)

1 Answer 1

1

This is not the most efficient way to do it, but it works. I define two functions. In the first function (addnd) I create two layers, the first one is the default NDVI and the second one is the value to add/subtract for each pixel. This second layer has values:

  • -0.122 when NDVI is between 0.5 and 0.6
  • 0.122 when NDVI is 0.6 and 0.8
  • 0 otherwise.

Then I have another function (sumnd) that simply sums both bands and add the result as a new layer.

// create NDVi and "add" band
function addnd(input) {
 var nd = input.normalizedDifference(['B8', 'B4']).rename('ndvi0');
 var nd2 = nd.where(nd.gte(0.5).and(nd.lte(0.6)), -0.122)
 .where(nd.gte(0.6).and(nd.lte(0.8)), 0.122)
 .where(nd.lt(0.5).or(nd.gt(0.8)), 0).rename('add');
 return input.addBands([nd, nd2]);
}

// sums ndvi0 and "add"
function sumnd(input){
   var ndvi = ee.Image(0).expression(
    'ndvi0+add',
    {
      'ndvi0': input.select('ndvi0'),
      'add': input.select('add')
    }).rename('ndvi');
  return input.addBands(ndvi);
}

// apply functions
var S2_collection = ee.ImageCollection("COPERNICUS/S2")
 .filter(ee.Filter.inList('system:index', tiles))
 .filterBounds(geometry)
 .map(addnd).map(sumnd);

If you check the images in S2_collection it should work. However when you make the mosaic the values are not always as expected because you are using mean.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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