0

I'm following the answer on Filter out "incomplete" Sentinel-2 images in Earth Engine to make daily mosaics of Sentinel 2 images.

However, I was expecting that the resulting imageCollection (daily) would have less images than the original filtered collection (s2), as these are mosaicked together by date and orbit, but the number of images in each collection is the same.



//ee.Geometry.Rectangle(minLng, minLat, maxLng, maxLat) ie xmin, ymin, xmax, ymax
var aoi = ee.Geometry.Rectangle(-7.50,47.00,6.50,54.00); // region of all sites in Europe

var s2 = ee.ImageCollection('COPERNICUS/S2_SR')
  .filterBounds(aoi)
  .filterDate('2019-01-01', '2019-01-05') // // %Y-%m-%d
  .map(function (image) {
    return image
      .set('date', image.date().format('yyyy-MM-dd'));
  });

print(s2.size());
print(s2.first(), 'first S2 image');

var daily = ee.ImageCollection(
    ee.Join.saveAll('images').apply({
      primary: s2, 
      secondary: s2, 
      condition: ee.Filter.and(
        ee.Filter.equals({
          leftField: 'date',
          rightField: 'date'
        }),
        ee.Filter.equals({
          leftField: 'SPACECRAFT_NAME',
          rightField: 'SPACECRAFT_NAME'
        }),
        ee.Filter.equals({
          leftField: 'SENSING_ORBIT_NUMBER',
          rightField: 'SENSING_ORBIT_NUMBER'
        })
      )
    })
  )
  .map(function (image) {
    return ee.ImageCollection(ee.List(image.get('images')))
      .mosaic()
      .set('system:time_start', ee.Date(image.get('date')).millis());
  });

// print(daily);
print(daily.size());

var listOfImages = daily.toList(daily.size());
// print(listOfImages);
var img1 = ee.Image(listOfImages.get(1)); // second image
var img2 = ee.Image(listOfImages.get(100));
var img3 = ee.Image(listOfImages.get(200));

print(daily.first(), "first image in daily");
print(img2, "second image in daily");


Map.centerObject(aoi, 6); 

Map.addLayer(daily.first(), {bands: 'B4,B3,B2', min: 300, max: 3000});
Map.addLayer(img1, {bands: 'B4,B3,B2', min: 300, max: 3000});
Map.addLayer(img2, {bands: 'B4,B3,B2', min: 300, max: 3000});
Map.addLayer(img3, {bands: 'B4,B3,B2', min: 300, max: 3000});

Map.addLayer(aoi, {}, 'aoi', true, 0.4);

When I display the first, and second image, for example, they appear the same, but with slightly different start times in the new field "time_start". Images 101 and 201 are different - I was expecting to get a smaller number of such images in the collection to process further.

Is this possible?


I can see now that the join adds a property images to each image in the collection with the matching images. Then the mosaic part mosaics each image with those matches in images, therefore producing multiple identical mosaics for each group of matches.

Either I could identify the unique lists of matches from each list in images, or alternatively, I could get a list of unique dates, spacecraft names and orbits from the imageCollection s2, and then filter by these, and mosaic.

Any suggestions as to which is best and some pointers towards the code?

1
  • Is it important, that it is mosaiced by orbit AND date? Or is it just important for you that it's mosaiced by date?
    – JonasV
    Jun 3, 2020 at 9:40

1 Answer 1

0

I found a way to do this, using the second answer here, mosaic by date, but expanded it to include orbit and spacecraft name.

The function mosaicBy first gets all dates, spacecraft names and orbit numbers, then gets the unique combination of these, filters the image collection for each unique combination and then mosaics those images.



//ee.Geometry.Rectangle(minLng, minLat, maxLng, maxLat) ie xmin, ymin, xmax, ymax
var aoi = ee.Geometry.Rectangle(-7.50,47.00,6.50,54.00); 

var s2 = ee.ImageCollection('COPERNICUS/S2_SR')
  .filterBounds(aoi)
  .filterDate('2019-01-01', '2019-01-05'); // // %Y-%m-%d

print(s2.first(), 'first image s2');


// Function to mosaic by date, orbit, etc
function mosaicBy(imcol){
  // imcol: An image collection
  // returns: An image collection

  // return the collection as a list of images (not an image collection)
  var imlist = imcol.toList(imcol.size());

  // Get all the dates as list
  var all_dates = imlist.map(function(im){
    return ee.Image(im).date().format("YYYY-MM-dd");
  });

  // get all orbits as list
  var all_orbits = imlist.map(function(im){
    return ee.Image(im).get('SENSING_ORBIT_NUMBER');
  });

  // get all spacecraft names as list
  var all_spNames = imlist.map(function(im){
    return ee.Image(im).get('SPACECRAFT_NAME');
  });

  // this puts dates, orbits and names into a nested list
  var concat_all = all_dates.zip(all_orbits).zip(all_spNames);

  // here we unnest the list with flatten, and then concatenate the list elements with " "
  concat_all = concat_all.map(function(el){
    return ee.List(el).flatten().join(" ");
    });

  // here, just get distinct combintations of date, orbit and name
  var concat_unique = concat_all.distinct();

  // mosaic
  var mosaic_imlist = concat_unique.map(function(d){

    // split into components
    var d1 = ee.String(d).split(" ");

    var date1 = ee.Date(d1.get(0));
    var orbit = ee.Number.parse(d1.get(1)).toInt();
    var spName = ee.String(d1.get(2));

    var im = imcol
      .filterDate(date1, date1.advance(1, "day")) // filter with start date, and then end date, ie date + 1 day
      .filterMetadata('SPACECRAFT_NAME', 'equals', spName)
      .filterMetadata('SENSING_ORBIT_NUMBER','equals', orbit)
      .mosaic();

    return im.set(
        "system:time_start", date1.millis(),
        "system:date", date1.format("YYYY-MM-dd"),
        "system:id", d1);
  });

  return ee.ImageCollection(mosaic_imlist);
}


var s2day = mosaicBy(s2);

print(s2day);

// Make list of image to display each one
var listOfImages = s2day.toList(s2day.size());

Map.centerObject(aoi, 6); 

Map.addLayer(s2day.first(), {bands: 'B4,B3,B2', min: 300, max: 3000});

Map.addLayer(ee.Image(listOfImages.get(1)), {bands: 'B4,B3,B2', min: 300, max: 3000}); // second image
Map.addLayer(ee.Image(listOfImages.get(2)), {bands: 'B4,B3,B2', min: 300, max: 3000}); // third image
Map.addLayer(ee.Image(listOfImages.get(3)), {bands: 'B4,B3,B2', min: 300, max: 3000}); // 4th image

Your Answer

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

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