[GIS] Combine checkbox with splitpanel widget in Google Earth Engine

google-earth-engine

I am trying to combine the checkbox widget with splitpanel widget so that everytime the checkbox is checked, GEE will split into two panels, and when unchecked, GEE will go back to one panel. However, it seems that it can split into two panels, but when I try to uncheck to switch back to one panel, there is the error:
Widgets can only be added to one panel at a time.

Is there anyway to make this work?

Here is my code:

var checkbox = ui.Checkbox('Show SRTM layer', false);

checkbox.onChange(function(checked) {
  // Shows or hides the first map layer based on the checkbox's value.
  ui.root.widgets().reset([splitPanel]);
});

Map.addLayer(ee.Image('CGIAR/SRTM90_V4'));
print(checkbox);

var image = ee.Image('LANDSAT/LC08/C01/T1_RT_TOA/LC08_045033_20171011');
// Make another map and add a color-NIR composite to it.
var linkedMap = ui.Map();
linkedMap.addLayer(image, {bands: ['B5', 'B4', 'B3'], max: 0.3}, 'color-NIR');
// Add a thermal image to the map.
linkedMap.addLayer(image, {
  bands: ['B11'],
  min: 290,
  max: 310,
  palette: ['gray', 'white', 'yellow', 'red']
}, 'Thermal');

// Link the default Map to the other map.
var linker = ui.Map.Linker([ui.root.widgets().get(0), linkedMap]);

var splitPanel = ui.SplitPanel({
  firstPanel: linker.get(0),
  secondPanel: linker.get(1),
  orientation: 'horizontal',
  wipe: false,
});

Best Answer

It would be possible to do it the way you're trying, using the same map as the left side and the un-split view, but it will be a bit simpler to avoid trying to give a widget two different parents (which will never work) if you create three separate ui.Maps: one for the unsplit view and one for each side of the split. Since you can link all three this still works as you want except for some extra tile loading (unless you want to have the layer toggles in sync between the two versions).

// Create and link maps
var singleMap = ui.root.widgets().get(0);
var leftMap = ui.Map();
var rightMap = ui.Map();
var linker = ui.Map.Linker([singleMap, leftMap, rightMap]);

var splitPanel = ui.SplitPanel({
  firstPanel: leftMap,
  secondPanel: rightMap,
  orientation: 'horizontal',
  wipe: false,
});

var checkbox = ui.Checkbox('Show SRTM layer', false);
checkbox.onChange(function(checked) {
  if (checked) {
    ui.root.widgets().reset([splitPanel]);
  } else {
    ui.root.widgets().reset([singleMap]);
  }
});
print(checkbox);

// Configure maps
singleMap.addLayer(ee.Image('CGIAR/SRTM90_V4'));
leftMap.addLayer(ee.Image('CGIAR/SRTM90_V4'));

var image = ee.Image('LANDSAT/LC08/C01/T1_RT_TOA/LC08_045033_20171011');
// Make another map and add a color-NIR composite to it.
rightMap.addLayer(image, {bands: ['B5', 'B4', 'B3'], max: 0.3}, 'color-NIR');
// Add a thermal image to the map.
rightMap.addLayer(image, {
  bands: ['B11'],
  min: 290,
  max: 310,
  palette: ['gray', 'white', 'yellow', 'red']
}, 'Thermal');

https://code.earthengine.google.com/99b4af724b717a8cfc9cd92bb81186ec


I tried making a version that uses the same map for the left and unsplit views. In order to do this, we have to replace the left panel in the SplitPanel with a dummy panel to remove the map from it so the map can be used by itself.

Unfortunately, there seems to be a layout glitch when the map is restored to the root, so that it is no longer the width of the window but very narrow, so it isn't actually usable. I will pass on this information to the Earth Engine Code Editor developers and hopefully this script will start working.

var singleOrLeftMap = ui.root.widgets().get(0);
var rightMap = ui.Map();
var linker = ui.Map.Linker([singleOrLeftMap, rightMap]);

var splitPanel = ui.SplitPanel({
  firstPanel: ui.Panel(),
  secondPanel: rightMap,
  orientation: 'horizontal',
  wipe: false,
});
var checkbox = ui.Checkbox('Show SRTM layer', false);
checkbox.onChange(function(checked) {
  if (checked) {
    ui.root.widgets().reset([splitPanel]);
    splitPanel.setFirstPanel(singleOrLeftMap);
  } else {
    // Replace the split's left panel so that the map,
    // which used to be the left panel, can be reused elsewhere
    splitPanel.setFirstPanel(ui.Panel());
    ui.root.widgets().reset([singleOrLeftMap]);
  }
});
print(checkbox);

https://code.earthengine.google.com/d32319aea94e893d68be67d5e5764aae

Related Question