1

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,
});
0

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

7
  • Hi Kevin, thanks so much for your answer! I actually want to have extra tile loading and want the maps to go in sync... I am wondering if there is an unsplit function available after I set the root to split view? My full program is at code.earthengine.google.com/0f9fa7e73412fa6e425fa4c06119dd66 and the checkbox/splitview is from line 147-200. Would be really appreciated if you would be willing to take a look! Thanks! – Barkley Dai Dec 11 '19 at 4:01
  • @BarkleyDai I tried creating a version that reuses the same map, but unfortunately I hit what seems to be a bug. See my edit. – Kevin Reid Dec 11 '19 at 4:17
  • Thanks for the comments! So it seems that after splitPanel the root is changed so there is no way to undo it? I am wondering in that case if there is another way to display two different but in sync maps side by side in GEE, and can allow the user to switch from single panel view and split panel view? Thanks a lot! – Barkley Dai Dec 11 '19 at 4:24
  • @BarkleyDai I believe my second script should restore the original single map layout when the checkbox is unchecked, but there is a bug preventing that from happening properly. I will report this and hopefully it can be made to work. – Kevin Reid Dec 11 '19 at 4:33
  • Thanks Kevin! I am wondering if there's a simpler way to do it, and came across the Map.unlisten and shown function, and I am wondering if there is anyway it could work on splitPanel if I can hide and show panel2? code.earthengine.google.com/397aa792d5237839ed9fd14fcd107190 – Barkley Dai Dec 11 '19 at 4:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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