实现 Leaflet 多类型点位标记与聚合功能的实战经验分享

        在现代的地理信息系统(GIS)应用中,地图功能是不可或缺的一部分。无论是展示商业网点、旅游景点还是公共服务设施,地图都能以直观的方式呈现数据。然而,当数据量较大时,地图上可能会出现大量的标记点,这不仅会影响用户体验,还会导致性能问题。因此,我们需要一种方法来智能地聚合这些标记点,同时允许用户在需要时查看详细信息。

Leaflet 是一个轻量级的开源 JavaScript 地图库,它提供了丰富的 API 和插件支持,非常适合实现这种功能。结合 Leaflet.markercluster 插件,我们可以轻松实现标记点的聚合和动态显示。

项目背景

在最近开发中,我遇到了一个有趣的需求:实现基于 Leaflet 的地图功能,支持多类型点位标记和聚合。这个功能需要展示不同类型的数据点,并在地图缩放时智能聚合,以避免地图过于拥挤。经过一番努力,我成功实现了这一功能,并在此分享我的经验和代码实现。

实现思路

1. 数据结构设计

在实现功能之前,我们需要定义清晰的数据结构,以便更好地管理和展示不同类型的数据点。以下是点位数据的格式示例:

markerData: [{latitude: "23.131828",longitude: "113.326821",name: "麦当劳(正佳广场五楼店)",address: "广州市天河区天河南街道天河路228号正佳广场五楼561铺",type: "fast_food"},{latitude: "23.116523",longitude: "113.390699",name: "肯德基(车陂南店)",address: "广州市天河区车陂路6号一层",type: "fast_food"}...
]

此外,我们还需要定义支持的标记点类型和对应的样式配置:

markerType: ["fast_food","coffee","landmark","tourist","shopping","entertainment","transport"
],typeList: [{name: "全部",type: "all",color: "#000000",iconUrl: require("../../assets/img/all.png")},{name: "快餐店",type: "fast_food",color: "blue",iconUrl: require("../../assets/img/fast_food.png")},{name: "咖啡店",type: "coffee",color: "green",iconUrl: require("../../assets/img/coffee.png")},{name: "城市地标",type: "landmark",color: "orange",iconUrl: require("../../assets/img/landmark.png")},{name: "旅游景点",type: "tourist",color: "red",iconUrl: require("../../assets/img/tourist.png")},{name: "购物中心",type: "shopping",color: "purple",iconUrl: require("../../assets/img/shopping.png")},{name: "娱乐场所",type: "entertainment",color: "yellow",iconUrl: require("../../assets/img/entertainment.png")},{name: "交通设施",type: "transport",color: "teal",iconUrl: require("../../assets/img/transport.png")}
]

2. 地图初始化

首先,我们需要初始化地图。Leaflet 提供了简单易用的 API 来创建地图实例,并设置中心点、缩放级别等基本参数。在我们的项目中,我们使用了天地图(Tianditu)作为地图源,这需要通过 WMTS 服务加载矢量地图和影像地图图层。

this.map = L.map("mapRef", {center: [23.111532, 113.324357], // 地图中心zoom: 13, // 缩放比例zoomControl: false, // 是否显示缩放按钮doubleClickZoom: false, // 是否双击放大attributionControl: false, // 是否显示右下角 Leaflet 标识minZoom: 3, // 最小缩放级别
});

3. 添加地图图层

我们使用了天地图的矢量地图和影像地图图层。需要注意的是,天地图的访问需要一个有效的 API 密钥(tk),并且图层的 URL 需要按照 WMTS 服务的规范进行拼接。

const tiandiKey = "YOUR_TIANDITU_API_KEY"; // 替换为你的天地图 API 密钥
const mapUrl = `http://t0.tianditu.gov.cn/vec_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=vec&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${tiandiKey}`;
const cvaLayer = L.tileLayer(`http://t0.tianditu.gov.cn/cva_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=cva&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=${tiandiKey}`
);this.map.addLayer(L.tileLayer(mapUrl)); // 添加矢量地图图层
this.map.addLayer(cvaLayer); // 添加影像地图图层

注意:如果你在加载天地图时遇到问题,请检查 API 密钥是否有效,以及 URL 拼接是否正确。如果问题仍然存在,可能是网络问题或链接本身的问题,建议适当重试或联系天地图官方支持。

4. 创建聚合图层

为了实现标记点的聚合,我们使用了 Leaflet.markercluster 插件。该插件可以将大量的标记点智能地聚合在一起,形成可点击的群组。当用户放大地图时,这些群组会自动拆分成更小的子集或单个标记点。

我们为每种类型的标记点创建了一个独立的聚合图层,并通过 iconCreateFunction 动态设置聚合图标的颜色和样式。

this.markerType.forEach((type) => {const iconCreateFunction = (cluster) => {const dynamicClassName = `custom-marker cluster-icon-${type}`;return L.divIcon({html: `<div class="${dynamicClassName}"><span>${cluster.getChildCount()}</span></div>`,className: `custom-marker cluster-icon-${type}`,iconSize: L.point(40, 40),});};this.markerClusters[type] = L.markerClusterGroup({iconCreateFunction: iconCreateFunction,});
});

5. 添加标记点

标记点的数据通常以数组的形式存储,每个数据项包含类型、名称、地址和坐标等信息,可以点击展示点位信息。我们根据数据项的类型,将其添加到对应的聚合图层中。

this.markerData.forEach((item) => {const [longitude, latitude] = gcoord.transform([item.longitude, item.latitude],gcoord.GCJ02,gcoord.WGS84);const marker = L.marker([latitude, longitude], {icon: icons[item.type],});marker.bindPopup(`<b>${item.name}</b><br>${item.address}`);this.markerClusters[item.type].addLayer(marker);
});Object.values(this.markerClusters).forEach((cluster) => {this.map.addLayer(cluster);
});

6. 动态过滤标记点

为了提升用户体验,我们允许用户通过点击按钮来筛选特定类型的标记点。当用户点击按钮时,我们移除所有聚合图层,并根据用户的选择重新添加对应的图层。

filterType(item) {Object.values(this.markerClusters).forEach((cluster) => {this.map.removeLayer(cluster);});if (item.type === "all") {Object.values(this.markerClusters).forEach((cluster) => {this.map.addLayer(cluster);});} else {if (this.markerClusters[item.type]) {this.map.addLayer(this.markerClusters[item.type]);}}
}

性能优化

在处理大量标记点时,性能优化是至关重要的。Leaflet.markercluster 插件本身已经对性能进行了优化,但我们仍然可以通过以下方式进一步提升性能:

  1. 限制标记点数量:在地图缩放级别较低时,可以隐藏一些不重要的标记点。

  2. 使用缓存:对于重复加载的数据,可以使用缓存机制减少重复请求。

  3. 异步加载数据:如果标记点数据量较大,可以采用分页或懒加载的方式动态加载数据。

总结

通过 Leaflet 和 Leaflet.markercluster 插件,我们成功实现了一个支持多类型点位标记和聚合的地图功能。这个功能不仅提升了用户体验,还为地图应用提供了更强大的数据展示能力。在开发过程中,我们需要注意地图图层的加载、聚合图标的动态设置以及性能优化等方面,以确保应用的稳定性和流畅性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/25484.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python3GUI--Fun!音乐播放器 By:PyQt5(附下载地址)

文章目录 一&#xff0e;前言二&#xff0e;展示1.主界面2.推荐歌单3.音乐小屋4.播放页面 三&#xff0e;心得体会1.重写表格2.高斯模糊3.项目结构 四&#xff0e;总结 欢迎下载体验&#xff01;点击下载 一&#xff0e;前言 打磨了一段时间的fun音乐播放器和大家见面了&…

光速解决phpstudy无法启动MySQL服务

问题描述 在初步安装使用phpstudy时&#xff0c;会出现mysql服务启动失败的情况&#xff0c;具体表现为点击一键启动后&#xff0c;mysql启动又立即停止 原因及解决方法&#xff1a; phpstudy数据库无法启动有以下几个原因&#xff0c;可以看看自己是第几种&#xff1a; 服务名…

Dashboard-frps

通过浏览器查看 frp的状态以及代理统计信息展示。 注&#xff1a;Dashboard 尚未针对大量的 proxy 数据展示做优化&#xff0c;如果出现 Dashboard 访问较慢的情况&#xff0c;请不要启用此功能。 需要在 frps.ini中指定 dashboard服务使用的端口&#xff0c;即可开启此功能&…

【网络编程】几个常用命令:ping / netstat / xargs / pidof / watch

ping&#xff1a;检测网络联通 1. ping 的基本功能2. ping 的工作原理3. ping 的常见用法4. ping 的输出解释5. ping 的应用场景6. 注意事项 netstat&#xff1a;查看网络状态 1. netstat 的基本功能2. 常见用法3. 示例4. 输出字段解释5. netstat 的替代工具6. 注意事项 xargs&…

AI 赋能教育:智能家教与个性化学习助手的革命性设计与实践

网罗开发 &#xff08;小红书、快手、视频号同名&#xff09; 大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等…

水利工程安全包括哪几个方面

水利工程安全培训的内容主要包括以下几个方面&#xff1a; 基础知识和技能培训 &#xff1a; 法律法规 &#xff1a;学习水利工程相关的安全生产法律法规&#xff0c;了解安全生产标准及规范。 事故案例 &#xff1a;通过分析事故案例&#xff0c;了解事故原因和教训&#x…

【HarmonyOS Next】鸿蒙应用折叠屏设备适配方案

【HarmonyOS Next】鸿蒙应用折叠屏设备适配方案 一、前言 目前应用上架华为AGC平台&#xff0c;都会被要求适配折叠屏设备。目前华为系列的折叠屏手机&#xff0c;有华为 Mate系列&#xff08;左右折叠&#xff0c;华为 Mate XT三折叠&#xff09;&#xff0c;华为Pocket 系列…

数据驱动未来!天合光能与永洪科技携手开启数字化新篇章

在信息化时代的今天&#xff0c;企业间的竞争早就超越了传统产品与服务的范畴&#xff0c;新的核心竞争力即——数据处理能力和信息技术的应用。作为数据技术领域的领军者&#xff0c;永洪科技凭借其深厚的技术积累和丰富的行业经验&#xff0c;成功助力天合光能实现数字化升级…

Metal学习笔记八:纹理

到目前为止&#xff0c;您已经学习了如何使用片段函数和着色器为模型添加颜色和细节。另一种选择是使用图像纹理&#xff0c;您将在本章中学习如何操作。更具体地说&#xff0c;您将了解&#xff1a; • UV 坐标&#xff1a;如何展开网格&#xff0c;以便可以对其应用纹理。 •…

SpringSecurity的核心过滤器-CsrfFilter

Spring Security除了认证授权外功能外,还提供了安全防护功能。本文我们来介绍下SpringSecurity中是如何阻止CSRF攻击的。 一、什么是CSRF攻击 跨站请求伪造(英语:Cross-site request forgery),也被称为 one-click attack 或者 session riding,通常缩写为 CSRF 或者 XSRF…

《当齐天大圣踏入3A游戏世界:黑神话·悟空的破壁传奇》:此文为AI自动生成

国产 3A 游戏的破晓之光 2024 年 8 月 20 日,这一天注定被铭记在中国游戏发展的史册上。国产首款 3A 游戏《黑神话・悟空》震撼上线,犹如一颗重磅炸弹,在全球游戏市场掀起了惊涛骇浪。仅仅上线 3 小时,其同时在线人数便突破了 140 万,一举打破 Steam 纯单机游戏最高在线纪…

rust 前端npm依赖工具rsup升级日志

rsup是使用 rust 编写的一个前端 npm 依赖包管理工具&#xff0c;可以获取到项目中依赖包的最新版本信息&#xff0c;并通过 web 服务的形式提供查看、升级操作等一一系列操作。 在前一篇文章中&#xff0c;记录初始的功能设计&#xff0c;自己的想法实现过程。在自己的使用过…

【备赛】点亮LED

LED部分的原理图 led前面有锁存器&#xff0c;这是为了防止led会受到lcd的干扰&#xff08;lcd也需要用到这些引脚&#xff09;。 每次想要对led操作&#xff0c;就需要先打开锁存器&#xff0c;再执行操作&#xff0c;最后关闭锁存器。 这里需要注意的是&#xff0c;引脚配置…

CSS 使用white-space属性换行

一、white-space属性的常见值 * 原本格式&#xff1a; 1、white-space:normal 默认值&#xff0c;空格和换行符会被忽略过滤掉&#xff1b;宽度不够时文本会自动换行 * 宽度足够时&#xff0c;normal 处理后的格式 * 宽度不够时&#xff0c; normal 处理后的格式 2、white-spa…

electron-builder打包时github包下载失败【解决办法】

各位朋友们&#xff0c;在使用electron开发时&#xff0c;选择了electron-builder作为编译打包工具时&#xff0c;是否经常遇到无法从github上下载依赖包问题&#xff0c;如下报错&#xff1a; Get "https://github.com/electron/electron/releases/download/v6.1.12/ele…

【WSL2】 Ubuntu20.04 GUI图形化界面 VcXsrv ROS noetic Vscode 主机代理 配置

【WSL2】 Ubuntu20.04 GUI图形化界面 VcXsrv ROS noetic Vscode 主机代理 配置 前言整体思路安装 WSL2Windows 环境升级为 WIN11 专业版启用window子系统及虚拟化 安装WSL2通过 Windows 命令提示符安装 WSL安装所需的 Linux 发行版&#xff08;如 Ubuntu 20.04&#xff09;查看…

2025学年安徽省职业院校技能大赛 “信息安全管理与评估”赛项 比赛样题任务书

2024-2025 学年广东省职业院校技能大赛 “信息安全管理与评估”赛项 技能测试试卷&#xff08;五&#xff09; 第一部分&#xff1a;网络平台搭建与设备安全防护任务书第二部分&#xff1a;网络安全事件响应、数字取证调查、应用程序安全任务书任务1 &#xff1a;内存取证&…

数据库导出

MySQL数据库 使用命令行导出 导出整个数据库&#xff1a;在命令行中输入mysqldump -u用户名 -p密码 数据库名 > 导出文件路径/文件名.sql。例如mysqldump -uroot -p123456 mydb > /home/user/mydb_backup.sql&#xff0c;回车后输入密码即可将名为mydb的数据库导出为SQL…

OpenCV给图像添加噪声

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 如果你已经有了一张干净的图像&#xff0c;并希望通过编程方式向其添加噪声&#xff0c;可以使用 OpenCV 来实现这一点。以下是一个简单的例子&a…

OSPF BIT 类型说明

注&#xff1a;本文为 “OSPF BIT 类型 | LSA 类型 ” 相关文章合辑。 机翻&#xff0c;未校。 15 OSPF BIT Types Explained 15 种 OSPF BIT 类型说明 Rashmi Bhardwaj Distribution of routing information within a single autonomous system in larger networks is per…