Google Earth Engine – Printing a List Element from a For Loop

google-earth-engine

I would like to generate a collection of the 3 least cloudy granules for each Sentinel-2 tile within the bounds of a particular shapefile. It seems that this will require a function that iterates on each tile separately rather just using .sort, "Cloudy_Pixel_Percentage", and .mosaic to create a single mosaic of the least cloudy granule for each tile. So, I have created a script that identifies the distinct tiles:

    // Load the ROI table
    var table = 
    ee.FeatureCollection("users/theronmb/TTCS_Area_Crop_for_Sentinel-2");

    // Find the MGRS_TILES that overlap with the ROI for the time period 
    // of interest
    var collection = ee.ImageCollection("COPERNICUS/S2")
      .filter(ee.Filter.calendarRange(3,6,'month'))
      .filter(ee.Filter.calendarRange(2017,2017,'year'))
      .filterBounds(table)
      .distinct('MGRS_TILE')
    ;

    print(collection);

    // Get a specific metadata property.
    var tiles = ee.List(collection.aggregate_array('MGRS_TILE'));

From there, I was thinking to use a for loop to create the collections I need, iterating on the list of distinct tiles. Unfortunately, this simple loop I am using for testing does not seem to do anything (or even generate an error). Where am I going wrong?

    print(tiles.get(0)); // This works
    print(tiles.size()); // This works

    // Test iterating on the specific metadata property (does not work)
    for (var i = 0; i < tiles.size(); i = i + 1) {
    print(tiles.get(i));
    }

Best Answer

So, yes, best to use map() instead of loops in Earth Engine. With that guidance, I was able to develop the following script to optionally create either the 1st, 2nd, or 3rd least cloudy image collection for a given set of Sentinel-2 tiles.

// Load the ROI table
var table = ee.FeatureCollection("users/theronmb/TTCS_Area_Crop_for_Sentinel-2");

// Find the MGRS_TILES that overlap with the ROI for the time period of interest
var collection = ee.ImageCollection("COPERNICUS/S2")
  .filter(ee.Filter.calendarRange(3,6,'month'))
  .filter(ee.Filter.calendarRange(2017,2017,'year'))
  .filterBounds(table)
  .distinct('MGRS_TILE')
;

// Get the unique MGRS tile list
var tiles = ee.List(collection.aggregate_array('MGRS_TILE'));

/* Function to iterate through the image collection to pull out the nth 
least cloudy granuales for each target tile.*/
var fun = function(tile) {
  var S2 = ee.ImageCollection("COPERNICUS/S2")
    .filter(ee.Filter.calendarRange(3,6,'month'))
    .filter(ee.Filter.calendarRange(2017,2017,'year'))
    .filterMetadata('MGRS_TILE', 'equals', tile)
    .limit(3, 'CLOUDY_PIXEL_PERCENTAGE', true);
  var mylist= S2.toList(3);
  var s2 = ee.Image(mylist.get(0)); //change to 1 or 2 for 2nd or 3rd least cloudy
  return s2;
};

// Apply function to tile list
var filtered = tiles.map(fun);

// Create image collection from image list
var filtered = ee.ImageCollection(filtered);

print(filtered)