0

Say I have 9 data layers, A1, A2, A3, B1, B2, B3, C1, C2, C3. I want to have two sections on a ui.Panel with 3 ui.Checkboxes each for the user to select either A, B, C and then 1, 2, 3. Then they hit an "apply" button that runs a function to only display the layer(s) that correspond to the checked boxes. If they check multiple boxes in a section, the app will select and display multiple layers.

I was thinking that you could do it with an ee.Algorithms.if() statement for each ui.Checkbox in the apply function combined with filter() to remove the layers that are not required, but I can't seem to figure out how to use '&' in ee.Algorithms.if().

The other option might be to use some sort of if/else statement that creates a variable and for every option, it adds a string (ex. if the user checks A, then it adds 'A' to the bname, and if they check 1, then it does bname + '1'). However, I also have no idea how I would do this.

If anyone has a hunch, let me know how it could be done!

1 Answer 1

1

The best way to approach UI control problems is often to do them in “plain” JavaScript — not using any Earth Engine “Algorithms” at all, but JavaScript arrays and JavaScript string concatenation. Here's code which should do what you want. I've included comments to explain each part.

// Define the options we want to offer.
var axis1Options = ['A', 'B', 'C'];
var axis2Options = ['1', '2', '3'];

// Set up the basic UI layout.
ui.root.clear();
var panel = ui.Panel({style: {width: '250px'}});
var map = ui.Map();
ui.root.add(panel).add(map);
map.setCenter(120.1685, 31.2175, 8);

// Create the widgets for the checkbox groups and the apply button.
var panelAxis1 = ui.Panel({layout: ui.Panel.Layout.flow('horizontal')});
panel.add(panelAxis1);
var panelAxis2 = ui.Panel({layout: ui.Panel.Layout.flow('horizontal')});
panel.add(panelAxis2);
var applyButton = ui.Button('Apply');
panel.add(applyButton);

// Map over the array of options to make an array of checkboxes.
// This is a JavaScript *CLIENT-SIDE* map(), so it's allowed to do
// things like add()ing widgets.
//
// The result of this is an array (list) of objects (dictionaries):
// [{'name': 'A', 'checkbox': ui.Checkbox('A')}, ...] 
var axis1Checkboxes = axis1Options.map(function (name) {
  var checkbox = ui.Checkbox(name);            // Make the checkbox,
  panelAxis1.add(checkbox);                    // put it on screen,
  return {'checkbox': checkbox, 'name': name}; // and remember it for later
});
var axis2Checkboxes = axis2Options.map(function (name) {
  var checkbox = ui.Checkbox(name);
  panelAxis2.add(checkbox);
  return {'checkbox': checkbox, 'name': name};
});

// Define the “Apply” button's behavior.
applyButton.onClick(function () {
  // Remove all existing layers
  map.layers().reset();
  // Loop over the first set of options.
  axis1Checkboxes.forEach(function (a1) {
    // Now, the variable a1 is one of the elements of axis1Checkboxes,
    // which has a .name and a .checkbox.
    // Proceed only if the checkbox is checked.
    if (a1.checkbox.getValue()) {
      // For this one of the first set of options, we try each of the second.
      axis2Checkboxes.forEach(function (a2) {
        if (a2.checkbox.getValue()) {
          // This code runs for each pair of checked boxes.

          // Construct the band name.
          var bandName = 'my_band_' + a1.name + a2.name;
          
          // Add a layer.
          // When using this for real you'd use something like
          //     myMultiBandImage.select(bandName)
          // for the image value.
          map.addLayer(ee.Image.constant(1), {}, bandName);
        }
      });
    }
  });
});

https://code.earthengine.google.com/2f3fcc8b4db73a6c6e4cc356c2ef110b

3
  • Hey Kevin, Thanks! Everything here works great when I implemented it to my code except for one small thing, I noticed that when you check two options in one axis, it only adds the second selection to the map. I tried implementing it to my code and it only adds one band. Maybe you could check out my code (your section is lines 60-139), the part where I add the band is line 121-132: code.earthengine.google.com/319941c3710ec36da531aab332d88499 Commented Feb 6, 2022 at 18:16
  • This file is slightly updated: code.earthengine.google.com/ebb0e7508596cf4d517c4f2513aa8ded Commented Feb 6, 2022 at 18:22
  • @ags You wrote c.map.layers().set(0, layer); which replaces the first layer every time it runs. Use c.map.layers().add(layer); instead. (Another problem is that m.imgInfo doesn't have a band for every combination, and the code hits an error if the combination doesn't exist, so you'll need to check if it exists if you want all the non-error cases to appear. But that problem at least produces an error message when it happens.)
    – Kevin Reid
    Commented Feb 6, 2022 at 19:08

Not the answer you're looking for? Browse other questions tagged or ask your own question.