4

I am currently trying to do a grouped reduction, but I am having trouble manipulating the outputs. The code calculates areas per land cover type and outputs a list of objects with two properties, 'code' i.e. land cover type and 'area', the area of the land cover in question. The issue is that I am having trouble filtering the output list, as I would like to access the area of each specific land cover without knowing the index.

The code is as follows:

// Load land cover
var lcStudy = ee.Image("COPERNICUS/Landcover/100m/Proba-V-C3/Global/2019")
                   .select('discrete_classification').clip(neighborhood);

// Add pixel area as a band to the Image
var lcStudyAreas = ee.Image.pixelArea().rename('area').addBands(lcStudy);
print(lcStudyAreas);

// Do a grouped reduction
var output = lcStudyAreas.reduceRegion({
  reducer: ee.Reducer.sum().group({
    groupField: 1,
    groupName: 'code',
  }),
  geometry: neighborhood,
  scale: 1000,
  maxPixels: 1e13
}).get('groups');

print(output);

The issue is I would like to know, for example, the area of the land cover number 20 (shrubland). But when I haven't found the correct way to filter the list. Writing:

var shrubArea = ee.List(output).filter(ee.Filter.eq('code',20));

Produces an error:

List.filter: Filters used in List.filter should refer to the property named 'item'.

But replacing 'code' for 'item' produces an empty list.

Here is a link to the code: https://code.earthengine.google.com/b144b1c5645b69748576e7d426a3bb3b

1
  • Edited because ee.Image.pixelArea() should be used without multiplying
    – M. Nicolas
    Commented Feb 17, 2021 at 23:37

1 Answer 1

4

ee.Filters are best when working with features and their properties, not dictionaries. Therefore, I recommend converting the dictionaries to features and the list to a feature collection:

var groupsList = lcStudyAreas.reduceRegion({
  reducer: ee.Reducer.sum().group({
    groupField: 1,
    groupName: 'code',
  }),
  geometry: neighborhood,
  scale: 1000,
  maxPixels: 1e13
}).get('groups');

var groupFeatures = ee.FeatureCollection(
  ee.List(groupsList).map(function (dict) {
    // Convert the dictionary to properties of a feature (with no geometry)
    return ee.Feature(null, dict);
  })
);

// All the features (for demonstration)
print(groupFeatures);

// Filtered to one matching feature
print(groupFeatures.filter(ee.Filter.eq('code', 20)));

It's also possible to filter a list using ee.List.map with the dropNulls option, but that is not particularly advantageous in this case. Converting to a FeatureCollection also makes it easy to export your data as a table later.

2
  • I would like to know more about "ee.Filters are best when working with features and their properties, not dictionaries"? There is a clue in the docs for ee.List.filter. "Filters a list to only the elements that match the given filter. To filter list items that aren't images or features, test a property named 'item', e.g.: ee.Filter.gt('item', 3)". This doesn't help for a list of dictionaries.
    – intotecho
    Commented Sep 14, 2021 at 11:24
  • @intotecho If you have a question, please ask it — with more concrete details of what exactly you want to know — on the Ask Question page. You can include a link to this question if it is useful context.
    – Kevin Reid
    Commented Sep 14, 2021 at 14:39

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.