I am calculating the centroid of a Feature, and then extracting the geometry of that point in a specific projection. When I print the geometry, it shows me under coordinates the coordinates I expect. Still, if I am trying to extract the coordinates using .coordinates(), it gives a different set of coordinates, presumably in a different projection.

How can I get the coordinates of a geometry in the projection of the geometry, or by explicitly mentioning the projection?

The code that showcases the issue:

var random_region = ee.FeatureCollection(
                [[[-69.06480462117582, -10.919336774192457],
                  [-69.06480462117582, -10.944028822959991],
                  [-69.03313309712797, -10.944028822959991],
                  [-69.03313309712797, -10.919336774192457]]], null, false),
              "system:index": "0"
var central_point = ee.Feature(random_region.first()).centroid(1)
var destination_landsat_projection = ee.ImageCollection("LANDSAT/LC08/C02/T1_L2").filterBounds(central_point.geometry()).first().projection()
central_point = central_point.geometry(null, destination_landsat_projection)
central_point.aside(print,"Point").coordinates().aside(print,"wrong coordinates")
//Point (494649.22, -1208426.05), EPSG:32619
//wrong [2868.8074992709517,1301.368171039052]
ee.Geometry.Point(ee.List([494649.22, -1208426.05]), 'EPSG:32619').aside(print,"Point").coordinates().aside(print,"correct coordinates")
//Point (494649.22, -1208426.05), EPSG:32619
//correct [494649.22,-1208426.05]
  • This seems like a Bug to me. At the very least inconsistent behaviour.
    – JonasV
    Aug 28, 2021 at 10:19
  • @JonasV To me as well. I posted it already on developer's group, but that's a busy place where threads get easily lost. I just posted this as a bug as well, just in case someone stumbles on this question issuetracker.google.com/issues/198012628
    – Andrei
    Aug 28, 2021 at 16:54
  • You might get lucky and Noel Gorelick sees your question, he's quite active on here. That could speed things up a bit
    – JonasV
    Aug 29, 2021 at 8:30
  • @JonasV That's exactly what I was planning on. Meanwhile, I discovered that the unexpected coordinates are some coordinates based directly on Landsat, because 1 unit is 1 pixel. Funnily enough, that's exactly what I needed. My script now depends on this undocumented? feature. Now I hope this won't be fixed too soon, or that it will be fixed with bug to bug backwards compatibility :D
    – Andrei
    Aug 29, 2021 at 15:08

1 Answer 1


This is interesting. You are right that it is not well documented, but it seems that printing the geometry will give you the point coordinates as xOrigin + x*xPixelSize and yOrigin+y*yPixelSize, while the ee.Geometry.Point.coordinates() will give you just the [x,y] (in the units of the projection).

Here's a code example that demonstrates this in four projections:

// EPSG:4326 with identity transform:
var projA = ee.Projection("EPSG:4326")
  print("projA crs: ", p.crs)             // EPSG:4326
  print("projA transform: ", p.transform) // [1,0,0,0,1,0]
// EPSG:4326 in half-degree units:
var projB = ee.Projection("EPSG:4326", [0.5,0,0,0,0.5,0])
  print("projB crs: ", p.crs)             // EPSG:4326
  print("projB transform: ", p.transform) // [0.5,0,0,0,0.5,0]
// EPSG:32619 with identity transform:
var projC = ee.Projection("EPSG:32619")
  print("projC crs: ", p.crs)             // EPSG:32619
  print("projC transform: ", p.transform) // [1,0,0,0,1,0]
// EPSG:32619 in 30m units, with origin at 1000,-1000
var projD = ee.Projection("EPSG:32619", [30,0,1000,0,-30,-1000])
  print("projD crs: ", p.crs)             // EPSG:32619
  print("projD transform: ", p.transform) // [30,0,1000,0,-30,-1000]
//[xScale, xShearing, xTranslation, yShearing, yScale, yTranslation]
var x = 1, y=1  // The x,y coordinates we will use.
// Point with coordinates [1,1] in different projections:
var pointA = ee.Geometry.Point([x,y], projA).aside(print, "pointA");
var pointB = ee.Geometry.Point([x,y], projB).aside(print, "pointB");
var pointC = ee.Geometry.Point([x,y], projC).aside(print, "pointC");
var pointD = ee.Geometry.Point([x,y], projD).aside(print, "pointD");
// Coordinates given as xOrigin+x*xPixelSize, yOrigin+y*yPixelSize
pointA.evaluate(function(p){print("pointA coordinates: " , p.coordinates)})
pointB.evaluate(function(p){print("pointB coordinates: " , p.coordinates)})
pointC.evaluate(function(p){print("pointC coordinates: " , p.coordinates)})
pointD.evaluate(function(p){print("pointD coordinates: " , p.coordinates)})
// The above prints the same information, as a javascript object 
// i.e. this is what gets printed in the .aside(print) above..

// However, the ee.Geometry.Point.coordinates() has the original
// x,y in the units of the projection, i.e. 1,1, for all points above:
print("Point A coordinates (x,y):", pointA.coordinates())
print("Point B coordinates (x,y):", pointB.coordinates())
print("Point C coordinates (x,y):", pointC.coordinates())
print("Point D coordinates (x,y):", pointD.coordinates())


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.