Google Earth Engine – How to Calculate Scale from Zoom Level

google-earth-enginescalezoom

I found the following formula on the interwebs, including on some google group from someone claiming to work at Google:

var scale = 156543.03392 * Math.cos(mapCenter.lat * Math.PI / 180) / Math.pow(2, mapCenter.zoom)

I understood that it's the right one for Google Maps API, but I'm not sure the same applies for layers added on a ui.Map object on Google Earth Engine. I don't exactly understand where the initial constant comes from, so it would be nice if someone has an explanation.

I suspect that the values the above formula yields are not accurate because when I try to export a map at that scale, I get an error 400 "User memory limit exceeded.", which is odd considering that the map has already been rendered. I am either missing something important, or the above formula is not correct for calculating this scale.

I would like to be able to export an ee.Image that has been added as a layer, at the same scale it is rendered in a ui.Map in the code editor.

P.S. WARNING: Do not use the above formula in google earth engine, maps, or in some other place. When compared with the method provided in the answer, i.e. getScale(), it gives different results. Not only that there's a difference between the formula above and getScale(), but the difference is not constant. This means that not only the initial constant is wrong, but also the rest of the formula. The differences changes independently both with zoom level, and with latitude.

Moral of the story and note to future self stumbling over my previous question:

  1. Do not program when tired, but if you do, check the documentation again while better rested
  2. Do not copy-paste code that you do not fully understand

Best Answer

Since you want to export at the scale the map is rendered in, you just need to ask the map for its scale: Map.getScale(). Here's a complete example:

var geometry = ee.Geometry.Point([0, 0]).buffer(1000).bounds()
var image = ee.Image.random().clip(geometry)
  .reproject('EPSG:4326', null, 30)
Map.centerObject(image)
Map.addLayer(image.randomVisualizer())

var exportButton = ui.Button({
  label: 'Export', 
  onClick: function () {
    exportImage()
  }
})
Map.add(exportButton)

function exportImage() {
  var scale = Map.getScale()
  print(scale)
  Export.image.toDrive({
    image: image, 
    description: 'exported', 
    scale: scale
  })
}

https://code.earthengine.google.com/e9b9a25452b3281a396abb25e0ad179d