[GIS] Tile error Google Earth Engine “Some bands might require explicit casts”

google-earth-enginetilestime seriestypecast

I'm getting this error when trying to map the result after calculating the seasonal median NDVI images for a time series with 7 different landsat tiles in Google Earth Engine:

enter image description here
Link to the code : https://code.earthengine.google.com/5ec4decebe224dcb8de73ed8c632c55f

Here is the code I'm using (sorry for the missing semi-colons):

var AOI_ZIM = ee.Geometry.Polygon(
     [[[25.02396766047741,-17.741728052677256],
     [26.56205359797741,-20.059388167694156],
     [28.28690711360241,-20.22441903223353],
     [28.42972937922741,-18.149348821775746],
     [25.02396766047741,-17.741728052677256]
     ]])    
//Image Collection//
var surfaceReflectanceL5 = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR').select(['B3', 'B4', 'pixel_qa'])
  .filterDate('1990-01-01', '2002-12-31')
  .filterBounds(AOI_ZIM)
var surfaceReflectanceL7 = ee.ImageCollection('LANDSAT/LE07/C01/T1_SR').select(['B3', 'B4', 'pixel_qa'])
  .filterDate('1990-01-01', '2002-12-31')
  .filterBounds(AOI_ZIM)
  
var combined_L5L7 = surfaceReflectanceL5.merge(surfaceReflectanceL7)
var filtered_L5L7 = combined_L5L7.filter(ee.Filter.or(ee.Filter.and(ee.Filter.eq('WRS_PATH', 173), ee.Filter.eq('WRS_ROW', 74)), ee.Filter.and(ee.Filter.eq('WRS_PATH', 174), ee.Filter.eq('WRS_ROW', 72))).not())

//Mask clouds and shadows with the QA band//
var cloudMask_L5L7 = function(image) {
  var qa = image.select('pixel_qa') 
  var R_NIR = image.select(['B3', 'B4'])
  var qa_thresholds = qa.bitwiseAnd(1 << 5)
          .and(qa.bitwiseAnd(1 << 6))
          .or(qa.bitwiseAnd(1 << 3))
  return R_NIR.updateMask(qa_thresholds.not())
}
var masked_L5L7 = filtered_L5L7.map(cloudMask_L5L7)

//Compute NDVI collection//
var calculateNDVI = function(scene) {
  var dateString = ee.Date(scene.get('system:time_start')).format('yyyyMMdd').cat('_').cat(ee.String(ee.Number(scene.get('WRS_PATH')).int())).cat(ee.String(ee.Number(scene.get('WRS_ROW')).int())).cat('_ndvi')
  var NDVI_band = scene.normalizedDifference(['B4', 'B3']).multiply(10000).int16()
  var add_band = scene.addBands(NDVI_band)
  return add_band.select('nd').rename(dateString)
}
var NDVIcollection = masked_L5L7.map(calculateNDVI)

//Calculate the median NDVI per season//
var years = ee.List.sequence(1990, 2002) //years
var list_path = ee.List.sequence(171, 173) //tile path ID
var list_row = ee.List.sequence(72, 74) //tile row ID

var stackList = function(collection) {
  var first = ee.Image(collection.get(0)).select([])
  var appendBands = function(image, previous) {
    return ee.Image(previous).addBands(image)
  }
  return ee.Image(collection.iterate(appendBands, first))
}

//Calculate median images
var median_NDVI = ee.ImageCollection.fromImages(years.map(function(y) {
  //filter by season
  var inSeason = NDVIcollection.filter(ee.Filter.calendarRange(y,y,'year')).filter(ee.Filter.calendarRange(10,4,'month'))
  var offSeason = NDVIcollection.filter(ee.Filter.calendarRange(y,y,'year')).filter(ee.Filter.calendarRange(5,9,'month'))
  
  //filter the in-season images by tile
  var path_list_in = function(path) {
    var filter_row_in = list_row.map(function(row) {
      var filter_tile_in = inSeason.filter(ee.Filter.and(ee.Filter.eq('WRS_PATH', path),ee.Filter.eq('WRS_ROW', row)))
      var inSeason_string = ee.String(ee.Number(y).int()).cat('_').cat(ee.String(ee.Number(path).int())).cat(ee.String(ee.Number(row).int())).cat('_inSeason')
      return filter_tile_in.median().rename(inSeason_string)
    })
    return filter_row_in
  }
  var medians_inSeason = list_path.map(path_list_in).flatten()
  var stack_inSeason = stackList(medians_inSeason)
  
  //filter the off-season images by tile
    var path_list_off = function(path) {
    var filter_row_off = list_row.map(function(row) {
      var filter_tile_off = offSeason.filter(ee.Filter.and(ee.Filter.eq('WRS_PATH', path),ee.Filter.eq('WRS_ROW', row)))
      var offSeason_string = ee.String(ee.Number(y).int()).cat('_').cat(ee.String(ee.Number(path).int())).cat(ee.String(ee.Number(row).int())).cat('_offSeason')
      return filter_tile_off.median().rename(offSeason_string)
    })
    return filter_row_off
  }
  var medians_offSeason = list_path.map(path_list_off).flatten()
  var stack_offSeason = stackList(medians_offSeason)
  
  return stack_inSeason.addBands(stack_offSeason).int16()
})) //returns an image collection with 13 images (elements), one per year, with 14 bands (1 band per season (x2) and per tile (x7))

var listMedians_coll = median_NDVI.toList(median_NDVI.size())
var Median_image = ee.Image(listMedians_coll.get(0))
Map.addLayer(Median_image, {bands: '1990_17173_inSeason', min:0, max:10000}, "Median")

Data types are consistent between all bands in the new image collection median_NDVI (signed int16) and between the original NDVIcollection and the new image collection, so I guess the problem must come from the fact that median_NDVI collection images have bands corresponding to different tiles, and therefore not spatially consistent.

What is the proper way to calculate these images?

Best Answer

It's the name that's giving you grief. Try rename()ing with a consistent string.

Related Question