Google Earth Engine – Mask Water Bodies Effectively

google-earth-enginemasking

I'm trying to to detect changes in land surface over few periods in a specific polygon.
The problem is that I want to block water bodies from my calculations.

How can I do it?

This is the code I have created. All the objects called "period1/2/3/4" are NDVI images that I have ALREADY processed and they reflect the average NDVI for few years i'm interested in.
:

var diff1=(period1.subtract(period2)).divide(period1).multiply(100);
var diff2=(period2.subtract(period3)).divide(period2).multiply(100);
var diff3=(period3.subtract(period4)).divide(period3).multiply(100);
var diff4=(period4.subtract(period5)).divide(period4).multiply(100);
var meandiff=(diff1.add(diff1).add(diff3).add(diff4)).divide(4);


var visDiff={min:0, max:100, palette: [
    'FFFFFF', '#ffcccc', '#ff8080', '#ff1a1a', '#e60000'
  ]};

Map.centerObject(period1,7);
Map.addLayer(diff1,visDiff,'Diff periods1-2');
Map.addLayer(diff2,visDiff,'Diff periods2-3');
Map.addLayer(diff3,visDiff,'Diff periods3-4');
Map.addLayer(diff4,visDiff,'Diff periods4-5');
Map.addLayer(meandiff,visDiff,'18Years');

Best Answer

Assuming you are working at Landsat resolution and your water bodies are stable over time, you can easily mask with the JRC water layer (Pekel et al. 2016). The only trick is that the basic water occurrence layer includes both water absence (dry land) and unmapped areas (mostly ocean) as masked data, so you have to parse the metadata layer for a complete picture:

var waterOcc = ee.Image("JRC/GSW1_0/GlobalSurfaceWater").select('occurrence'),
    jrc_data0 = ee.Image("JRC/GSW1_0/Metadata").select('total_obs').lte(0),
    waterOccFilled = waterOcc.unmask(0).max(jrc_data0),
    waterMask = waterOccFilled.lt(50);

Map.addLayer(meandiff.updateMask(waterMask),visDiff,'18Years'); 
Related Question