MapLibre GL JS第11课:获取鼠标指针坐标

📌 学习目标

  • 掌握获取鼠标指针坐标的实现方法
  • 理解相关API的使用
  • 能够独立完成类似功能开发

🎯 核心概念

获取鼠标指针的坐标。

💻 完整代码

代码示例

js 复制代码
const map = new maplibregl.Map({
    container: 'map', // 容器ID
    style: 'https://demotiles.maplibre.org/style.json',
    center: [-74.5, 40], // 初始位置
    zoom: 3 // 初始缩放级别
});

map.on('mousemove', (e) => {
    document.getElementById('info').innerHTML =
        // e.point 是鼠标移动事件相对于地图左上角的 x, y 坐标,相对于地图左上角
        `${JSON.stringify(e.point)
        }<br />${
            // e.lngLat 是事件的经度、纬度地理坐标    
            JSON.stringify(e.lngLat.wrap())}`;
});

代码示例

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Get coordinates of the mouse pointer</title>
    <meta property="og:description" content="鼠标悬停时显示鼠标位置,包括像素坐标以及经纬度坐标。" />
    <meta property="og:created" content="2025-06-25" />
    <meta charset='utf-8'>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel='stylesheet' href='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.css' />
    <script src='https://unpkg.com/maplibre-gl@5.24.0/dist/maplibre-gl.js'></script>
    <style>
        body { margin: 0; padding: 0; }
        html, body, #map { height: 100%; }
    </style>
</head>
<body>
<style>
    #info {
        display: block;
        position: absolute;
        top: 20px;
        left: 50%;
        transform: translate(-50%);
        width: 50%;
        padding: 10px;
        border: none;
        border-radius: 3px;
        font-size: 12px;
        text-align: center;
        color: #222;
        background: #fff;
    }
</style>
<div id="map"></div>
<pre id="info"></pre>
<script>
    const map = new maplibregl.Map({
        container: 'map', // 容器ID
        style: 'https://demotiles.maplibre.org/style.json',
        center: [-74.5, 40], // 初始位置
        zoom: 3 // 初始缩放级别
    });

    map.on('mousemove', (e) => {
        document.getElementById('info').innerHTML =
            // e.point 是鼠标移动事件相对于地图左上角的 x, y 坐标
            `${JSON.stringify(e.point)
            }<br />${
                // e.lngLat 是事件的经度、纬度地理坐标
                JSON.stringify(e.lngLat.wrap())}`;
    });
</script>
</body>
</html>

🔍 代码解析

1. 初始化地图

使用 new maplibregl.Map() 创建地图实例,配置基本参数。本示例重点展示如何监听鼠标移动事件获取坐标。

2. 监听鼠标移动事件

通过 map.on('mousemove', callback) 监听鼠标移动事件:

  • e.point: 鼠标相对于地图左上角的像素坐标
  • e.lngLat: 鼠标位置的地理坐标(经纬度)

3. 坐标转换方法

  • e.lngLat.wrap(): 将经度归一化到 -180, 180 范围内

⚙️ 参数说明

参数 类型 必填 说明
container string 地图容器ID
style string 地图样式URL
center number, number 初始中心点,默认0, 0
zoom number 初始缩放级别,默认0

事件对象属性

属性 类型 说明
e.point Point 鼠标像素坐标 {x, y}
e.lngLat LngLat 地理坐标 {lng, lat}

🎨 效果说明

运行代码后:

  • 地图顶部显示一个信息面板
  • 鼠标在地图上移动时,实时显示当前位置的像素坐标和经纬度坐标
  • 像素坐标原点为地图左上角
  • 经纬度坐标自动进行经度归一化处理

地图默认显示美国东部区域(-74.5°W, 40°N),缩放级别为3。

💡 常见问题

Q1: 为什么需要使用 wrap() 方法?

A: wrap() 方法将经度限制在 -180, 180 范围内,避免经度值超过这个范围导致显示问题。

Q2: 如何获取点击位置的坐标?

A: 将事件改为 click

javascript 复制代码
map.on('click', (e) => {
    console.log(e.lngLat);
});

Q3: 如何将像素坐标转换为地理坐标?

A: 使用 map.unproject(point) 方法:

javascript 复制代码
const lngLat = map.unproject([x, y]);

📝 练习任务

  1. 基础练习:修改信息面板的样式和位置
  2. 进阶挑战:添加点击事件,在点击位置添加标记
  3. 拓展思考:如何实现坐标格式切换(度分秒/十进制)?

🌟 最佳实践

  1. 性能优化: 鼠标移动事件触发频繁,避免在回调中执行耗时操作
  2. 坐标精度: 根据需求控制经纬度显示精度
  3. 事件清理 : 不再需要监听时使用 map.off() 移除事件监听
  4. 边界处理 : 使用 wrap() 处理跨越180度经线的情况

🔗 延伸阅读


本文是MapLibre GL JS实践课程系列的一部分,欢迎关注收藏

相关推荐
郭老二3 小时前
【前端】vue3:编译步骤
前端
不在逃避q4 小时前
Trae/Vs Code/Cursor命令行无法跑npm命令
前端·arcgis·npm
夏殇之殁4 小时前
包中创建自定义列表项。 . 使用自定义列表项进行数据绑定 . 将天气预报数据保存到本地内存表,通过LiveBindings进行显示。 ...
服务器·前端·javascript
The Chosen One9854 小时前
高进度算法模板速记(待完善)
java·前端·算法
陈随易4 小时前
MoonBit抓包模块pcap,查看电脑的每一次联网通信
前端·后端·程序员
新中地GIS开发老师6 小时前
WebGIS开发学生作品|低空航天管理与航线规划系统
前端·javascript·webgis·三维gis开发
用户059540174466 小时前
大模型对话记忆持久化踩坑实录:用 Playwright 自动化测了 300 次,终于揪出会话丢失的真凶
前端·css
丙氨酸長鏈6 小时前
Web前端入门第 问:JavaScript 一个简单的 IndexedDB 数据库入门示例
前端·javascript·数据库
kyriewen7 小时前
面试官让我手写虚拟列表——AI生成的版本,快速滚动几下就白屏了
前端·javascript·面试
IT_陈寒7 小时前
Vite热更新失效?你可能漏了这个配置
前端·人工智能·后端