vgridjs
Version:
Vgrid DGGS JS
125 lines (123 loc) • 4.36 kB
JavaScript
;
// dggs/tilecode.ts
var MAX_ZOOM = 32;
var MIN_ZOOM = 0;
function tile(lng, lat, zoom) {
if (zoom < MIN_ZOOM || zoom > MAX_ZOOM) {
throw new Error(`Invalid zoom level: ${zoom}`);
}
if (lng < -180 || lng > 180) {
throw new Error(`Invalid longitude: ${lng}`);
}
if (lat < -90 || lat > 90) {
throw new Error(`Invalid latitude: ${lat}`);
}
const n = Math.pow(2, zoom);
const xtile = Math.floor((lng + 180) / 360 * n);
const ytile = Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * n);
return { x: xtile, y: ytile, z: zoom };
}
function bounds(x, y, z) {
if (z < MIN_ZOOM || z > MAX_ZOOM) {
throw new Error(`Invalid zoom level: ${z}`);
}
const n = Math.pow(2, z);
const west = x / n * 360 - 180;
const east = (x + 1) / n * 360 - 180;
const north = Math.atan(Math.sinh(Math.PI * (1 - 2 * y / n))) * 180 / Math.PI;
const south = Math.atan(Math.sinh(Math.PI * (1 - 2 * (y + 1) / n))) * 180 / Math.PI;
return { west, south, east, north };
}
function quadkey(tile2) {
let quadkey2 = "";
for (let i = tile2.z; i > 0; i--) {
let digit = 0;
const mask = 1 << i - 1;
if ((tile2.x & mask) !== 0) digit += 1;
if ((tile2.y & mask) !== 0) digit += 2;
quadkey2 += digit.toString();
}
return quadkey2;
}
function quadkeyToTile(quadkey2) {
let x = 0;
let y = 0;
const z = quadkey2.length;
for (let i = z; i > 0; i--) {
const mask = 1 << i - 1;
const digit = parseInt(quadkey2[z - i]);
if (digit & 1) x |= mask;
if (digit & 2) y |= mask;
}
return { x, y, z };
}
function latlon2tilecode(lat, lon, zoom) {
const t = tile(lon, lat, zoom);
return `z${t.z}x${t.x}y${t.y}`;
}
function latlon2quadkey(lat, lon, zoom) {
const t = tile(lon, lat, zoom);
return quadkey(t);
}
function quadkey2latlon(quadkey_id) {
const t = quadkeyToTile(quadkey_id);
const b = bounds(t.x, t.y, t.z);
const center_lat = (b.south + b.north) / 2;
const center_lon = (b.west + b.east) / 2;
return [center_lat, center_lon];
}
function tilecode2latlon(tilecode_id) {
const match = tilecode_id.match(/z(\d+)x(\d+)y(\d+)/);
if (!match) throw new Error("Invalid tilecode format. Expected format: 'zXxYyZ'");
const z = parseInt(match[1]);
const x = parseInt(match[2]);
const y = parseInt(match[3]);
const b = bounds(x, y, z);
const center_lat = (b.south + b.north) / 2;
const center_lon = (b.west + b.east) / 2;
return [center_lat, center_lon];
}
function tilecode2quadkey(tilecode_id) {
const match = tilecode_id.match(/z(\d+)x(\d+)y(\d+)/);
if (!match) throw new Error("Invalid tilecode format. Expected format: 'zXxYyZ'");
const z = parseInt(match[1]);
const x = parseInt(match[2]);
const y = parseInt(match[3]);
return quadkey({ x, y, z });
}
function quadkey2tilecode(quadkey_id) {
const t = quadkeyToTile(quadkey_id);
return `z${t.z}x${t.x}y${t.y}`;
}
function tilecodeCellLength(tilecode_id) {
const match = tilecode_id.match(/z(\d+)x(\d+)y(\d+)/);
if (!match) throw new Error("Invalid tilecode format. Expected format: 'zXxYyZ'");
const z = parseInt(match[1]);
const x = parseInt(match[2]);
const y = parseInt(match[3]);
const b = bounds(x, y, z);
const earthCircumference = 40075016686e-3;
const tileSize = earthCircumference / Math.pow(2, z);
const lat = (b.south + b.north) / 2;
const adjustedTileSize = tileSize * Math.cos(lat * Math.PI / 180);
return adjustedTileSize;
}
function tilecode2wktbound(tilecode_id) {
const match = tilecode_id.match(/z(\d+)x(\d+)y(\d+)/);
if (!match) throw new Error("Invalid tilecode format. Expected format: 'zXxYyZ'");
const z = parseInt(match[1]);
const x = parseInt(match[2]);
const y = parseInt(match[3]);
const b = bounds(x, y, z);
return `POLYGON((${b.west} ${b.south}, ${b.west} ${b.north}, ${b.east} ${b.north}, ${b.east} ${b.south}, ${b.west} ${b.south}))`;
}
exports.latlon2quadkey = latlon2quadkey;
exports.latlon2tilecode = latlon2tilecode;
exports.quadkey2latlon = quadkey2latlon;
exports.quadkey2tilecode = quadkey2tilecode;
exports.tilecode2latlon = tilecode2latlon;
exports.tilecode2quadkey = tilecode2quadkey;
exports.tilecode2wktbound = tilecode2wktbound;
exports.tilecodeCellLength = tilecodeCellLength;
//# sourceMappingURL=tilecode.cjs.map
//# sourceMappingURL=tilecode.cjs.map