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! May 25 at 15:17

Your Answer

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

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