0

I am developing an GEE-app where I initially want to concatenate a birdSelector string for user-defined filtering of an image collection containing monthly bird distribution maps from different breeding colonies (species_colony_month).

I plan to use three ui.checkBoxes for the selection: speciesSelect (eg. 'URAAL'), colonySelect (eg. 'c026') and monthSelect (eg. 'may').

How should I code the thee ui.Checkboxes so that I can build up the birdSelector string (eg. URAAL_c023_may)?

    var birdSelector = speciesSelect.getValue() + '_' + colonySelect.getValue() + '_' + monthSelect.getValue();

1 Answer 1

0

ui.Checkbox.getValue() returns booleans, so in your script you'd probably end up with true_true_true.

I hardly ever add any GUI to my EE scripts and this script is more about me playing around for fun than actually helping you. The script obviously contain more code than needed to solve your immediate problem. Sorry about that! Still, perhaps it could at least be somewhat useful.

withState(function (state) {
  // Setup the GUI
  var speciesOptions = [
    {id: 'speciesA', label: 'Species A'}, 
    {id: 'speciesB', label: 'Species B'},
    {id: 'speciesC', label: 'Species C'},
    {id: 'speciesD', label: 'Species D'},
  ]
  var speciesPanel = ui.Panel()
  Map.add(speciesPanel)
  Radios(speciesOptions, state.bind('species')).addTo(speciesPanel)
  
  var colonyOptions = [
    {id: 'colonyA', label: 'Colony A'}, 
    {id: 'colonyB', label: 'Colony B'}
  ]
  var colonyPanel = ui.Panel()
  Map.add(colonyPanel)
  Radios(colonyOptions, state.bind('colony')).addTo(colonyPanel)
  
  var monthOptions = [
    {id: 'jan', label: 'January'}, 
    {id: 'feb', label: 'February'}
  ]
  var monthPanel = ui.Panel()
  Map.add(monthPanel)
  Radios(monthOptions, state.bind('month')).addTo(monthPanel)
  
  var collection = createDummyCollection()

  // Listen to changes and update the map
  state.listen(['species', 'colony', 'month'], function () {
    var species = state.get('species')
    var colony = state.get('colony')
    var month = state.get('month')
    var birdSelector = species && colony && month
      ? species + '_' + colony + '_' + month
      : null
    Map.layers().reset()
    if (birdSelector) { // Add map layer if we got a valid selector
      var image = collection
        .filter(ee.Filter.eq('selector', birdSelector))
        .first()
      print('Selector', birdSelector)
      Map.addLayer(image.randomVisualizer())
    }
  })
  
  function createDummyCollection() {
    return ee.ImageCollection(ee.List(
      speciesOptions.map(function (species, i) {
        return colonyOptions.map(function (colony, j) {
          return monthOptions.map(function (month, k) {
            return ee.Image.random(i 
              + speciesOptions.length * j 
              + speciesOptions.length * colonyOptions.length * k)
              .reproject('EPSG:4326', null, 1e6)
              .set('selector', species.id + '_' + colony.id + '_' + month.id)
          })
        })
      })
    ).flatten())    
  }
    
})


function withState(callback) {
  var state = {}
  var listeners = []
  
  callback({
    get: get,
    set: set,
    bind: bind,
    listen: listen
  })

  function bind(property) {
    return function (value) {
      set(property, value)
    }
  }
  
  function get(property) {
    return state[property]
  }
  
  function set(property, value) {
    var prevValue = state[property]
    state[property] = value
    if (prevValue !== value) {
      listeners.forEach(function (o) {
        if (o.properties.indexOf(property) > -1) {
          o.listener(property, value, prevValue)
        }
      })
    }
  }
  
  function listen(properties, listener) {
    listeners.push({properties: properties, listener: listener})
  }  
}


// A group of checkboxes where only one can be selected at a time
function Radios(options, onChange) {
  var selection
  var checkboxById = {}
  var checkboxes = options.map(function (option, i) {
    var checkbox = ui.Checkbox(option.label, option.id == selection, function (selected) {
      if (selection && selection !== option.id) {
        // Don't trigger when resetting previously selected checkbox
        checkboxById[selection].setValue(false, false)
      }
      var previousSelection = selection
      selection = selected // Update selection
        ? option.id 
        : selection === option.id
          ? undefined // Already selected
          : selection
      if (selection !== previousSelection) {
        onChange(selection)
      }
    })
    checkboxById[option.id] = checkbox
    return checkbox
  })
  return {
    addTo: function(panel) {
      checkboxes.forEach(function (checkbox) {
        panel.add(checkbox)
      })
    }
  }
}

https://code.earthengine.google.com/6371724c3f68666f157166767059742a

1
  • Thanks a lot Daniel, will check out your suggestions as soon as possible! Commented May 25, 2023 at 15:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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