Skip to content

Instantly share code, notes, and snippets.

@KEIII
Last active June 29, 2018 09:53
Show Gist options
  • Save KEIII/58ea4794e964188221a1fbc902e7d343 to your computer and use it in GitHub Desktop.
Save KEIII/58ea4794e964188221a1fbc902e7d343 to your computer and use it in GitHub Desktop.
Convert zoom level to range
/**
* Convert zoom level to range.
*
* @param {number} zoomLevel The zoom level in meters
* @param {number} latitude The latitude in radians
* @param {number} canvasWidth The canvas width in px
* @param {number} scaleFactor The scale factor (e.g. window.devicePixelRatio)
* @param {number} fov The FOV in degrees (e.g. 60)
* @param {number} globeRadius The globe radius in meters (e.g. 6378137)
*
* @return {number} The range in meters
*/
export const zoomLevelToRange = (
zoomLevel: number,
latitude: number,
canvasWidth: number,
scaleFactor: number,
fov: number,
globeRadius: number,
) => {
const equatorialCircumference = 2 * Math.PI * globeRadius;
const tileSize = 256 * scaleFactor; // px
// @link https://wiki.openstreetmap.org/wiki/Zoom_levels#Distance_per_pixel_math
// The horizontal distance represented by each square tile,
// measured along the parallel at a given latitude, is given by:
// S(tile) = C * cos(latitude) / 2^zoomlevel
// where C means the equatorial circumference of the Earth
const distOfTile = equatorialCircumference * Math.cos(latitude) / Math.pow(2, zoomLevel);
// As tiles are 256-pixels wide, the horizontal distance represented by one pixel is:
// S(pixel) = S(tile) / tilesize
const distOfPx = distOfTile / tileSize;
const distOfCanvas = distOfPx * canvasWidth;
return (distOfCanvas / 2) / Math.tan(fov / 2);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment