[GIS] How to transform EPSG:3857 to tile pixel coordinates at zoom factor 0

coordinate systemepsgleaflettilesweb-mapping

I'm creating a Leaflet map with an WebGL overlay (using L.CanvasOverlay) which renders a street network on the GPU.

Let's assume I have a point (1497143.62, 6896952.18) in EPSG:3857 and want to transform it to a pixel coordinate on a 256×256 raster, similar to a google maps tile at zoom level 0 (compare: this and that).

I can convert the same point (52.51904, 13.44907) to EPSG:4326 and use the following JavaScript code to do the reprojection to the 256×256 tile raster:

/**
 * Converts Lat/Lon to tile pixel X/Y at zoom level 0 
 * for 256x256 tile size and inverts y coordinates.
 *
 * @param {float} lat Latitude
 * @param {float} lon Longitued
 * @return Point with x and y corrdinates.
 */
function latLonToPixels(lat, lon) {
    var sinLat = Math.sin(lat * Math.PI / 180.0);
    var pixelX = ((lon + 180) / 360) * 256;
    var pixelY = (0.5 - Math.log((1 + sinLat) / (1 - sinLat)) / (Math.PI * 4)) * 256;
    return { x: pixelX, y: pixelY };
}

… which leaves me with the desired point (137.56378, 83.94214) on the raster.

So, using leaflet I could transform my point from 3857 to 4326 and afterwards calculate the pixel coordinates using the formula above. But as I understand the forumlas, this would require two spherical reprojections which is jus too much computing for large geometries.

I suspect there is a much more simple and efficient approach for this transformation. But I couldnt figure it out yet. Any idea?

In addition, searching the internet I can't figure out what the EPSG:3857 coordinates actually denote. This and that answer try to explain it a bit but it is still unclear how to programmatically solve this.

Best Answer

This is the answer. Sometimes you have to go through all the process of asking a question to understand the solution. JavaScript:

/**
 * Converts spherical web mercator to tile pixel X/Y at zoom level 0 
 * for 256x256 tile size and inverts y coordinates.
 *
 * @param {L.point} p Leaflet point in EPSG:3857
 * @return {L.point} Leaflet point with tile pixel x and y corrdinates.
 */
function mercatorToPixels(p)  {
  var equator = 40075016.68557849;
  var pixelX = (p.x + (equator / 2.0)) / (equator / 256.0);
  var pixelY = ((p.y - (equator / 2.0)) / (equator / -256.0));
  return L.point(pixelX, pixelY);
}

Explanation

The tile at zoom level 0 has a size of 40,075,016m * 40,075,016m. The tile size is 256px * 256px. The center of the web mercator is (0, 0).

  1. Translate the X-coordinate by a positiv half equator.
  2. Divide the X-result by the positive pixel size in meter.
  3. Translate the Y-coordinate by a negative half equator.
  4. Divide the Y-result by the negative pixel size in meter.

That's it.