Google Earth Engine – How to Mosaic Landsat Image Collection on Google Earth Engine

google-earth-engine

My research area needs multiple landsat images(About 15 images), so I want to mosaic images where they are in the same path first (they have the same acquisition date). Howerver, I only know the mosaic operation for the specified date

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

So how do I get the date of each image in the image collection? Or is there any better iterative way to mosaic the same date images?

Best Answer

I typically iterate over the dates you need your mosaic for:

var startDate = '2022-05-01'
var endDate = '2022-06-01'

var collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2')
  
var numberOfDays = ee.Date(endDate).difference(ee.Date(startDate), 'days')
var dayOffsets = ee.List.sequence(0, numberOfDays.subtract(1))
var dailyMosaics = ee.ImageCollection(dayOffsets
  .map(function (dayOffset) {
    var date = ee.Date(startDate).advance(ee.Number(dayOffset), 'days')
    var images = collection.filterDate(date.getRange('day'))
    return ee.ImageCollection(images)
      .map(preProcess)
      .mosaic()
      .set('system:time_start', date.millis())
  })
)

Map.addLayer(dailyMosaics.first(), {bands: 'SR_B4,SR_B3,SR_B2', min: 0, max: 3000, gamma: 1.5})


function preProcess(image) {
  var qa = image.select('QA_PIXEL')
  var cloudShadow = bitwiseExtract(qa, 4)
  var snow = bitwiseExtract(qa, 5)
  var cloud = bitwiseExtract(qa, 6).not()
  return image
    .select('SR_B.*')
    .multiply(2.75e-05)
    .add(-0.2)
    .multiply(10000)
    .int16()
    .updateMask(cloudShadow.not().and(snow.not()).and(cloud.not()))
}

function bitwiseExtract(value, fromBit, toBit) {
  if (toBit === undefined)
    toBit = fromBit
  var maskSize = ee.Number(1).add(toBit).subtract(fromBit)
  var mask = ee.Number(1).leftShift(maskSize).subtract(1)
  return value.rightShift(fromBit).bitwiseAnd(mask)
}

https://code.earthengine.google.com/e08db00830e500decf7b55ded7642864

Alternatively, you could use a join:

var dates = ee.FeatureCollection(dayOffsets
  .map(function (dayOffset) {
      var date = ee.Date(startDate).advance(ee.Number(dayOffset), 'days')
        .advance(12, 'hours')
      return ee.Feature(null, {'system:time_start': date.millis()})
  })
)
var twelveHoursInMillis = 12 * 60 * 60 * 1000
var dailyMosaics = ee.ImageCollection(
  ee.Join.saveAll('images').apply({
    primary: dates,
    secondary: collection,
    condition: ee.Filter.maxDifference({
      difference: twelveHoursInMillis,
      leftField: 'system:time_start',
      rightField: 'system:time_start'
    })
  })
).map(function (feature) {
  return ee.ImageCollection(ee.List(feature.get('images')))
    .map(preProcess)
    .mosaic()
    .set('system:time_start', feature.get('system:time_start'))
})

https://code.earthengine.google.com/411502413e90e52f36e356461e738ffc