7

I'm creating a composite image, in order to create a timeseries. I've already created the composited image, but i am having difficulty masking the clouds of the composite image. I've followed the code from a page having similar problems, however when I run the code (after replacing all the l8_mayo to composite as that is the name of my composite var), I get the error code of composite.map not a function. This error does not come up when I run the exact same code from the previous answer.

Can someone explain how to overcome this problem?

Here is the page I used: Apply a cloud mask to a Landsat8 collection in Google Earth Engine - time series

here is my code and the link to my code: https://code.earthengine.google.com/e42eaf1819e63e1d679e5db3f4c54e89

(point is the long, lat for Lake Manyara, Tanzania)

//load images for composite
var sr14= ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
.filterBounds(point)
.filterDate('2014-01-01','2014-03-01')
.select(['B4','B3','B2']);

// Temporally composite the images with a maximum value function.
var composite = sr14.max();
Map.setCenter(35.8244, -3.5799);
Map.addLayer(composite, {}, 'max value composite');

var getQABits = function(image, start, end, newName) {
// Compute the bits we need to extract.
var pattern = 0;
for (var i = start; i <= end; i++) {
   pattern += Math.pow(2, i);
}
// Return a single band image of the extracted QA bits, giving the band
// a new name.
return image.select([0], [newName])
              .bitwiseAnd(pattern)
              .rightShift(start);
};

// A function to mask out cloudy pixels.
var cloud_shadows = function(image) {
// Select the QA band.
var QA = image.select(['BQA']);
// Get the internal_cloud_algorithm_flag bit.
return getQABits(QA, 7,8, 'Cloud_shadows').eq(1);
// Return an image masking out cloudy areas.
};

// A function to mask out cloudy pixels.
var clouds = function(image) {
// Select the QA band.
var QA = image.select(['BQA']);
// Get the internal_cloud_algorithm_flag bit.
return getQABits(QA, 4,4, 'Cloud').eq(0);
// Return an image masking out cloudy areas.
};

var maskClouds = function(image) {
var cs = cloud_shadows(image);
var c = clouds(image);
image = image.updateMask(cs);
return image.updateMask(c);
};

var composite_free = composite.map(maskClouds);

Map.addLayer(composite_free, 'composite collection without clouds');

2 Answers 2

15

Please, read the related answer.

Use the right parameters and always check metadata

You're trying to filter with BQA band and in SR product, there is no BQA band, there is pixel_qa band instead. Also, bits used are different (3 and 5). Finally, if you are trying to create a cloud-free composite, first sort by cloud cover.

var point = /* color: #98ff00 */ee.Geometry.Point([35.83946228027344, -3.5380934964711126]);

//load images for composite
var sr14= ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
.filterBounds(point)
.filterDate('2014-01-01','2014-03-01').sort('CLOUD_COVER',false);

// Temporally composite the images with a maximum value function.
var visParams = {bands: ['B4', 'B3', 'B2'], min:0,max: 1000};
Map.setCenter(35.8244, -3.5799);
Map.addLayer(sr14, visParams, 'max value composite');

var getQABits = function(image, start, end, newName) {
    // Compute the bits we need to extract.
    var pattern = 0;
    for (var i = start; i <= end; i++) {
       pattern += Math.pow(2, i);
    }
    // Return a single band image of the extracted QA bits, giving the band
    // a new name.
    return image.select([0], [newName])
                  .bitwiseAnd(pattern)
                  .rightShift(start);
};

// A function to mask out cloudy pixels.
var cloud_shadows = function(image) {
  // Select the QA band.
  var QA = image.select(['pixel_qa']);
  // Get the internal_cloud_algorithm_flag bit.
  return getQABits(QA, 3,3, 'cloud_shadows').eq(0);
  // Return an image masking out cloudy areas.
};

// A function to mask out cloudy pixels.
var clouds = function(image) {
  // Select the QA band.
  var QA = image.select(['pixel_qa']);
  // Get the internal_cloud_algorithm_flag bit.
  return getQABits(QA, 5,5, 'Cloud').eq(0);
  // Return an image masking out cloudy areas.
};

var maskClouds = function(image) {
  var cs = cloud_shadows(image);
  var c = clouds(image);
  image = image.updateMask(cs);
  return image.updateMask(c);
};

var composite_free = sr14.map(maskClouds);

Map.addLayer(composite_free,visParams, 'composite collection without clouds');

Link: https://code.earthengine.google.com/6a9d2bce417076d1f1b677e775584690

0
12

@Aldo's answer is the correct one, no doubt, but if you want to make the code shorter and you don't mind loosing the 'core' of cloud masking, you can use a module:

var point = /* color: #98ff00 */ee.Geometry.Point([35.83946228027344, -3.5380934964711126]);

//load images for composite
var sr14= ee.ImageCollection('LANDSAT/LC08/C01/T1_SR')
.filterBounds(point)
.filterDate('2014-01-01','2014-03-01')
//.select(['B4','B3','B2']); // if you select those bands you loose BQA band

// Temporally composite the images with a maximum value function.
var composite = sr14.max();
Map.setCenter(35.8244, -3.5799);
var vis = {bands:['B5','B6','B4'],min:0, max:5000}

Map.addLayer(composite, vis, 'max value composite');

var mask = require('users/fitoprincipe/geetools:cloud_masks')

print(mask.help['landsatSR'])

var mask_function = mask.landsatSR() // mask function

var col_free = sr14.map(mask_function) // apply function to collection
var composite_free = col_free.median() // create composite using max

Map.addLayer(composite_free, vis, 'composite collection without clouds');

link: https://code.earthengine.google.com/31b5b21913eefdc05563dfec72c4ee08

3
  • Hi, this doesn't work for Collection 2 which is now the recommended collection in GEE. I think it's because the band names are different. Is there any fix? Thank you!
    – Jan Pisl
    Jun 15, 2022 at 14:45
  • Also, I wonder why use max() for the composites? Is it better in some way than median() or mean()? Thank you!
    – Jan Pisl
    Jun 15, 2022 at 15:04
  • 1
    ok, now there are two comments to answer. 1st, yes, C2 is recommended and not implemented yet. 2nd, no reason, but I understand that the most common composite is median, so I'll modify it, thanks Jun 15, 2022 at 23:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.