I have a large FeatureCollection (100,000+ polygons) and want to get several values from it at once to display in a ui.Label
with only one call to .evaluate
. I have found the following way to do it that works but want to check if this is the BEST way:
var selectedstr = (ee.Feature(selectedstate.first()).select(['NAME', 'GEOID', 'ALAND', 'AWATER'], null, false)).toDictionary().values(['NAME', 'GEOID', 'ALAND', 'AWATER']);
var selectedarray;
selectedstr.evaluate(function(result) {
if (result) {
selectedarray = result.toString().split(",");
mylabel.setValue(selectedarray[0] + ", " + selectedarray[1] + ", " + selectedarray[2] + ", " + selectedarray[3]);
// do other stuff
}
});
Here's a working example on a much smaller layer.
Answer
You've got the right general idea — you should bundle all the results you want into one ComputedValue
and evaluate
that. To simplify and improve your code so far, you can delete .toString().split(",")
. The result is already a JavaScript array so doing this is at best redundant and at worst corrupts the data (e.g. if one of the values is a string containing a comma).
But in the bigger picture: You don't need to convert the properties to a dictionary and then to an array — just evaluate the feature itself. (But it is good to still use .select()
, like you already are, so you don't compute and download any properties or geometry you don't actually plan to use.)
In order to handle the case when the collection is empty without encountering an error, we do .select()
on the features before taking the first feature of the collection. (This will not waste computation because only the features needed for the final result are actually evaluated.)
var selectedFeature = selectedstate
.map(function(feature) {
return feature.select(['NAME', 'GEOID', 'ALAND', 'AWATER'], null, false);
})
.first();
selectedFeature.evaluate(function(evaluatedFeature) {
if (evaluatedFeature) {
var properties = evaluatedFeature.properties;
mylabel.setValue(
properties.NAME + ", " +
properties.GEOID + ", " +
properties.ALAND + ", " +
properties.AWATER);
} else {
mylabel.setValue("Nothing selected");
}
});
No comments:
Post a Comment