2

I am using the below code (taken from this post) to make monthly composites of cloud masked S2 data but the reduce.median won't work because my ImageCollection doesn't have a timestamp. Does anyone know how I can add a timestamp to the masked ImageCollection?

/* Function to mask clouds using the Sentinel-2 QA band
 * @param {ee.Image} image Sentinel-2 image
 * @return {ee.Image} cloud masked Sentinel-2 image
 */
function maskS2clouds(image) {
  var qa = image.select('QA60');

  // Bits 10 and 11 are clouds and cirrus, respectively.
  var cloudBitMask = 1 << 10;
  var cirrusBitMask = 1 << 11;

  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
      .and(qa.bitwiseAnd(cirrusBitMask).eq(0));

  return image.updateMask(mask).divide(10000);
}


var geometry = geometry; 

var col = ee.ImageCollection('COPERNICUS/S2')
          .filterBounds(geometry).filterDate('2018-01-01','2019-01-01')
          // Pre-filter to get less cloudy granules.
          .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
          .map(maskS2clouds)

print(col)          

//Monthly Images
var months = ee.List.sequence(1,12);
var years = ee.List.sequence(2018,2018); 

// monthly composite
var monthlyImages =  ee.ImageCollection.fromImages(
  years.map(function (y) {
  return months.map(function(m){
  var w = col.select('B4', 'B3', 'B2').filter(ee.Filter.calendarRange(y, y, 'year'))
           .filter(ee.Filter.calendarRange(m, m, 'month'))
           //.mean()
           .median()
           //.min()
           .set('system:time_start',ee.Date.fromYMD(y,m,1));
  return w.set('year', y)
           .set('month', m)
           .set('date', ee.Date.fromYMD(y,m,1))
           .set('system:time_start',ee.Date.fromYMD(y,m,1)) 

});
}).flatten());

print(monthlyImages)

Error: ImageCollection (Error) reduce.median: Can't apply calendarRange filter to objects without a timestamp.

1

Certain (many) operations on an image will not include the image properties in the result. In your case, divide(10000) is the one dropping system:time_start. You can add all properties back with copyProperties(). First argument is the image or feature you want to copy properties from. By (the slightly annoying) default, all system:* properties is excluded. Provide a second argument to explicitly specify the list of property names to copy to include system:* properties. image.propertyNames() is the list of all property names.

image.updateMask(mask).divide(10000)
    .copyProperties(image, image.propertyNames())

https://code.earthengine.google.com/82b43cd41b05ba85292c907807009223

| improve this answer | |

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.