3

This question is a follow-up to the excellent answer of Rodrigo E. Principe here: Mosaicking a Image Collection by Date (day) in Google Earth Engine

I am trying to apply the suggested code to gather a time series of mosaics covering the state of Bavaria. But when I display the first element of the resulting collection, I see a big coverage gap. Here's the code: https://code.earthengine.google.com/01c7ca48b7710b7ddddaa564ecc12331

Can somebody explain why this happens? And is there a way to avoid this, ideally without destroying the temporal resolution? If not, I'd also be good with a solution that combines images from a time span to fill the gap (even though the time span should be as small as possible).

1 Answer 1

6

At day one (2018-01-01) you have 4 images that the code is mosaicking into one. When you add the first image of the resulting collection using Map.addLayer(newcol.first()), you get the mosaic for that day (day 1). The gap is because that day there were no images in that area. You can check it

var tools = require('users/fitoprincipe/geetools:tools')

//Load Bavarian state borders from assets
var bavariaBorders = ee.FeatureCollection("users/schmittm/bavariaBorders");

var start = ee.Date('2018-01-01');
var finish = ee.Date('2018-01-02');

// Load Sentinel-1 Imagery of standard acquisition mode (IW, VV/VH)
var s1_collection = ee.ImageCollection('COPERNICUS/S1_GRD')
    .filterDate(start, finish)
    .filterBounds(bavariaBorders)
    .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV'))
    .filter(ee.Filter.eq('instrumentMode', 'IW'));

print(s1_collection)
tools.map.addImageCollection(s1_collection)

You can check from day 2 to 3 and see that there are images for that period, just in the gap. You can also check the resulting mosaic for day 2 replacing newcol.first() at the end of your script:

// Map.addLayer(newcol.first())
Map.addLayer(ee.Image(newcol.toList(newcol.size()).get(1)))

If you want a mosaic to cover the whole area you should make the temporal resolution a bit bigger, at least 2 days (3 best).

I improved the code so you can "play" with temporal resolution

//Load Bavarian state borders from assets
var bavariaBorders = ee.FeatureCollection("users/schmittm/bavariaBorders");

var start = ee.Date('2018-01-01');
var finish = ee.Date('2018-12-31');

// Load Sentinel-1 Imagery of standard acquisition mode (IW, VV/VH)
var s1_collection = ee.ImageCollection('COPERNICUS/S1_GRD')
    .filterDate(start, finish)
    .filterBounds(bavariaBorders)
    .filter(ee.Filter.listContains('transmitterReceiverPolarisation', 'VV'))
    .filter(ee.Filter.eq('instrumentMode', 'IW'));

print(s1_collection)

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

print(diff)

var temporalResolution = 3  // days

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

print(range)

// 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 = s1_collection.filterDate(date, date.advance(temporalResolution, 'day'))

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

  // 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)

var inspectImage = 1  // what image do you want to see?

Map.addLayer(ee.Image(newcol.toList(newcol.size()).get(inspectImage)))

If you want to add a date band replace day_mosaics function for this:

var day_mosaics = function(date, newlist) {
  // Cast
  date = ee.Date(date)
  newlist = ee.List(newlist)

  // get date as YEARMONTHDAY. For example, for January 8th 2010
  // would be: 20100108
  var date_formatted = ee.Number.parse(date.format('YYYYMMdd'))
  // make date band as an 32 bit unsigned integer and rename it as 'date'
  var dateband = ee.Image.constant(date_formatted).toUint32()
                         .rename('date')

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

  // Make the mosaic
  var image = ee.Image(filtered.mosaic().clip(bavariaBorders))
                .addBands(dateband)  // add date band

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

Although I don't like it much because date is an unsigned 32 bit integer band, which may be incompatible for exporting with the other bands. To export it, you should cast the rest to the bands to be uint32 as well, and that could make the file bigger.

Here is the link for the last approach: https://code.earthengine.google.com/3bdaa594c43a5759dae7d1b00c674b27

2
  • Is there any possibility to store the acquisition dates in the new collection?
    – Michael
    Commented Dec 28, 2018 at 20:30
  • 1
    Hi @Michael, I have just update the answer to match your needs of a date band Commented Jan 23, 2019 at 2:14

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.