Google Earth Engine – How to Update Layers on Widget Selection?

google-earth-enginegoogle-earth-engine-javascript-apiuser interface

I'm trying to get a layer selector widget working. The first layer that loads appear to load fine, but when another layer is selected, the map doesn't clear first. In other words, it appears as though all the layers persist.

var S2 = ee.ImageCollection("COPERNICUS/S2"), 
    S2c = ee.ImageCollection('COPERNICUS/S2_CLOUD_PROBABILITY'),
    S2Sr = ee.ImageCollection('COPERNICUS/S2_SR');

var AOI = ee.Geometry.Point(-122.269, 45.701);

// 3 image collections
S2 = S2.filterBounds(AOI);
S2c = S2c.filterBounds(AOI);
S2Sr = S2Sr.filterBounds(AOI);

//Map ui setup

var myMap = ui.Map();

var S2_lyr = ui.Map.Layer(S2.first(), {"opacity":1,"bands":["B1"],"gamma":1}, 'image 1: S2');
var S2c_lyr = ui.Map.Layer(S2c.first(), {"opacity":1,"bands":["probability"],"gamma":1}, 'image 2: S2c');
var S2Sr_lyr = ui.Map.Layer(S2Sr.first(), {"opacity":1,"bands":["B1"],"gamma":1}, 'image 3: S2_Sr');

// image dictionary
var images = {
  'image 1: S2': getImage(0),
  'image 2: S2c': getImage(1),
  'image 3: S2Sr': getImage(2)
};

//image selection function
function getImage(number) {
  number = ee.Number(number)
  var collection = ee.ImageCollection([  // collection of images
  S2.first(), 
  S2c.first(), 
  S2Sr.first() 
  ]) 
  var listOfImages = collection.toList(collection.size()); // list of images
  var image = ee.Image(listOfImages.get(number)); // get individual image
  return image;
}

var alllayers = Map.layers();

alllayers
.add(S2_lyr)
.add(S2c_lyr)
.add(S2Sr_lyr);

myMap.setControlVisibility(false);
var leftSelector = addLayerSelector(Map, 0, 'top-left');


// Add a layer selection widget to the map
function addLayerSelector(mapToChange, defaultValue, position) {
  var label = ui.Label('Select Image Masking Method');
  // This function changes the given map to show the selected image.
  function updateMap(selection) {
    mapToChange.layers().remove()
    mapToChange.layers().set(0, ui.Map.Layer(images[selection]));
  }

  // Configure a selection dropdown to allow the user to choose between images,
  // and set the map to remove the previous image when a user makes a selection.
  var select = ui.Select({items: Object.keys(images), onChange: updateMap});
  select.setValue(Object.keys(images)[defaultValue], true);

  var controlPanel =
      ui.Panel({widgets: [label, select], style: {position: position}});

  mapToChange.add(controlPanel);
}

myMap.centerObject(S2Sr.first(), 10);


This is based on a similar question which was answered but which I cannot successfully reproduce:

Google Earth Engine – Selected layers not updating

Best Answer

The problem is probably here:

mapToChange.layers().remove()

Map.layers() returns a ui.data.ActiveList (check the documentation). This ActiveList has a remove() method, which takes an element and removes it from the list. It does not clear the list. If you want to clear it, you should use .reset() method, with no arguments.

Hope this helps! And welcome to StackExchange ! :)


For future questions, it is recommended to reduce the code to the minimum working example. In other words, try to not post your original code, but to make a draft where just the problem happens. In this case, you could have probably removed all the parts related to getImage(), replacing the dictionary with a static one.