Shaun Levick

Environmental Monitoring and Modelling

Lab 8 - Mapping and monitoring surface water availability


Managing water resources requires spatially explicit knowledge of where water is located in landscapes, and how it varies over time. The objective of this lab is to map the presence of surface water from space, and calculate the inundation frequency of different water bodies.


  • Google Earth Engine Team
  • USAID, SERVER Mekong, NASA, Winrock International, adpc

Mapping water from space

We will make use of the Landsat 8 TOA Tier 1 collection for this exercise (LANDSAT/LC08/C01/T1_TOA).

var L8 = ee.ImageCollection('LANDSAT/LC08/C01/T1_TOA');
  • Define a region of interest using the geometry rectangle tool. Rename it (roi). We will use the vicinity of Menindee Lakes for this example, located between Broken Hill and Ivanhoe in NSW, Australia.
  • Next we will set the desired date range that we are interested in. Landsat 8 is available from April 2013 to present
// Set the desired the start and end dates
var startdate = ee.Date('2013-05-01');
var enddate = ee.Date('2019-09-30');

// Select  Landsat  8  images  within  the  specified  time  and spatial range
var l8images = L8.filterDate(startdate, enddate)

Masking out clouds

  • This next piece of code shows an alternative way of dealing with clouds by masking
//Makes  a  function  to  mask  the  clouds
var cloudThresh = 20;
var cloudFunction = function(image){
var scored = ee.Algorithms.Landsat.simpleCloudScore(image);
var quality ='cloud');
var cloudy =;
var cloudmask = cloudy.not();
return image.updateMask(cloudmask);
  • Now we can write a function to map the mask over the collection
//  Map  the  function  over  the  Landsat  8  collection.
var l8CloudMasked =;

//Display  the  median  of  the  image  collection  for  the ROI
Map.centerObject(roi, 8);
Map.addLayer(l8CloudMasked.median().clip(roi), {
min: 0,
max: 0.5,
bands: ['B5', 'B4', 'B3']
}, 'Landsat 8 False colour median');

The Normalised Difference Water Index (NDWI)

  • The following lines of code create a function to calculate NDWI - the Normalised Difference Water Index. We need the NIR and green bands for this as NDWI = (G - NIR)/(G + NIR).
  • The second part of the code uses the function to calculate NDWI for each image in the collection that intersects our roi and date range.
  • The third part of the code maps NDWI spatially to show the maximum spatial extent of water over our date range.
// Creating the function to calculate the NDWI
function addNdwi(img) {
var ndwi = img.normalizedDifference(['B3', 'B5']).rename('NDWI');
return img.addBands(ndwi);

// Add NDWI to the collection
var l8ndwi = L8
.filterDate(startdate, enddate)
.select(['B3', 'B5'])

// Map NDWI spatially
{bands: 'NDWI', min: 0, max:1, palette: ['darkblue']}, 'NDWI L8');
  • If we are interested in a particular year we can map it like this, using 2018 as an example.
// Choose a year and make NDWI map
var year = 2018;
var ndwiViz = {bands:'NDWI',min:0,max:1,palette:['darkblue']};
var ndwiYEAR = l8ndwi.filterDate({
start: ee.Date.fromYMD(year, 1, 1),
end: ee.Date.fromYMD(year, 12, 31)
Map.addLayer(ndwiYEAR.mask(ndwiYEAR).clip(roi), ndwiViz, '2018 NDWI');
  • Lastly, we can compute the frequency of inundation. This involves a bit of maths as shown below.
//Computing frequency of inundation
var waterBinary ='NDWI').map(function(image) {
var frequency = waterBinary.sum().divide(waterBinary.count());
{palette: ['white', 'magenta', 'blue','darkblue']}, 'Water inundation frequency');


  • Move your region of interest (roi) around different parts of Australia and explore how current drought conditions are affecting dam levels in different parts of the country.
  • Think about how you might go about expanding the time-series and going further back in time to look at longer-term inundation trends.

GEARS - Geospatial Ecology and Remote Sensing -

(c) Shaun R Levick