Last active
January 21, 2021 03:57
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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