一、原理
墨卡托适用于二维,从0级开始,为正方形,列号从左往右,行号从上到下,每级瓦片:
行数=列数=Math.pow(2,zoom)
经纬度划分适用于三维球,从1级开始,左右各一张,为长方形,列号从左往右,行号从下到上,每级瓦片:
行数=Math.pow(2,zoom-1) 列数=Math.pow(2.zoom)
二、js代码
// 经纬度转瓦片编号
function lon2tile(lon, zoom) {
return (Math.floor((lon + 180) / 360 * Math.pow(2, zoom)));
}
//经纬度划分下转瓦片行列号,适用于三维球
function lat2tileGeo(lat, zoom) {
return (Math.floor((90 - lat) / 180 * Math.pow(2, zoom)));
}
//web墨卡托下转瓦片行列号,适用于二维平面
function lat2tileWeb(lat, zoom) {
return (Math.floor((1 - Math.log(Math.tan(lat * Math.PI / 180) + 1 / Math.cos(lat * Math.PI / 180)) / Math.PI) / 2 * Math.pow(2, zoom)));
}
// 墨卡托下瓦片编号转经纬度
function tile2long(x, z) {
return (x / Math.pow(2, z) * 360 - 180);
}
function tile2lat(y, z) {
var n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);
return (180 / Math.PI * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n))));
}
/**
* web墨卡托转瓦片行列号
* @param {*} zoom
* @param {*} x
* @param {*} y
* @returns
*/
function web2XY(zoom, x, y) {
//计算总共多少列瓦片
const cols = Math.pow(2, zoom + 1)
//计算总像素值
const pixels = cols * 256;
//计算总米数
const meters = 20037508.342789244 + 20037508.342789244
//计算分辨率
const resolution = meters / pixels;
//当前位置x方向距离原点多少米
const rangeX = x - (-20037508.342789244);
//当前位置x方向距离原点多少像素
const pxs = rangeX / resolution;
//
//瓦片横坐标
const i = Math.floor(pxs / 256);
//当前位置y方向距离原点多少米
const rangeY = 20037508.342789244 - y;
//当前位置y方向距离原点多少像素
const pys = rangeY / resolution;
//瓦片纵坐标
const j = Math.floor(pys / 256)
return { i, j }
}
function computeTileArea(bounds, zoom) {
const startCol = lon2tile(bounds.left, zoom + 1)
const endCol = lon2tile(bounds.right, zoom + 1)
const startRow = lat2tileGeo(bounds.top, zoom + 1)
const endRow = lat2tileGeo(bounds.bottom, zoom + 1)
return {
startCol, endCol, startRow, endRow
}
}
网友评论