26

I have an image collection of Sentinel-1 data over 3 years filtered by a region of interest that spans 3-4 tiles, and want to know the best way to mosaic all the images (tiles) that were taken on the same day into one image. Currently filtering by date yields separate images for each separate tile, and I would like to merge all images (tiles) from the same day into one image.

I know how to do this for one specified date with a command like this:

ee.Image(collection.filterDate('2014-10-01','2014-10-02').mosaic())

But I would like to do this iteratively for the whole collection in my ROI over a broad date range and obtain a new image collection of mosaicked images by days in which there is some data.

The collection is created by the following code:

var poly = /* color: #d63000 */ee.Geometry.Polygon(
    [[[-76.0803, 10.8656],
      [-76.0913, 7.7436],
      [-73.1909, 7.7545],
      [-73.3776, 9.4273],
      [-75.2124, 10.9304]]])

var start = ee.Date('2014-10-01');
var finish = ee.Date('2018-03-31');

var collection = ee.ImageCollection('COPERNICUS/S1_GRD')
.filterDate(start, finish)
.filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV'))
.filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH'))
.filter(ee.Filter.eq('instrumentMode', 'IW'))
.filterMetadata('resolution_meters', 'equals', 10)
.filterBounds(poly);

For example, the first three images in this collection are all tiles from the same day (2014-12-02), and I would like to mosaic them together into one 3-tile image for day 2014-12-02, and then do this for the entire collection of over 500 tiles/images to get a collection of day-unique tile mosaics.

0

2 Answers 2

27
var poly = /* color: #d63000 */ee.Geometry.Polygon(
    [[[-76.0803, 10.8656],
      [-76.0913, 7.7436],
      [-73.1909, 7.7545],
      [-73.3776, 9.4273],
      [-75.2124, 10.9304]]])

var start = ee.Date('2014-10-01');
var finish = ee.Date('2018-03-31');

var collection = ee.ImageCollection('COPERNICUS/S1_GRD')
.filterDate(start, finish)
.filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV'))
.filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VH'))
.filter(ee.Filter.eq('instrumentMode', 'IW'))
.filterMetadata('resolution_meters', 'equals', 10)
.filterBounds(poly);

// Difference in days between start and finish
var diff = finish.difference(start, 'day')

// Make a list of all dates
var range = ee.List.sequence(0, diff.subtract(1)).map(function(day){return start.advance(day,'day')})

// Funtion for iteraton over the range of dates
var day_mosaics = function(date, newlist) {
  // Cast
  date = ee.Date(date)
  newlist = ee.List(newlist)

  // Filter collection between date and the next day
  var filtered = collection.filterDate(date, date.advance(1,'day'))

  // Make the mosaic
  var image = ee.Image(filtered.mosaic())

  // Add the mosaic to a list only if the collection has images
  return ee.List(ee.Algorithms.If(filtered.size(), newlist.add(image), newlist))
}

// Iterate over the range to make a new list, and then cast the list to an imagecollection
var newcol = ee.ImageCollection(ee.List(range.iterate(day_mosaics, ee.List([]))))
print(newcol)

https://code.earthengine.google.com/20ad3c83a17ca27b28640fb922819208

0
11

Here is another solution that does not involve iterating through days, but maps through unique dates (after removing seconds, microseconds...) that appear in the image collection. It also adds the image date as the id as @erg asked in a commentary above.

function mosaicByDate(imcol){
  // imcol: An image collection
  // returns: An image collection
  var imlist = imcol.toList(imcol.size())

  var unique_dates = imlist.map(function(im){
    return ee.Image(im).date().format("YYYY-MM-dd")
  }).distinct()

  var mosaic_imlist = unique_dates.map(function(d){
    d = ee.Date(d)

    var im = imcol
      .filterDate(d, d.advance(1, "day"))
      .mosaic()

    return im.set(
        "system:time_start", d.millis(), 
        "system:id", d.format("YYYY-MM-dd"))
  })

  return ee.ImageCollection(mosaic_imlist)
}
3
  • I got an error when I use your code code.earthengine.google.com/bc8f2df523abd4cace352581cd837718 Commented Jan 17, 2020 at 10:40
  • 3
    The function input is an image collection, so you do not need to map it. Then, instead of var ic_m = ic.map(mosaicByDate(ic)), use var ic_m = mosaicByDate(ic). Commented Jan 17, 2020 at 14:16
  • Thanks. This works well. I have a large AOI and would want to make a mosaic covering the large area (3 bands). How can I include the adjacent bands from different dates? WOuld changing .filterDate(d, d.advance(1, "day")) to .filterDate(d.advance(-1, "day"), d.advance(1, "day")) include the data sets of the previous and next day?
    – Philipp R
    Commented Nov 1, 2021 at 8:56

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