I'm working with the Hansen Global Forest Change dataset and following the guide on how to quantify the data. This produces an object showing acres of forest loss for each year (lossyear band values) within a geometry. This is exactly what i want, but I need to map this over an entire feature collection to get these annual values for each feature in the collection as opposed to an object representing the sum of the whole collection.

I've done this with Image Collections (create an Image with a band for each year and then mapping over the FC to get the value for each band and attach it to the FC features), but the way that the grouped reducer creates an object based on unique values in the lossyear band is throwing me.

Do I need to create an image with a band for each value in the lossyear band and then iterate over it, or is there a way to apply this grouped reducer strategy over an entire feature collection?

Ultimately, I am aiming for a .csv with these annual values and the id's of the FC.


var aoi = ee.FeatureCollection("users/jrobertsonpanthera/surveyed_grid_3test");

// Hansen Data
var gfc = ee.Image('UMD/hansen/global_forest_change_2022_v1_10');
var lossImage = gfc.select(['loss']);
var lossAreaImage = lossImage.multiply(ee.Image.pixelArea());

var lossYear = gfc.select(['lossyear']);

//get sum for aoi
var lossByYear = lossAreaImage.addBands(lossYear).reduceRegion({
  reducer: ee.Reducer.sum().group({
    groupField: 1
  geometry: aoi,
  scale: 30,
  maxPixels: 1e9
print(lossByYear, 'lossByYear');

//dictionary object sun by year
var statsFormatted = ee.List(lossByYear.get('groups'))
  .map(function(el) {
    var d = ee.Dictionary(el);
    return [ee.Number(d.get('group')).format("20%02d"), d.get('sum')];
var statsDictionary = ee.Dictionary(statsFormatted.flatten());
print(statsDictionary, 'statsDictionary');

//show aoi, zoom the map
Map.addLayer(ee.Image().paint(aoi, 1, 3), null, 'region'); 

//show the loss layer
var treeLossVisParam = {
  bands: ['lossyear'],
  min: 0,
  max: 1,
  palette: ['yellow', 'red']
Map.addLayer(gfc, treeLossVisParam, 'tree loss year');


1 Answer 1


You can use reduceRegions() for that.

var lossByYearCollection = lossAreaImage
    collection: aoi, 
    reducer: ee.Reducer.sum().group({groupField: 1}),
    scale: 30
var stats = lossByYearCollection
  .map(function (feature) {
    var id = feature.get('id')
    var groups = ee.List(feature.get('groups'))
    return ee.FeatureCollection(groups.map(function(el) {
      var d = ee.Dictionary(el)
      return ee.Feature(feature.geometry(), {
        id: id,
        year: ee.Number(d.get('group')).format("20%02d"), 
        area: d.get('sum')

  collection: stats, 
  description: 'loss-area-by-polygon-and-year', 
  selectors: ['id, year, area'] // If don't want the .geo and system:index columns


  • This is fantastic. It works great, thank you! I'm struggling to figure out how to utilize this data in the current format. Is there a way to transpose the annual data into columns (id, loss_2001,loss_2002, etc)?
    – jamierob
    Aug 22, 2023 at 19:53
  • I would suggest you post a new question about that, including the details, including the format you are trying to to convert this too, in detail. Aug 22, 2023 at 21:54

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.