[GIS] Google Earth Engine Image (Error) User memory limit exceeded. How to fix it

errorgoogle-earth-engineimage-mosaic

This is the code that has an error. I don´t know how to fix it.

I am trying to get the albedo values of a range of time: 2001-2018 and just of 4 months of each year, September to December.

var col = ee.ImageCollection('MODIS/006/MCD43A3')
                  .filter(ee.Filter.date('2001-01-01', '2018-12-31'))
                  .filterBounds(geometry).select('Albedo_WSA_shortwave'); 
                   
// Functions to stack colletion series into image bands 

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

// Function to generate mask for each Scene.

var getSceneMask = function(scene) {
  var dateString = ee.Date(scene.get('system:time_start')).format('yyyy-MM-dd');
  var mask = scene.select('Albedo_WSA_shortwave').gt(-9999).updateMask(ee.Image(1)); 
  return mask.rename(dateString);};

//Stacked mask for collection
    
var Maskcol = stackCollection(col.map(getSceneMask));

// Generate a datelist for collection 

var datelist = ee.List(Maskcol.bandNames()).map(function(date){return ee.Date(date).format('yyyy-MM-dd')});

// Stack bands and rename by date  

var WSA_stacked = stackCollection(col.select('Albedo_WSA_shortwave')).multiply(0.001).rename(datelist).clip(geometry);


Map.addLayer(WSA_stacked.select(20), {min:0.0, max:400, gamma:2}); 

print(WSA_stacked);
print(datelist);

// Exportar datos //

Export.image.toDrive({
  image: WSA_stacked.clip(geometry),
  description: 'MODIS_WSA_stacked',
  region: geometry,
  folder: 'ejemplo',
  scale: 500,
  crs: 'EPSG:4326'});

Best Answer

Your stackCollection function is an inefficient way to go about combining an image collection's bands into an image, and is not needed. You can use the built-in ImageCollection.toBands(), instead. It produces band names of the form "imageId_bandName" so we'll have to reformat the strings, but the image IDs are already the dates, so we don't have to save the system:time_start separately, just change the text format.

var col = ee.ImageCollection('MODIS/006/MCD43A3')
  .filter(ee.Filter.date('2001-01-01', '2018-12-31'))
  .filterBounds(geometry)
  .select('Albedo_WSA_shortwave'); 

var colStacked = col.toBands();

var datelist = colStacked.bandNames().map(function(bandName){
  // Band names from toBands are of the form "imageId_bandName",
  // so in this case they are the date with underscores followed by "_Albedo_WSA_shortwave".
  // Match the underscores, replace them with dashes, and discard the rest.
  return ee.String(bandName).replace("^(\\d+)_(\\d+)_(\\d+)_.*$", "$1-$2-$3");
});

// Or, instead of using the image IDs we can use system:time_start from the
// collection. This computes the same value; use whichever you like.
var datelist2 =
  ee.List(
    col.reduceColumns(ee.Reducer.toList(), ['system:time_start']).get('list'))
  .map(function(timestamp) {
    return ee.Date(timestamp).format('yyyy-MM-dd');
  });

// Stack bands and rename bands by date  
var WSA_stacked = colStacked
  .multiply(0.001)
  .rename(datelist)
  .clip(geometry);

https://code.earthengine.google.com/0bfc7bc140517ffd157e8e9862f23e42

Note that I left out your getSceneMask because the only part of it that was actually used in your script was the band names. If you intended to mask the images, I recommend doing it in a .map() rather than building a separate collection and image and list, i.e. change col rather than the later steps.

I also removed several redundant .select()s — the one in the definition of col is all that is necessary.

Related Question