经纬志
首页 / MapLibre / API 文档

unproject

先看结论

容器像素到经纬度的反算:把屏幕上的位置还原成地理坐标。

最后验证 2026-11-03 · MapLibre GL JS 4.x · 更新 2026-10-29 · 引用本文
map.unproject(point) → LngLat

参数与返回

项说明
point相对地图容器的像素坐标,Point 或 [x, y]
返回LngLat,可用 lng、lat 或 toArray() 取值

地图事件里通常已经带了 e.lngLat,不需要再换算。 unproject 用在事件对象之外:自己接的原生事件、第三方拖拽库、覆盖层的鼠标位置。

原生鼠标事件的坐标转换

var canvas = map.getCanvas();

canvas.addEventListener('mousedown', function (e) {
  var rect = canvas.getBoundingClientRect();

  var point = [
    e.clientX - rect.left,
    e.clientY - rect.top
  ];

  var lngLat = map.unproject(point);
  console.log(lngLat.lng, lngLat.lat);
});

必须先减去容器的 getBoundingClientRect() 偏移。 直接用 clientX 会把页面滚动与布局位置算进去,结果偏出很远。

拖拽绘制

var dragging = false;
var shape = [];

canvas.addEventListener('pointerdown', function (e) {
  dragging = true;
  shape = [toLngLat(e)];
});

canvas.addEventListener('pointermove', function (e) {
  if (!dragging) { return; }
  shape.push(toLngLat(e));
});

canvas.addEventListener('pointerup', function () {
  dragging = false;
  if (shape.length <= 2) { return; }

  var data = {
    type: 'Feature',
    geometry: { type: 'Polygon', coordinates: [shape] }
  };

  var src = map.getSource('sketch');

  if (src) {
    src.setData(data);
  } else {
    map.addSource('sketch', { type: 'geojson', data: data });
  }
});

function toLngLat(e) {
  var rect = canvas.getBoundingClientRect();
  return map.unproject([e.clientX - rect.left, e.clientY - rect.top]).toArray();
}

覆盖物位置与地理坐标互转

需求调用
已知经纬度,求屏幕位置map.project(lnglat)
已知屏幕位置,求经纬度map.unproject(point)
取地图中心map.getCenter()

精度与边界

反算结果使用当前投影,拖到极区附近时纬度会被限制在墨卡托可表达的范围内。 容器外的坐标(负值或超出宽高)也会得到有效经纬度, 但通常已落在当前视口之外,业务上应自行判空。

不要在 move 期间对同一元素反复 unproject 再 project。 来回换算会引入浮点误差,连续拖动后覆盖物会缓慢漂移。 覆盖物只保存经纬度,每帧重新 project 一次即可。

引用本文

经纬志(2026)。《unproject》。https://www.jingweizhi.com/maplibre/api/unproject.html(访问日期 2026-11-03)。