Search code examples
google-earth-engine

How can I set different visualization parameters in Google Earth Engine in a foreach


I want to set different visualization parameters for the four different bands I am including in the map in the script below. I tried to request that by using a list with different viz parameters like this:

var visParams = [{"bands":["treecover2000"],"min":0,"max":100,"gamma":1},
                 {"bands":["loss"],"min":0,"max":50,"gamma":1},
                 {"bands":["gain"],"min":0,"max":1000,"gamma":1},
                 {"bands":["lossyear"],"min":0,"max":1,"gamma":1}];

But then I had to call them using get and it didn't work well as it is structured.

Code example here:

var image = ee.Image("UMD/hansen/global_forest_change_2021_v1_9");

// Map names
var MAP_PARAMS = {
  'Img 1': ['treecover2000'],
  'Img 2': ['loss'],
  'Img 3': ['gain'],
  'Img 4': ['lossyear']
};


// Shared visualization parameters for the images - but I want them to be specific to each band
function getVisualization(bands) {
  return {min: 0, max: 10000, bands: bands, palette: ['yellow', 'green']};
}


// Create a map for each visualization option.
var maps = [];
Object.keys(MAP_PARAMS).forEach(function(name) {
  var map = ui.Map();
  map.add(ui.Label(name,{backgroundColor: '#bbffec', color:'#19404c'}));
  map.addLayer(image, getVisualization(MAP_PARAMS[name]), name);
  map.setControlVisibility(false);
  maps.push(map);
});

var linker = ui.Map.Linker(maps);

// Enable zooming on the top-left map.
maps[0].setControlVisibility({zoomControl: true});

// Show the scale (e.g. '500m') on the bottom-right map.
maps[3].setControlVisibility({scaleControl: true});

// Create a grid of maps.
var mapGrid = ui.Panel(
    [
      ui.Panel([maps[0], maps[1]], null, {stretch: 'both'}),
      ui.Panel([maps[2], maps[3]], null, {stretch: 'both'})
    ],
    ui.Panel.Layout.Flow('horizontal'), {stretch: 'both'});

// Center the map at an interesting spot in Greece. All
// other maps will align themselves to this parent map.
maps[0].setCenter(-46.122, -12.726, 5);

// Add the maps and title to the ui.root.
ui.root.widgets().reset([mapGrid])
ui.root.setLayout(ui.Panel.Layout.Flow('horizontal'));

Solution

  • It was actually way easier than I thought. By adding the parameters to the MAP_PARAMS I could request the visualization parameters from there instead of using the function getVisualization

    var MAP_PARAMS = {
      'Img1': ['treecover2000',{"bands":"treecover2000","min":0,"max":1,"palette":['e3ebe8','ff6a5f']}],
      'Img2': ['loss',{"bands":"loss","min":0,"max":1,"palette":['e3ebe8', 'fd66cc']}],
      'Img3': ['gain',{"bands":"gain","min":0,"max":1,"palette":['e3ebe8', 'e9ef00']}],
      'Img4': ['lossyear',{"bands":"lossyear","min":0,"max":5000,"palette":['e3ebe8','fc978f','f6665c','ba4e49','421d03']}]
    };
    

    and then I could request it in the maps by requesting intead of

      map.addLayer(image, getVisualization(MAP_PARAMS[name]), name);
    

    this way:

     map.addLayer(image, (MAP_PARAMS[name][0],MAP_PARAMS[name][1]), name);
    

    if it is the smartest decision I don't know, but it works just fine