1

I am trying to use in Google Earth Engine a reducer (histogram) on an ImageCollection, computing it for multiple shapes for each image.

For a given image, I use reduceRegions(..., ee.Reducer.mean()) and this work, returning a feature collection with property mean.

However, when I try to apply this to all the image of the ImageCollection, using map(), it still returns a FeatureCollection, but the mean property is empty.

How can I solve this? Why is my result good on an image, but weird on an ImageCollection

var rec1 = ee.Geometry.Polygon([[[-89.78276, 40.160312], [-89.78293, 40.153424],
      [-89.77108, 40.153424], [-89.77117, 40.160377]]]);

var rec2 = ee.Geometry.Polygon([[[-89.782848, 40.15335], [-89.782848, 40.14607],
      [-89.774522, 40.14607],[-89.774265, 40.15322]]]);

var featCol = ee.FeatureCollection([ee.Feature(rec1), ee.Feature(rec2)]);

/// get ImageCollection, and Image
var CDL= ee.ImageCollection("USDA/NASS/CDL")
var CDL_2015 = ee.Image('USDA/NASS/CDL/2015');


/// For one image: works
var fieldStats_oneIm = CDL_2015.select("cropland").reduceRegions({
collection: featCol,
reducer: ee.Reducer.mean(),
scale: 30
});



/// For all images: does not work?
var fieldStats_ImCol = CDL.map(function(image) {return 
    image.select("cropland").reduceRegions({
    collection: featCol,
    reducer: ee.Reducer.mean(),
    scale: 30
})});



print(fieldStats_oneIm, "fieldStats_oneIm")
print(fieldStats_ImCol, "fieldStats_ImCol")
4

This is how I would solve it, which doesn't mean it's the best or even correct way to do it. But it works. The are some features that don't have the mean property, but I guess it is an issue of the image collection.

var rec1 = ee.Geometry.Polygon([[[-89.78276, 40.160312], [-89.78293, 40.153424],
      [-89.77108, 40.153424], [-89.77117, 40.160377]]]);

var rec2 = ee.Geometry.Polygon([[[-89.782848, 40.15335], [-89.782848, 40.14607],
      [-89.774522, 40.14607],[-89.774265, 40.15322]]]);

var featCol = ee.FeatureCollection([ee.Feature(rec1), ee.Feature(rec2)]);

/// get ImageCollection, and Image
var CDL= ee.ImageCollection("USDA/NASS/CDL")
var CDL_2015 = ee.Image('USDA/NASS/CDL/2015');

//Map.centerObject(CDL_2015)
Map.addLayer(CDL_2015)


/// For one image: works
var fieldStats_oneIm = CDL_2015.select("cropland")
.reduceRegions({
collection: featCol,
reducer: ee.Reducer.mean(),
scale: 30
});

// iterating function
var userFunc = function(image, list) {
  var newimg = image.select("cropland")
    .reduceRegions({
      collection: featCol,
      reducer: ee.Reducer.mean(),
      scale: 30
    })
  return ee.List(list).add(newimg)
}

// empty list to fill with features
var list = ee.List([])

// iterate over the image collection to fill the list
var fieldStats_list = ee.List(CDL.iterate(userFunc, list))

// Cast the list into a FeatCol
// as reduceRegions returns a FeatureCollection you have to flatten
var fieldStats_ImCol = ee.FeatureCollection(fieldStats_list).flatten();

// Print and show
print(fieldStats_oneIm, "fieldStats_oneIm")
print(fieldStats_ImCol, "fieldStats_ImCol")

Map.addLayer(fieldStats_ImCol)
Map.centerObject(featCol)
1

Answer to my own question: the code was actually close to right. I mainly omitted to use flatten(), which would return one feature per year/polygon, instead of having just one feature per year. Without the flatten(), the mean property was actually containing two values, and hence would be difficult to read in the UI.

Second issue in my example is that for some year, there is no data, and hence nothing returned.

Hence, just use:

print(fieldStats_ImCol.flatten(), "fieldStats_ImCol")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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