First of all, the property name that holds the cloud coverage in Sentinel 2 is CLOUD_COVERAGE_ASSESSMENT
, not CLOUD_COVER
. In you code you are just sorting, which does nothing because that property is not present, but if you try to filter, it will throw an error.
// function to create mosaic of AOI
// Mosaic the visualization layers and display (or export).
// Map the function over one year of data
// Load Sentinel-2
var s2 = ee.ImageCollection('COPERNICUS/S2')
.filterDate('2017-06-01', '2017-12-30')
.filterBounds(geometry)
var filtered = s2.filterMetadata('CLOUD_COVERAGE_ASSESSMENT', 'less_than', 50)
// var filtered = s2.filterMetadata('CLOUD_COVER', 'less_than', 50) // doesn't work
print('S2', s2.toList(s2.size()).map(function(img){return [ee.Image(img).date().format('yyyyMMdd'), ee.Image(img).get('CLOUD_COVERAGE_ASSESSMENT')]}))
print('filtered', filtered.toList(filtered.size()).map(function(img){return [ee.Image(img).date().format('yyyyMMdd'), ee.Image(img).get('CLOUD_COVERAGE_ASSESSMENT')]}))
https://code.earthengine.google.com/e2709c19846884520c2369faffc50b64
To compute a "mask percentage" property first you have to mask out clouds:
var cldmask = require('users/fitoprincipe/geetools:cloud_masks')
var masked = filtered.map(cldmask.sentinel2())
// Inspect first masked
var rgbVis = {
min: 0.0,
max: 3000,
bands: ['B4', 'B3', 'B2'],
};
Map.addLayer(masked.first(), rgbVis, 'Masked')
Map.addLayer(geometry)
An then, I have a function in geetools
to compute the percentage of masked pixels.
var tools = require('users/fitoprincipe/geetools:tools')
// Test the first image of the collection
var maskCover = tools.image.maskCover(masked.first(), geometry)
print('first image mask coverage (%):', maskCover)
print('first image cloud coverage (%):', masked.first().get('CLOUD_COVERAGE_ASSESSMENT'))
// Add MASK_COVER property for all images in the collection
var addMaskCover = function(img) {
var maskCover = tools.image.maskCover(img, geometry)
return img.set('MASK_COVER', maskCover)
}
var colWithMaskCover = masked.map(addMaskCover)
// filter the collection by MASK_COVER
var newFiltered = colWithMaskCover.filterMetadata('MASK_COVER', 'less_than', 10)
// Inspect results
print('newFiltered', newFiltered)
print(newFiltered.toList(newFiltered.size()).map(function(img){
return {
'CLOUD_COVERAGE_ASSESSMENT':ee.Image(img).get('CLOUD_COVERAGE_ASSESSMENT'),
'MASK_COVER': ee.Image(img).get('MASK_COVER')
}
}))
https://code.earthengine.google.com/cd36f8a7336e396aab0c1ec99b78043e
map
function to calculate the number of cloud pixels and non-cloud pixels within a given polygon, get the cloud cover from these two numbers, then add a new property to each image to store this information.