I am trying to create a time series of the total area of water pixels in a particular region using the ee.Image.pixelArea() method. I understand that this method creates a raster whereby the value of each pixel is the corresponding area of a specific pixel. This means that we would need a raster of strictly value 1 to multiply with that raster, to get the area, as is shown in Quantifying Forest Change and Calculating Area in Google Earth Engine.
I previously saw an answer to Counting number of pixel identified as water from a collection of landsat image using Google Earth Engine, which is similar to the output I want, except the answer does not convert the NDWI band to 1 (water pixels = 1, non-water = 0) but immediately multiplies the NDWI raster with the ee.Image.pixelArea(), which contradicts the two other articles i mentioned previously.
Despite me dividing the water pixels extracted by NDWI by itself (so everything = 1), my resultant values would be exactly the same if I had not done that (i.e. change water1 to water01, and erase the subsequent line where water01 = water1.divide(water1), which baffles me.
Can anyone provide some insight as to why this is so, or point out exactly what is wrong with my script?
// last modified on 9/7/2020
// script to extract total area of water pixels from given area (fp), using landsat 8
// two outputs: one where clouds are masked, one where clouds are not masked
var roi = ee.Geometry.Polygon([
[[95.1,20.5],[95.3,21],[96.3,21],[96.1,20.5]]
]);
Map.centerObject(roi,10);
// loading image collection
var landsat8= ee.ImageCollection('LANDSAT/LC08/C01/T1_SR').filterBounds(roi)
.filterDate('2013-01-01', '2015-07-31')
.filterMetadata("CLOUD_COVER","less_than",20);
var visParams = {
bands: ['B4', 'B3', 'B2'],
min: 0,
max: 3000,
gamma: 1.4,
};
Map.addLayer(landsat8, visParams,'original images');
// Function to extract water, then calculate area of water pixel
var waterfunction = function(image){
//add the NDWI band to the image
var ndwi = image.normalizedDifference(['B3', 'B5']).rename('NDWI');
//get pixels above the threshold
var water1 = ndwi.gt(-0.2);
//convert all pixels to value 1
var water01 = water1.divide(water1);
//extract only water pixels
image = image.addBands(water01).updateMask(water01);
// now to calculate water area, multiply water01 (all values are 1) by ee.Image.pixelArea; since that image gives us the area of each pixel
// then rename the band
var waterArea = water01
.multiply(ee.Image.pixelArea())
.rename('waterArea')
.divide(1e6);
// adding area of water as a band
image = image.addBands(waterArea);
// calculate area
var stats = waterArea.reduceRegion({
reducer: ee.Reducer.sum(),
geometry: roi,
scale: 30,
})
;
return image.set(stats);
};
// function to mask clouds out
function maskL8sr(image) {
// Bits 3 and 5 are cloud shadow and cloud, respectively.
var cloudShadowBitMask = (1 << 3);
var cloudsBitMask = (1 << 5);
// Get the pixel QA band.
var qa = image.select('pixel_qa');
// Both flags should be set to zero, indicating clear conditions.
var mask = qa.bitwiseAnd(cloudShadowBitMask).eq(0)
.and(qa.bitwiseAnd(cloudsBitMask).eq(0));
return image.updateMask(mask);
}
// mapping water function over my collection
var collection = landsat8.map(waterfunction);
print(collection,'collection');
var visParams2 = {min: -0.2,
max: 1,
bands: 'NDWI',
palette: ['00FFFF', '0000FF']};
var NDWICollection = collection.select('NDWI')
Map.addLayer(NDWICollection.first(), visParams2,'water');
//creating a chart
var title = {
title: 'Total area of water pixels (No clouds masked out)',
hAxis: {title: 'Time'},
vAxis: {title: 'Area (sq km)'},
};
// var cloudChart = ui.Chart.image.series({
// imageCollection: collection.select('waterArea'),
// region: fp,
// reducer: ee.Reducer.sum(),
// scale: 30,
// })
// .setOptions(title);
// print(cloudChart);
// masking clouds, then mapping water function over the collection
var cloudlessCollection = landsat8.map(maskL8sr).map(waterfunction);
var title2 = {
title: 'Total area of water pixels (Clouds masked out)',
hAxis: {title: 'Time'},
vAxis: {title: 'Area (sq km)'},
};
var cloudlessChart = ui.Chart.image.series({
imageCollection: cloudlessCollection.select('waterArea'),
region: roi,
reducer: ee.Reducer.sum(),
scale: 30,
})
.setOptions(title2);
print(cloudlessChart);