2

How do you write the MSAVI formula in JavaScript function for Google Earth Engine?

I am trying to calculate the MSAVI as a function. The aim is to map the result over a Sentinel-2 composite and not a single image.

I tried the same thing for the OSAVI Index and it worked fine: OSAVI = (NIR-Red)/ (NIR+Red+0.16)

function addOSAVI(input) {
  var nir = input.select(['B8']);
  var red = input.select(['B4']);
  var osavi = nir.subtract(red).divide(nir.add(red).add(0.16)).rename('OSAVI');
return input.addBands(osavi);

}

I need a function in the same manner as the OSAVI function, but I have problem with implementing sqrt() and pow() correctly.

enter image description here

function addMSAVI(input) {
  var nir = input.select(['B8']);
  var red = input.select(['B4']);
  var msavi = (nir.add(1).multiply(2).subtract(sqrt(pow(nir.add(1).multiply(2),2)).subtract((nir.subtract(red)).multiply(2)))).divide(2).rename('MSAVI');
return input.addBands(msavi);

}

More information about MSAVI: http://wiki.landscapetoolbox.org/doku.php/remote_sensing_methods:modified_soil-adjusted_vegetation_index

  • 1
    have you read developers.google.com/earth-engine/image_math? – Rodrigo E. Principe Mar 22 '18 at 17:50
  • Yes I have of course, but I can't find anything helpful for using within a function. Are you refering to image.expression()? – loloj0 Mar 22 '18 at 18:05
  • Use image.expression() with TOA or BOA reflectance values – aldo_tapia Mar 22 '18 at 18:36
  • I want to use the function on an a pre filtered sentinel-2 composite, so I can't use image.expression() as far as I know and I tried it. var msavi = s2_composite.expression('(2*NIR+1-sqrt(pow((2*NIR+1),2) - 8*(NIR-RED))/2)', {'NIR': input.select('B8'), 'RED': input.select('B4')}); is not working – loloj0 Mar 22 '18 at 18:51
  • you should update the question showing what you've tried so far. – Rodrigo E. Principe Mar 22 '18 at 19:28
3

Both ways work just fine and give the same results: https://code.earthengine.google.com/3f766772035a8890b0caf231eb652a1f.

There is also a small mistake in the formula in your code - wrong bracket.

// compute composite for all images aquired in the last 3 days
var now = ee.Date(Date.now())
var composite = s2
  .filterDate(now.advance(-3, 'day'), now)
  .mosaic()
  .divide(10000)

Map.addLayer(composite, {bands: ['B8', 'B8', 'B4'], min: 0, max: 0.4}, 'composite')

// compute MSAVI2 using expression
var msavi2 = composite.expression(
  '(2 * NIR + 1 - sqrt(pow((2 * NIR + 1), 2) - 8 * (NIR - RED)) ) / 2', 
  {
    'NIR': composite.select('B8'), 
    'RED': composite.select('B4')
  }
);

Map.addLayer(msavi2, {min: -0.1, max: 0.5}, 'msavi2 (expression)')

// compute MSAVI2 using fluent API
msavi2 = composite.select('B8').multiply(2).add(1)
  .subtract(composite.select('B8').multiply(2).add(1).pow(2)
    .subtract(composite.select('B8').subtract(composite.select('B4')).multiply(8)).sqrt()
  ).divide(2)

Map.addLayer(msavi2, {min: -0.1, max: 0.5}, 'msavi2 (fluent)')
  • Thank you so much, this works just fine! Awesome Apperently I did not know how to use the pow and sqrt correctly. – loloj0 Mar 22 '18 at 19:57

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.