3

I'm trying to add to the map automatically trough a function a set of images from a landsat8 Image Collection to which previously I applied some filtering and a cloud masking function. I'm able to add all the images using the approach commented here: Add/display all images of mycollection in google earth engine, but the problem is that this way the clouds are not being filtered. I can't understand how to pass the cloudless images to the addImage function created on the script, I think it has something to do with the server/client structure of the platform.

Here is the link to the code:

https://code.earthengine.google.com/?scriptPath=users%2Fpaullcfias%2Fmosaics%3Alandsat8_rev

And the code itself:

    /**
 * Function to mask clouds based on the pixel_qa band of Landsat 8 SR data.
 * @param {ee.Image} image input Landsat 8 SR image
 * @return {ee.Image} cloudmasked Landsat 8 image
 */
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);
}

var dataset = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR') .filterDate('2019-01-01', '2020-03-31') .filterBounds(table) .filter(ee.Filter.or( ee.Filter.and(ee.Filter.eq('WRS_PATH', 8),
ee.Filter.eq('WRS_ROW', 60)), ee.Filter.and(ee.Filter.eq('WRS_PATH', 8), ee.Filter.eq('WRS_ROW', 61)), ee.Filter.and(ee.Filter.eq('WRS_PATH', 9),
ee.Filter.eq('WRS_ROW', 60)), ee.Filter.and(ee.Filter.eq('WRS_PATH', 9), ee.Filter.eq('WRS_ROW', 61)))) .filter(ee.Filter.lt('CLOUD_COVER', 75)) .map(maskL8sr);

print(dataset);

var listOfImages = dataset.toList(dataset.size()); print(listOfImages);

var visParams = { bands: ['B4', 'B3', 'B2'], min: 0, max: 3000, gamma: 1.4, };

Map.centerObject(table);

function addImage(image2) { // display each image in collection var image = ee.Image(image2.id); Map.addLayer(image.clip(table), visParams); }

dataset.evaluate(function(dataset) { // use map on client-side dataset.features.map(addImage); });

Map.addLayer(table, {},"zona estudio");

var slider = ui.Slider(); slider.onSlide(function(value) { var int_value = value * (Map.layers().length() - 1) >> 0; Map.layers().get(int_value).setOpacity(1); for (var i = int_value + 1; i < Map.layers().length(); i++) { Map.layers().get(i).setOpacity(0); } }); print(slider);

Paul León
  • 65
  • 7
  • By the way, I'm able to add each cloud filtered image manually to the map coverting the Image Collection to List and calling each element by it's index, but the idea is to automatize that task. – Paul León Jun 25 '20 at 23:17

1 Answers1

6

The solution you have tried uses the image 'id' so you end up displaying the 'original' image in the collection. As an alternative, following what you said in the comment, you can use the .get() method in your list inside a client side 'for' loop. For example:

var dataset = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
                  .filterDate('2019-01-01', '2020-03-31')
                  .filterBounds(table)
                  .filter(ee.Filter.or(
                  ee.Filter.and(ee.Filter.eq('WRS_PATH', 8),         
                  ee.Filter.eq('WRS_ROW', 60)),
                  ee.Filter.and(ee.Filter.eq('WRS_PATH', 8), 
                  ee.Filter.eq('WRS_ROW', 61)),
                  ee.Filter.and(ee.Filter.eq('WRS_PATH', 9),         
                  ee.Filter.eq('WRS_ROW', 60)),
                  ee.Filter.and(ee.Filter.eq('WRS_PATH', 9), 
                  ee.Filter.eq('WRS_ROW', 61))))
                  .filter(ee.Filter.lt('CLOUD_COVER', 75))
                  .map(maskL8sr);

var listOfImages = dataset.toList(dataset.size()); // 29 images

var visParams = { bands: ['B4', 'B3', 'B2'], min: 0, max: 3000, gamma: 1.4, };

Map.centerObject(table);

// client side loop for(var i = 0; i < 29; i++){ var image = ee.Image(listOfImages.get(i)); Map.addLayer(image, visParams, i.toString()) }

jfoguet
  • 545
  • 3
  • 6
  • Thank you very much @jfoguet, that worked well for me. I need to dig more into the client/server behavior. – Paul León Jun 29 '20 at 02:11
  • Thank you for this. Works great, except I don't always know there will be 29 images. Is there a way to set the loop so that we can type something like: for(var i = 0; i < n.toInt(); i++) { \ This doesn't work, help? – HPWhite Oct 16 '20 at 15:27
  • #HPWhite, inside the for loop you need a client-side number. So you can use try this line: var length = collection.size().getInfo() – jfoguet Oct 17 '20 at 16:36