To calculate the area of the classes in a categorical image I'm using a ee.Image.reduceRegion
.
Sources:
var geometry =
ee.Geometry.Polygon(
[[[12.124393381085076, 42.35185853899329],
[12.124393381085076, 42.28788783747578],
[12.241123117413201, 42.28788783747578],
[12.241123117413201, 42.35185853899329]]], null, false);
var lc = ee.ImageCollection('COPERNICUS/Landcover/100m/Proba-V-C3/Global')
.filter(ee.Filter.date("2015-01-01", "2015-12-31"))
.select("discrete_classification")
.first()
var scale = lc.projection().nominalScale()
And applying the reduction:
var area = ee.Image.pixelArea().divide(1e4)
.addBands(lc)
.reduceRegion({
reducer:ee.Reducer.sum().group(1),
geometry:geometry,
scale:scale
}
)
// Reducing all the classes to get a single comparable value
var reduced_area = ee.Number(ee.List(area.get("groups")).map(function(group){
return ee.Dictionary(group).get("sum")
}).reduce(ee.Reducer.sum()))
print("reduced_count", reduced_count)
# Outputs:
# "pixel_area"
# 6837.526895473032
However, I'm forced to use an API that is reducing the region with ee.Reducer.frequencyHistogram
, I assume that I could calculate the area from each category just by multiplying each pixel count per class by the pixel area, but the results are not even close when I compare with the previous result.
// Not grouping to get an overall value to compare with previous calcualtion.
var frequency = lc
.reduceRegion({
reducer:ee.Reducer.frequencyHistogram(),
geometry:geometry,
scale:scale
}
)
print(
'Frequency area',
ee.Number(ee.Dictionary(
frequency.get("discrete_classification")
).values()
.reduce(ee.Reducer.sum()))
.multiply(scale.pow(2)).divide(1e4) // dumb, but just for clarity
)
# Outputs:
# "Frequency area"
# 12514.60784313726
So, why is this difference? can I calculate the area based on the frequency histogram?
Best Answer
You're not specifying a projection anywhere in your code, so
You don't actually know what projection you're using in the
reduceRegion
calls (probably EPSG:3857 because that's the projection of your lc image), andWhatever you're using, it doesn't have equal area pixels, so you get different area per pixel at different latitudes.
At the latitude you're working at, the pixels are approximately 5457 sqm in the original EPSG:3857 projection of the image, not the 10,000 sqm you were expecting (so you're off by about 50%).
You can switch to an equal area projection valid in your region of interest, and the multiplication method will work out to be almost identical.
# Frequency area 6837.443137254904
https://code.earthengine.google.com/a9dfe316e48a6bad8136cfd3043aa028