MapLibre GL JS第69课:获取鼠标下的要素

📌 学习目标

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

MapLibre GL JS 从入门到精通 - 130+实战案例

🎯 核心概念

获取鼠标指针下的要素。

💻 完 整 代 码

代码示例

const map = new maplibregl.Map({
    container: 'map',
    style: 'https://tiles.openfreemap.org/styles/bright',
    center: [-96, 37.8],
    zoom: 3
});

map.on('mousemove', (e) => {
    const features = map.queryRenderedFeatures(e.point);

    // 为了可读性和性能,限制显示的属性数量
    const displayProperties = [
        'type',
        'properties',
        'id',
        'layer',
        'source',
        'sourceLayer',
        'state'
    ];

    const displayFeatures = features.map((feat) => {
        const displayFeat = {};
        displayProperties.forEach((prop) => {
            displayFeat[prop] = feat[prop];
        });
        return displayFeat;
    });

    document.getElementById('features').innerHTML = JSON.stringify(
        displayFeatures,
        null,
        2
    );
});

代码示例

<!DOCTYPE html>
<html lang="en">
<head>
    <title>Get features under the mouse pointer</title>
    <meta property="og:description" content="使用 queryRenderedFeatures 显示悬停地图要素的属性。" />
    <meta property="og:created" content="2006-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>
    #features {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        width: 50%;
        overflow: auto;
        background: rgba(255, 255, 255, 0.8);
    }
    #map canvas {
        cursor: crosshair;
    }
</style>
<div id="map"></div>
<pre id="features"></pre>
<script>
    const map = new maplibregl.Map({
        container: 'map',
        style: 'https://tiles.openfreemap.org/styles/bright',
        center: [-96, 37.8],
        zoom: 3
    });

    map.on('mousemove', (e) => {
        const features = map.queryRenderedFeatures(e.point);

        // 为了可读性和性能,限制显示的属性数量
        const displayProperties = [
            'type',
            'properties',
            'id',
            'layer',
            'source',
            'sourceLayer',
            'state'
        ];

        const displayFeatures = features.map((feat) => {
            const displayFeat = {};
            displayProperties.forEach((prop) => {
                displayFeat[prop] = feat[prop];
            });
            return displayFeat;
        });

        document.getElementById('features').innerHTML = JSON.stringify(
            displayFeatures,
            null,
            2
        );
    });
</script>
</body>
</html>

🔍 代码解析

1. 初始化地图

使用 new maplibregl.Map() 创建地图实例,配置美国区域作为初始视图。

2. 关键配置项

  • map.queryRenderedFeatures(): 查询鼠标位置下的要素
  • displayProperties: 定义要显示的属性列表
  • JSON.stringify(): 将要素信息格式化为JSON字符串显示

⚙️ 参数说明

参数类型必填说明
point[number, number]屏幕坐标 [x, y]
options.layersstring[]只查询指定图层

🎨 效果说明

在这里插入图片描述

运行代码后,地图显示美国区域。鼠标在地图上移动时,右侧面板会实时显示鼠标位置下的所有要素信息,包括类型、属性、所属图层、来源等。

💡 常 见 问 题

Q1: 查询结果为空?
A: 检查以下几点:

  1. 确认鼠标位置确实在要素上
  2. 检查options.layers过滤条件是否正确
  3. 确认图层是否可见

Q2: 如何限制只查询特定图层?
A: 使用layers选项过滤:

const features = map.queryRenderedFeatures(e.point, {
    layers: ['places', 'roads']
});

Q3: 如何只获取要素的属性?
A: 使用map.queryRenderedFeatures().map(f => f.properties)

📝 练习任务

  1. 基础练习:修改displayProperties显示更多属性
  2. 进阶挑战:添加图层筛选器,只显示特定图层信息
  3. 拓展思考:如何实现点击获取要素信息?
  4. 综合实践:创建一个要素信息调试工具

🌟 最佳实践

  1. 性能优化: 限制显示的属性数量,避免频繁DOM操作
  2. 调试友好: 格式化JSON输出便于阅读
  3. 交互设计: 区分鼠标样式便于用户理解
  4. 开发辅助: 用于检查图层数据和属性结构
  5. 无障碍: 考虑为屏幕阅读器提供替代方案

🔗 延伸阅读


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

丷丩

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值