(Almost) every map projection, including the one used in the Code Editor's interactive map, has a different scale at different points. Therefore, there is no single number which accurately describes the area of a pixel anywhere on the map.
ee.Image.pixelArea()
may be used to determine the area of individual pixels so that you can perform accurate area calculations.
Generate an image in which the value of each pixel is the area of that pixel in square meters. The returned image has a single band called "area."
For example, if you add it to the map,
Map.addLayer(ee.Image.pixelArea());
then click the “Inspector” tab in the Code Editor and click on the map, then the inspector will report the area of the specific pixel you clicked on. This area depends on the zoom level and where you are.
In order to use pixelArea()
with a sum or count reducer, the usually correct thing to do is to multiply the input image by pixelArea()
. Thus, each pixel's value is multiplied (weighted, if you like) by that pixel's area, so the overall answer is a sum over the area rather than the pixels.
To illustrate, I've added a threshold and reduceRegion to Earth Engine's NDVI example:
var region = ee.Geometry.Polygon([[[-95.5, 39.5], [-95.5, 38.8], [-94.3, 38.8], [-94.3, 39.5]]], null, false);
Map.addLayer(region);
Map.setCenter(-94.84497, 39.01918, 8);
var img = ee.Image('MODIS/006/MOD09GA/2012_03_09');
var ndvi = img.normalizedDifference(['sur_refl_b02', 'sur_refl_b01']);
Map.addLayer(ndvi, {min: 0, max: 1}, 'NDVI');
var thresholded = ndvi.gt(0.35);
Map.addLayer(ee.Image.pixelArea(), {}, 'Area', false);
Map.addLayer(thresholded, {}, 'Thresholded');
print('Scale 100 m', thresholded.multiply(ee.Image.pixelArea()).reduceRegion({
reducer: ee.Reducer.sum(),
geometry: region,
scale: 100,
}).get('nd'));
print('Scale 1 km', thresholded.multiply(ee.Image.pixelArea()).reduceRegion({
reducer: ee.Reducer.sum(),
geometry: region,
scale: 1000,
}).get('nd'));
https://code.earthengine.google.com/91f1ec1f3d8d7e2e4e1942849bf645b9
Since thresholded
has a value of either 0 or 1, multiplying it by the area, thresholded.multiply(ee.Image.pixelArea())
, produces that pixel's contribution to the total area: either nothing or the area of the pixel.
(The same idea works if the input image is some sort of density value rather than a binary threshold: summing density times area gives a total quantity.)
In the example, I'm running the reduction twice, with two different scales. You can see that the results are approximately the same, indicating that the scale / pixel area has been compensated for.