I computed the NDWI of the whole image collection and I expect to output an image that shows water body whenever it has been flooded , even once , throughout the filtered date.

Somehow the output image only show the result of the last image in the image collection.

This is what I currently have :

// Function to clip image collection
var clipimgcol = function(image){ return image.clip(Border)} ;
// ImageCollection
var l8collection = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
.filterDate('2014-02-05', '2018-02-05')

// Mask pixels with clouds and cloud shadows
// Surface reflectance products come with a 'pixel_qa' band based on CFMask
// Create function leaving Water and Clear
var maskCloudWater = function(image){
var pixel_qa = image.select('pixel_qa');
return image.updateMask(pixel_qa.eq(322).or(pixel_qa.eq(386)).or(pixel_qa.eq(834))
.or(pixel_qa.eq(898)).or(pixel_qa.eq(1346)) //pixel_qa = Clear
.or(pixel_qa.eq(900)).or(pixel_qa.eq(1348))); //pixel_qa = Water

// use "map" to apply the function to each image in the collection
var l8masked = l8collection.map(maskCloudWater);

// Compute the Normalized Difference Water Index (NDWI).
var getNDWI = function(img){
  return img.addBands(img.normalizedDifference(['B3','B5']).rename('NDWI'));

// map over image collection
var l8ndwi = l8masked.map(getNDWI);
var ndwi = l8ndwi.select('NDWI');

I use a threshold of 0.3 for NDWI and tried to iterate the image collection so once the pixel's NDWI is gte 0.3 it returns 1 and the output will be the way I expected, but resulted differently :

var ini = ee.Image(ndwi.first());
function it (current , previousresult){
  var step1 = current.gte(0.3);
  var step2 = ee.Image(previousresult).select('NDWI');
  var laststep = ee.Image.cat([step2 , step1]);

  return laststep;
var ndwiit = ee.Image(ndwi.iterate(it , ini)).select('NDWI');
var ndwiViz = {min: -1, max: 1, palette: ['green', 'white','blue']};
Map.addLayer(ndwiit , ndwiViz, 'NDWIIT', false);

I also came up with the idea of remap function, to update the pixel's NDWI value once it is gte 0.3 but i didn't know how to extract band value of every pixel.


I think there can be a simpler approach to this. From my understanding you just want to see if the NDWI value ever exceeds 0.3 in ANY scene of the image collection. To do this you can first find out pixels in each scene that are greater than 0.3 NDWI.

var gt3 = ndwi.map(function(image){
  return image.gte(0.3);

This will give you a mask layer having pixels with value 0 and 1, 0 for pixels less than 0.3 NDWI and 1 for pixels greater than or equal to 0.3. Now since all the pixels are either 0 or 1 in each scene. You can take max of this collection to get either 0, for pixels whose ndvi were never greater than 0.3 as all the pixels will be 0, or 1, for pixels which had at least one scene with NDWI gte 0.3

var ndwiit = gt3.max();

Then the rest of code should work fine.

  • It worked ! However, I would prefer to keep the maximum value of the pixels that had once (or more than once) exceed 0.3 . Pixels that has never exceed the threshold of 0.3 also has a NDWI value of the first or last image. Is that possible? – Kevin. C Jul 10 '19 at 17:05
  • you can do ndwi.max().gte(0.3) to get max pixel value of each pixel within the collection and then apply the gte 0.3 condition. As if a pixel never exceeded 0.3 then the max will definitely be less than 0.3. As for pixels that never exceeded the threshold but have value same as the first image ndwi.max().eq(ndwi.first()).and(ndwi.max().lt(0.3)) should work. Here I am calculating max and then equating it to first image as well as checking max values less than 0.3. Note that this will just give you a mask and it needs to be applied to the max if you want actual values. – Nishanta Khanal Jul 11 '19 at 5:26
  • Tried to compute probability of pixels being water by iteration. My goal is to add 1 to the pixels that's gte 0.3(which returns1) so the greater the value the more red it will be. var ini = ndwi.first(); function it (current , previousresult){ var step1 = current.gte(0.3); var step2 = ee.Image(previousresult).gte(0.3); var laststep = step2.add(step1); return laststep; } var ndwiit = ee.Image(ndwi.iterate(it , ini)); var ndwiitViz = {min: 0, max: 62, palette: ['green', 'yellow','red']}; Map.addLayer(ndwiit, ndwiitViz , 'ndwiit'); but it return nothing @Nishanta Khanal – Kevin. C Jul 11 '19 at 10:13
  • How are you calculating the probability? If it is total number of times a pixel is gte 0.3 divided by total number of scenes for the pixel then you can do var ndwiit = gt3.sum().divide(gt3.count()). The problem with your implementation is that when you use 'add' function it takes into account masks of the images and when you are doing that for a whole bunch of images, all the masks in each scene start to pile up. – Nishanta Khanal Jul 11 '19 at 11:11
  • if you stll want to stick to your implementation, i could make it work in this way var ini = ee.Image.constant(0); function it (current , previousresult){ var step1 = ee.Image(current).gte(0.3).unmask(0); var step2 = ee.Image(previousresult); var laststep = step2.add(step1); return laststep; } – Nishanta Khanal Jul 11 '19 at 11:12

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.