Skip to content

Instantly share code, notes, and snippets.

@stonetip
Last active January 21, 2021 03:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stonetip/11e4aef1c579f9817f6921d59a6b873b to your computer and use it in GitHub Desktop.
Save stonetip/11e4aef1c579f9817f6921d59a6b873b to your computer and use it in GitHub Desktop.
Function demo to convert between lat/lon and zxy tile coordinates at a given zoom level
<html>
<head>
<title>tile calc</title>
</head>
<body>
<script>
const degToRad = Math.PI/180;
function getTileZXY(zxyStr) { // e.g. 12/773/1447
const tileStrParts = zxyStr.split("/");
const z = Number(tileStrParts[0]);
const x = tileStrParts[1];
const y = tileStrParts[2];
console.log("tile parts:", z, x, y);
return {z, x, y} ;
}
function tileToLatLon(z, x, y){ // e.g. z = 12, x = 773, y = 1447
const n = Math.pow(2, z);
const lat = Math.atan(Math.sinh(Math.PI * (1 - 2 * y/n))) / degToRad;
const lon = x/n*360-180;
console.log("2 lat,lon:", lat, lon);
return {z, lon, lat};
}
function latLonToTile(z, lat, lon){ // e.g. z = 12, lat = 46.619, lon = -112.061
const n = Math.pow(2, z);
const x = Math.floor((lon + 180)/360 * n);
const y = Math.floor((1.0 - Math.asinh(Math.tan(lat*degToRad)) / Math.PI) / 2.0 * n);
console.log("x, y:", x, y);
return {z, x, y};
}
// Test getting tile coordinate parts from string
//const tileZXY = getTileZXY("12/773/1447");
const tileZXY = getTileZXY("10/193/361");
// Test getting lat/lon object from tile coordinates
const coord = tileToLatLon(tileZXY.z, tileZXY.x, tileZXY.y);
console.log("coord:", coord);
// Test getting tile coordinates object from lat/lon
const zxy = latLonToTile(coord.z, coord.lat, coord.lon);
console.log("zxy:", zxy);
// Test 11
const zxy11 = latLonToTile(11, 46.792, -112.142);
console.log("zxy11:", zxy11);
// Test 12
const zxy12 = latLonToTile(12, 46.792, -112.142);
console.log("zxy12:", zxy12);
// Test 13
const zxy13 = latLonToTile(13, 46.792, -112.142);
console.log("zxy13:", zxy13);
// Test 0
const zxy0 = latLonToTile(0, 37.473, -89.633);
console.log("zxy0:", zxy0);
// Test 1
const zxy1 = latLonToTile(1, 37.473, -89.633);
console.log("zxy1:", zxy1);
// Test 2
const zxy2 = latLonToTile(2, 37.473, -89.633);
console.log("zxy2:", zxy2);
const coord2 = tileToLatLon(2, 0, 1);
console.log("coord2:", coord2);
// Build a bounding box for a tile
// Order: minX, minY, maxX, maxY
function getTileBoundingBox(z, x, y){
const commonLatLon = tileToLatLon(z, x, y);
const minX = commonLatLon.lon;
const minY = tileToLatLon(z, x, y + 1).lat;
const maxX = tileToLatLon(z, x + 1, y).lon;
const maxY = commonLatLon.lat;
return {minX, minY, maxX, maxY};
}
// bbox tests
const bb0 = getTileBoundingBox(zxy0.z, zxy0.x, zxy0.y);
console.log("bb0:", bb0);
const bb1 = getTileBoundingBox(zxy1.z, zxy1.x, zxy1.y);
console.log("bb1:", bb1);
const bb2 = getTileBoundingBox(zxy2.z, zxy2.x, zxy2.y);
console.log("bb2:", bb2);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment