[GIS] Earth engine reproject: why does reprojecting a pixel at 30m scale gives me pixels with an area of ~550

google-earth-enginereprojection-mathematics

Trying to understand how reproject() in Google Earth Engine works. To find an example, I am using ee.Image.pixelArea(), which gives an image containing the area of each pixel in square meters.

Now reprojecting this at the 30m scale, I expect that I will end up with pixels having an area of 900.

However, the data shows that my pixels have actually an area of ~557… what is hapenning? What is reproject() doing in that case?

var projection = ee.Projection('EPSG:3857').atScale(30)
var image_area = ee.Image.pixelArea()
var image_area_30 = ee.Image.pixelArea().reproject(projection)

Use the inspector to see the value of each individuals pixels, or:

Map.addLayer(image_area_30, {min:500, max:550}, "image_area_30")

EDIT/ANSWER

Bad question: the native projection of earth engine is a Mercator one, which does not preserve area. So indeed, need to go close to Equator, even if there seems to be around 893. Choosing instead an Albers equal area shows values for each pixel at 899.88 far away from Equator.

Best Answer

Google Earth Engine uses as default the Web Mercator Projection (EPSG:3857), which is a cylindrical map projection, and so, it distorts the size of objects as the latitude increases from the Equator to the poles. You can see the Tissot's indicatrix directly on GEE:

var p1 = ee.Feature(ee.Geometry.Point([-70, -80]))
var p2 = ee.Feature(ee.Geometry.Point([-70, -70]))
var p3 = ee.Feature(ee.Geometry.Point([-70, -60]))
var p4 = ee.Feature(ee.Geometry.Point([-70, -50]))
var p5 = ee.Feature(ee.Geometry.Point([-70, -40]))
var p6 = ee.Feature(ee.Geometry.Point([-70, -30]))
var p7 = ee.Feature(ee.Geometry.Point([-70, -20]))
var p8 = ee.Feature(ee.Geometry.Point([-70, -10]))
var p9 = ee.Feature(ee.Geometry.Point([-70, -5]))
var p10 = ee.Feature(ee.Geometry.Point([-70, 0]))

var fc = ee.FeatureCollection([p1,p2,p3,p4,p5,p6,p7,p8,p9,p10])
var circles = fc.map(function(el){return el.buffer(100000)})
Map.centerObject(circles)
Map.addLayer(circles)
Related Question