首页 / MapLibre / API 文档
unproject
先看结论
容器像素到经纬度的反算:把屏幕上的位置还原成地理坐标。
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)。