[GIS] Cloudfree images in small area from Sentinel-2

cloud covergoogle-earth-enginesentinel-2

I have a similar question to this one here: Filter Landsat images base on cloud cover over a region of interest

Different from the linked question I would like to find a more general solution that is not just working for landsat.

I have some small areas (up to 1 kmĀ²) where I would like to get all the images that are completely cloud free.

Using the .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 5)) on the cropped image checks the entire scene for clouds and not just the small area. Is there something comparable to ee.Algorithms.Landsat.simpleCloudScore(image).select('cloud'); that would work for Sentinel 2?

Here is what I tried:

var rectangle = ee.Geometry.Rectangle([16.9, 78.31, 17.1, 78.33]);

var collection = ee.ImageCollection('COPERNICUS/S2')
    .filterDate('2018-05-01', '2018-10-30')
    .filterBounds(rectangle);

var clip_collection = collection.map(function(image) { return image.clip(rectangle); });

var coll_s2_filtered = clip_collection.filterBounds(rectangle)
                      .filter(ee.Filter.lte('CLOUDY_PIXEL_PERCENTAGE', 5))
                      .sort('system:time_start',false);

And I tried using the ee.Algorithms.Landsat.simpleCloudScore(image) but then I get

"Error in map(ID=20180501T122701_20180501T122655_T33XWG):
Landsat.simpleCloudScore: Image is not a Landsat scene or is missing
SENSOR_ID metadata."

Best Answer

I think a good approach would be similar to this code sample below Sentinel Cloud-free Collection Google Earth Engine Code Editor

var Jan2016 = ee.ImageCollection('COPERNICUS/S2')
      .filterBounds(NSW)
      .filterDate('2016-01-01', '2016-01-30');

var trueColor = {bands: ['B4', 'B3', 'B2'], min: 0, max: 3000};
var falseColor= {bands: ['B8', 'B3', 'B4'], min: 0, max: 3000};
//Define the CLoud layer (here: QA60 is MSI2's quality mask)
var Clouds = {bands: ['QA60']};

//Add the cloud mask as layer; PROBLEM: SEEMS QA60 is taken from different images every time..
//Clouds is just a band, do i need to specify the threshold?
Map.addLayer(Jan2016, Clouds, "CloudsJan16");

// Mask clouds
var noclouds = Jan2016.map(function(img) {
              var mask = 
img.select(['QA60']).neq(11); 
//.neq(xx) doesn't seem to make a difference
                   return img.updateMask(mask);

});

//Add the layer/imagery to the map with variable, display type, and name  
Map.addLayer(noclouds, trueColor, "NoClouds");
Map.addLayer(Jan2016, falseColor, "Jan2016false");
Related Question