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 }(北京坐标)。


关键变量与方法

  1. this.tileZoom
    当前地图的缩放级别(例如 0 表示全球视野,18 表示街道级细节)。

  2. this.zoomScale(tileZoom)
    计算当前缩放级别下的 比例因子。通常实现为 Math.pow(2, tileZoom),表示每个缩放级别将瓦片数量翻倍。

  3. this.worldSize
    基准缩放级别(通常为 0)下的世界地图尺寸(单位:像素)。
    标准瓦片地图中,worldSize = 256 * Math.pow(2, 0) = 256(单个瓦片尺寸为 256x256 像素)。

  4. this.lngX(lng)
    将 经度 转换为墨卡托投影的 X 坐标,范围 [0, 1]
    公式:

    javascript
    复制
    lngX(lng) {
      return (lng + 180) / 360; // 经度范围[-180, 180] → 投影到[0, 1]
    }
  5. this.latY(lat)
    将 纬度 转换为墨卡托投影的 Y 坐标,范围 [0, 1]
    公式(基于墨卡托投影):

    javascript
    复制
    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]
    }

计算步骤

  1. 计算缩放比例因子 k

    javascript
    复制
    const k = this.zoomScale(this.tileZoom) / this.worldSize;
    • 示例:若 tileZoom = 2,则 zoomScale = 2^2 = 4worldSize = 256
      → k = 4 / 256 = 0.015625

  2. 计算瓦片列号 column

    javascript
    复制
    column = this.lngX(latlng.lng) * k;
    • 示例:经度 lng = 116.404
      → lngX(116.404) = (116.404 + 180)/360 ≈ 0.8233
      → column = 0.8233 * 0.015625 ≈ 0.01287

  3. 计算瓦片行号 row

    javascript
    复制
    row = this.latY(latlng.lat) * k;
    • 示例:纬度 lat = 39.915
      → latY(39.915) ≈ 0.408(具体值需通过墨卡托公式计算)
      → row = 0.408 * 0.015625 ≈ 0.006375

  4. 返回结果

    javascript
    复制
    return { column, row, zoom: this.tileZoom };
    • 输出示例

      javascript
      复制
      { column: 0.01287, row: 0.006375, zoom: 2 }

功能总结

此函数将地理坐标转换为 归一化的瓦片坐标系(范围 [0, k]),其中:

  • column 和 row:表示坐标点相对于当前缩放级别下整个地图的 相对位置

  • zoom:记录当前缩放级别,用于后续瓦片索引计算。


实际应用场景

  1. 瓦片加载
    根据 column 和 row 计算具体瓦片 URL(需取整处理):

    javascript
    复制
    const tileX = Math.floor(column * Math.pow(2, zoom));
    const tileY = Math.floor(row * Math.pow(2, zoom));

    示例:zoom=2 → 瓦片网格为 4x4tileX=0tileY=0

  2. 点标记定位
    将地理坐标转换为地图容器的像素坐标:

    javascript
    复制
    const pixelX = column * (256 * Math.pow(2, zoom));
    const pixelY = row * (256 * Math.pow(2, zoom));

完整代码示例

javascript
复制
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 }
posted on 2025-03-26 10:29  顺风车  阅读(53)  评论(0)    收藏  举报