MapboxGL行列号计算
MapboxGL的行列号计算。
var latlng = [114.29,30.56]; //武汉市地理坐标
var zoom = 5; //层级
var tileX = Math.floor(map.transform.locationCoordinate(latlng).x * Math.pow(2, zoom));
var tileY = Math.floor(map.transform.locationCoordinate(latlng).y * Math.pow(2, zoom));
epsg4490下输出: tileX:26, tileY:5

locationCoordinate 函数目的
将地理经纬度坐标转换为当前地图缩放级别下的瓦片坐标系中的 列号(column) 和 行号(row),用于确定该坐标点对应的地图瓦片位置。
参数说明
-
latlng
包含lng(经度)和lat(纬度)属性的对象,表示地理坐标。
示例:{ lng: 116.404, lat: 39.915 }(北京坐标)。
关键变量与方法
-
this.tileZoom
当前地图的缩放级别(例如0表示全球视野,18表示街道级细节)。 -
this.zoomScale(tileZoom)
计算当前缩放级别下的 比例因子。通常实现为Math.pow(2, tileZoom),表示每个缩放级别将瓦片数量翻倍。 -
this.worldSize
基准缩放级别(通常为0)下的世界地图尺寸(单位:像素)。
标准瓦片地图中,worldSize = 256 * Math.pow(2, 0) = 256(单个瓦片尺寸为 256x256 像素)。 -
this.lngX(lng)
将 经度 转换为墨卡托投影的 X 坐标,范围[0, 1]。
公式:lngX(lng) { return (lng + 180) / 360; // 经度范围[-180, 180] → 投影到[0, 1] } -
this.latY(lat)
将 纬度 转换为墨卡托投影的 Y 坐标,范围[0, 1]。
公式(基于墨卡托投影):latY(lat) { const sin = Math.sin(lat * Math.PI / 180); const y = 0.5 - (Math.log((1 + sin) / (1 - sin)) / (4 * Math.PI)); return y; // 纬度范围[-85.06, 85.06] → 投影到[0, 1] }
计算步骤
-
计算缩放比例因子
kconst k = this.zoomScale(this.tileZoom) / this.worldSize;-
示例:若
tileZoom = 2,则zoomScale = 2^2 = 4,worldSize = 256
→k = 4 / 256 = 0.015625。
-
-
计算瓦片列号
columncolumn = this.lngX(latlng.lng) * k;-
示例:经度
lng = 116.404
→lngX(116.404) = (116.404 + 180)/360 ≈ 0.8233
→column = 0.8233 * 0.015625 ≈ 0.01287。
-
-
计算瓦片行号
rowrow = this.latY(latlng.lat) * k;-
示例:纬度
lat = 39.915
→latY(39.915) ≈ 0.408(具体值需通过墨卡托公式计算)
→row = 0.408 * 0.015625 ≈ 0.006375。
-
-
返回结果
return { column, row, zoom: this.tileZoom };-
输出示例:
{ column: 0.01287, row: 0.006375, zoom: 2 }
-
功能总结
此函数将地理坐标转换为 归一化的瓦片坐标系(范围 [0, k]),其中:
-
column和row:表示坐标点相对于当前缩放级别下整个地图的 相对位置。 -
zoom:记录当前缩放级别,用于后续瓦片索引计算。
实际应用场景
-
瓦片加载
根据column和row计算具体瓦片 URL(需取整处理):const tileX = Math.floor(column * Math.pow(2, zoom)); const tileY = Math.floor(row * Math.pow(2, zoom));示例:
zoom=2→ 瓦片网格为4x4,tileX=0,tileY=0。 -
点标记定位
将地理坐标转换为地图容器的像素坐标:const pixelX = column * (256 * Math.pow(2, zoom)); const pixelY = row * (256 * Math.pow(2, zoom));
完整代码示例
class MapProjection {
constructor() {
this.tileZoom = 2; // 当前缩放级别
this.worldSize = 256; // 基准缩放级别下的世界尺寸(像素)
}
zoomScale(zoom) {
return Math.pow(2, zoom);
}
lngX(lng) {
return (lng + 180) / 360;
}
latY(lat) {
const sin = Math.sin(lat * Math.PI / 180);
return 0.5 - (Math.log((1 + sin) / (1 - sin)) / (4 * Math.PI);
}
locationCoordinate(latlng) {
const k = this.zoomScale(this.tileZoom) / this.worldSize;
return {
column: this.lngX(latlng.lng) * k,
row: this.latY(latlng.lat) * k,
zoom: this.tileZoom
};
}
}
// 使用示例
const map = new MapProjection();
const coord = map.locationCoordinate({ lng: 116.404, lat: 39.915 });
console.log(coord); // { column: ~0.01287, row: ~0.006375, zoom: 2 }
浙公网安备 33010602011771号