5

Is there a “quick" way in Google Earth Engine to show in an image collection (Sentinel 2) the least cloudy image per each path/row or tile (multiple tiles) for a given timeframe? So far I managed to filter but not to pick the selection of the best images.

2 Answers 2

5

Not sure if this is exactly what you want, but you can sort() and mosaic():

var s2 = ee.ImageCollection('COPERNICUS/S2');

var composite = s2.filterDate('2016-01-01', '2016-12-31')
                  .sort('CLOUDY_PIXEL_PERCENTAGE', false)
                  .map(function(image) {
                    return image.addBands(image.metadata('system:time_start'));
                  })
                  .mosaic();

Since there's a time band, you'll be able to recover the date of each pixel.

2
  • Thank you Nicholas! How can I include in your code a command to filter by one specific region (country). I tried with .filterBounds but I got some error...
    – Ana Leite
    Jul 23, 2017 at 15:27
  • To do it for a country, s2 = s2.filterBounds(geometry). Jul 24, 2017 at 16:34
3

Sentinel-2 uses MGRS tiles (granules) as described on the Sentinel-2 Data Products page.

Approach:

  1. Filter the collection by date range and MGRS tile
  2. Sort using the Sentinel-2 image's CLOUDY_PIXEL_PERCENTAGE property
  3. Extract the first image in the sorted collection

In code:

var START_DATE = '2017-02-15';
var END_DATE = '2017-04-15';
var MGRS_TILE = '31RCL';

var s2_unsorted = ee.ImageCollection('COPERNICUS/S2')
                    .filterMetadata('MGRS_TILE', 'equals', MGRS_TILE)
                    .filterDate(START_DATE, END_DATE);
var s2_sorted = s2_unsorted.sort('CLOUDY_PIXEL_PERCENTAGE');
var least_cloudy_image = ee.Image(s2_sorted.first());

Map.centerObject(least_cloudy_image);
Map.addLayer(
  least_cloudy_image,
  {bands:'B4,B3,B2', min:0, max:3000},
  'least cloudy image'
);    
print('least cloudy image', least_cloudy_image);

It can be useful to print out the image collection, and the list of metadata properties to confirm that it is working the way you expect:

var MAX_IMAGES_IN_LIST = 100;
var getCloudMetadata = function (coll) {
  return coll.toList(MAX_IMAGES_IN_LIST).map(
    function (i) {
      return ee.Image(i).get('CLOUDY_PIXEL_PERCENTAGE');
    }
  );
};

print(
  'START_DATE', START_DATE,
  'END_DATE', END_DATE,
  'MGRS_TILE', MGRS_TILE
);
print(
  's2 (unsorted)', s2_unsorted,
  'CLOUDY_PIXEL_PERCENTAGE metadata', getCloudMetadata(s2_unsorted)
);
print(
  's2 (sorted)', s2_sorted,
  'CLOUDY_PIXEL_PERCENTAGE metadata', getCloudMetadata(s2_sorted)
);
2
  • Thank you Tyler! I don't want sort for just one tile, my goal is to sort for each tile of a region, for instances, a country: var countries = ee.FeatureCollection('ft:1tdSwUL7MVpOauSgRzqVTOwdfy17KDbw-1d9omPw'). filter(ee.Filter.inList("Country", ["Mozambique"])); But I'm not being able to do that... Mozambique is huge,I don't want to spend time sort tile by tile :)
    – Ana Leite
    Jul 23, 2017 at 11:30
  • @Tyler Erickson- I am having the same problem where I want the least cloud image from the Sentinel 2 image collection across entire ROI, that has multiple tiles. Were you able to find a solution?
    – tg110
    Feb 15, 2019 at 18:24

Your Answer

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

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