I am trying to pull out every lake and pond in a region of SW Alaska. I have successfully identified all water features using the following code:

// study area
var rect = ee.Geometry.Rectangle([-168, 58, -155, 64], 'EPSG:4326', false); //xMin, yMin, xMax, yMax
Map.addLayer(rect,{},"rectangle", false);

// Function to mask clouds using the Sentinel-2 QA band.
function maskS2clouds(image) {
  var qa = image.select('QA60');
  // Bits 10 and 11 are clouds and cirrus, respectively.
  var cloudBitMask = Math.pow(2, 10);
  var cirrusBitMask = Math.pow(2, 11);
  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0).and(
  // Return the masked and scaled data.
  return image.updateMask(mask).divide(10000);

// Bring in the Sentinel-2 collection and create MNDWI from a median of the filtered collection
var s2 = ee.ImageCollection('COPERNICUS/S2')
                  .filterDate('2016-06-01', '2018-10-15')
                  // Pre-filter to get less cloudy granules.
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
                  .filter(ee.Filter.dayOfYear(153, 274)) // summer images only
var mndwi = s2.normalizedDifference(['B3', 'B11']).rename('mndwi');
Map.addLayer(mndwi.clip(rect), {min:-1, max:1, palette:['brown','black','blue']}, 'Modified Normalized Difference Water Index MNDWI', false);

// Change this threshold to allow more or less water in mask
var ndwiThreshold = 0.4; 
var water = mndwi.gt(ndwiThreshold);
Map.addLayer(water.clip(rect), {min:0, max:1, palette:['black', 'blue']}, 'water', true);

but how could I separate lakes/ponds from streams and rivers? I've been trying to use aspect ration but haven't gotten that to work yet.


It would take some back-end work on your part, but the recently released GRWL dataset includes a global raster that labels waterbodies as rivers, lakes, dams, etc. at 30 meter resolution. A possible hurdle you'd have to overcome is that their tiles are in local UTM Zone CRSs, so you'd probably want to stitch them all together for a global study. You could also request on the developer's forum that GEE ingest that dataset for all users. But if you're only working in a small area (which you seem to be), you could create your own mini-GRWL by stitching only the tiles you need.

If you are able to read from the GRWL dataset, you can simply overlay each of your target areas with the GRWL data and compute the mode value of GRWL, which maps to a particular waterbody type. Their raster has the following:

Pixel classifications:

DN = 255 : River

DN = 180 : Lake/reservoir

DN = 126 : Tidal rivers/delta

DN = 86 : Canal

DN = 0 : Land/water not connected to the GRWL river network

  • If it gets frustrating, I am speaking from experience when I say that automating the classification of water bodies is not easy to get right. This dataset takes a lot of the pain out of the process once you can get it in a usable format and upload it as an asset. – Jon Jul 31 '18 at 20:10

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.