0

I have a Google Earth Engine app that displays multiple image layers from an image collection. The user uses checkboxes to pick what layers to display. I want to add a feature that adds a ee.Geometry.Point layer to the map wherever the user clicks and I want it so that everytime the user clicks somewhere new, it replaces the last point (so there is only 1 point on the map at a time).

I tried making it so that when adding the point, it uses the size() of the image collection as the Map.layers() index to add, but it returns this weird error saying: "ee.Number({.....})" is not a valid list index.

Map.onClick(function(coordinate) {
var point = ee.Geometry.Point(coordinate.lon, coordinate.lat);

// imgCol is the image collection containing all the user's selected images
Map.layers().set(imgCol.size(), ui.Map.Layer(point, {color: 'FF0000'}, "Point"));
});

Keep in mind in the real app, the user chooses the number of layers so I can't just set the index to a constant number.

1 Answer 1

0

Most ui.* methods expect client-side values. This is the case of ui.data.ActiveList.set() - it doesn't work with the server-side ee.Number you get from ee.ImageCollection.size(). You can read up on client vs server here.

A quick fix is to turn your server-side ee.Number into a client-side number with a getInfo() call. In general, you should try to avoid getInfo(). It blocks the user interface - sometimes for a very long time, depending on the amount of work EE need to perform.

Map.layers().set(imgCol.size().getInfo(), ui.Map.Layer(point, {color: 'FF0000'}, "Point"));

An alternative to this is to use evaluate() instead. This prevents any blocking, but will still introduce a delay before the layer is added.

imgCol.size().evaluate(function (i) {
  Map.layers().set(i, ui.Map.Layer(point, {color: 'FF0000'}, "Point"));
})

Maybe you can keep track of which layer to use in a different way altogether? This uses a global variable with the index that get updated for each click.

var imgCol = ee.ImageCollection([])

var i = 0
Map.onClick(function(coordinate) {
  var point = ee.Geometry.Point(coordinate.lon, coordinate.lat);
  
  // imgCol is the image collection containing all the user's selected images
  Map.layers().set(i, ui.Map.Layer(point, {color: 'FF0000'}, "Point"));
  i++
});

https://code.earthengine.google.com/820fcb75a86f86352d4ae1d62c4650fe

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.