1

Using this code, I've extracted water extent in a Landsat median image. But how can I compute water area extent?

code link: https://code.earthengine.google.com/8ad84d9ca59b3cb71b62f83119621bdc

var urmia = table;

Map.centerObject(urmia);
Map.addLayer(urmia);

var landsat = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
.filterBounds(urmia)
.filterDate('2018-01-01','2019-01-01')
.filter(ee.Filter.lessThan('CLOUD_COVER',5))
.median()
.clip(urmia)
.select('B[4-5]')
.normalizedDifference(['B4','B5'])
.gt(0.2)
.rename('time2');

Map.addLayer(landsat);
0

Has Lake Urmia shrunk dramatically? In the following code, I convert all pixels above your NDWI threshold to 1 and and everything else to 0. That way you can apply a region reducer to sum all of the values in the region, which in essence is the number of "positive" pixels. If LS8 pixels are 30mx30m, multiply the sum by 30^2 to get total number of square meters, and convert to square kilometers. That leads to a calculated area of ~2477 square kilometers, which is way less than Google's reporting of 5200 square kilometers...

Edit: Updated code to implement ee.Image.pixelArea() rather than back-of-the-envelope math. Turns out the water-covered region is ~1956 km^2.

var urmia = table;

Map.centerObject(urmia);
Map.addLayer(urmia);

// Create water mask
var h20mask = function(image) {
  return image.updateMask(image.gt(0.2));
};

var landsat = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
.filterBounds(urmia)
.filterDate('2018-01-01','2019-01-01')
.filter(ee.Filter.lessThan('CLOUD_COVER',5))
.median()
.clip(urmia)
.select('B[4-5]')
.normalizedDifference(['B4','B5'])
.gt(0.2)
.rename('time2');

Map.addLayer(landsat);
print("Landsat",landsat);

// Convert pixels with water to 1
var h20 = h20mask(landsat);
Map.addLayer(h20,{},"h20");
var LS_to0 = h20.expression(
    '0 * LS', {
      'LS': h20
});
var LS_to1 = LS_to0.expression(
    '1 + LS', {
      'LS': LS_to0
});
// Visualize
Map.addLayer(LS_to1, {color:'#00FF00', min:-1,max:1}, "water");

// Calculate pixel area
var LS_PA = LS_to1.multiply(ee.Image.pixelArea());

// Print sum
var stats = LS_PA.reduceRegion({
  reducer: ee.Reducer.sum(),
  geometry: table,
  scale: 30,
  maxPixels: 1e13
});

print(stats);
  • thanks for your help. but I think ee.image.pixelArea() is more accurate than your methodology. Have a look to this link, please: developers.google.com/earth-engine/… – Johny Astine Feb 24 at 11:29
  • @JohnyAstine I had no idea ee.image.pixelArea() existed! Thanks for sharing; see updated code. – JepsonNomad Feb 24 at 19:29

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.