当前位置: 首页 > news >正文

leaflet中绘制轨迹线的大量轨迹点,解决大量 marker 绑定 tooltip 同时显示导致的性能问题

优化思路:获取屏幕可视区范围,判断tooltip 的经纬度是否在可视区范围内,如果在就显示,如果不在就隐藏,达到优化效果

代码:

/*** Leaflet Tooltip 视窗优化演示** 这个文件展示了如何在其他 Leaflet 项目中实现类似的 tooltip 优化方案* 主要解决大量 marker 绑定 tooltip 导致的性能问题** 使用方法:* 1. 引入此文件中的优化函数* 2. 替换原有的 bindTooltip 调用* 3. 在地图事件中调用更新方法*//*** 防抖* @param {*} fn 需要防抖的方法* @param {*} delay 防抖时间* @param {*} atOnce 是否需要立即执行* @returns* how use vue3+ts* (1) 首次执行 设置时间内只执行首次 适用于新增、设置、修改等*  let addTest = _.myDebounce(function(e: any) {addNum();}, 2000,true);let addNum = () => {console.log("打印参数");};**(2)设置时间内只执行最后一次  适用于筛选等let addTest = _.myDebounce(function(e: any) {addNum();}, 2000,false);let addNum = () => {console.log("打印参数");};*/
const myDebounce = (fn, time, atOnce) => {let delay = time || 200;let timer = null;let count = 0;return function () {const _this = this;const args = arguments;// 如果是立即执行if (atOnce) {// 第一次直接执行不用等if (count == 0) {fn.apply(_this, args);count++;if (timer) {clearTimeout(timer);}timer = setTimeout(function () {count = 0;// fn.apply(_this, args);}, delay);}} else {if (timer) {clearTimeout(timer);}timer = setTimeout(function () {fn.apply(_this, args);}, delay);}};
};/*** Tooltip 视窗优化类* 管理 Leaflet 地图中的 tooltip 显示优化*/
export class LeafletTooltipOptimizer {constructor(map) {this.map = map;this.visibleTooltipMarkers = new Set(); // 可视区域内已绑定tooltip的markerthis.allTooltipMarkers = new Map(); // 所有需要tooltip的marker信息this.updateDebounced = myDebounce(this.updateVisibleTooltips.bind(this), 200, false);this.initEventListeners();}/*** 初始化地图事件监听*/initEventListeners() {if (this.map) {this.map.on("moveend", this.updateDebounced);this.map.on("zoomend", this.updateDebounced);this.map.on("resize", this.updateDebounced);console.log("Tooltip优化事件监听器已初始化");}}/*** 检查marker是否在可视区域内*/isMarkerInViewport(marker) {if (!marker || !this.map) return false;try {const bounds = this.map.getBounds();const markerLatLng = marker.getLatLng();return bounds.contains(markerLatLng);} catch (error) {console.warn("检查marker可视性时出错:", error);return false;}}/*** 为marker绑定tooltip(延迟绑定)* @param {L.Marker} marker* @param {string} content tooltip内容* @param {Object} options tooltip选项*/bindTooltipIfVisible(marker, content, options = {}) {if (!marker) return;// 存储tooltip配置信息this.allTooltipMarkers.set(marker, { content, options });// 如果在可视区域内且未绑定tooltip,则绑定if (this.isMarkerInViewport(marker) && !this.visibleTooltipMarkers.has(marker)) {marker.bindTooltip(content, options);this.visibleTooltipMarkers.add(marker);}}/*** 更新可视区域内的tooltip绑定*/updateVisibleTooltips() {if (!this.map || this.allTooltipMarkers.size === 0) return;try {this.allTooltipMarkers.forEach((tooltipConfig, marker) => {const isVisible = this.isMarkerInViewport(marker);const hasTooltip = this.visibleTooltipMarkers.has(marker);if (isVisible && !hasTooltip) {// 进入可视区域,绑定tooltipmarker.bindTooltip(tooltipConfig.content, tooltipConfig.options);this.visibleTooltipMarkers.add(marker);} else if (!isVisible && hasTooltip) {// 离开可视区域,解绑tooltipmarker.unbindTooltip();this.visibleTooltipMarkers.delete(marker);}});} catch (error) {console.error("更新可视tooltip时出错:", error);}}/*** 清理marker的tooltip记录* @param {L.Marker} marker*/cleanupMarkerTooltip(marker) {if (marker) {this.allTooltipMarkers.delete(marker);this.visibleTooltipMarkers.delete(marker);}}/*** 清理所有tooltip记录*/clearAllTooltips() {this.allTooltipMarkers.clear();this.visibleTooltipMarkers.clear();}/*** 清理事件监听器*/destroy() {if (this.map) {this.map.off("moveend", this.updateDebounced);this.map.off("zoomend", this.updateDebounced);this.map.off("resize", this.updateDebounced);}this.clearAllTooltips();}/*** 获取统计信息*/getStats() {return {totalMarkers: this.allTooltipMarkers.size,visibleMarkers: this.visibleTooltipMarkers.size,hiddenMarkers: this.allTooltipMarkers.size - this.visibleTooltipMarkers.size,};}
}/*** 使用示例:** // 1. 创建优化器实例* const tooltipOptimizer = new LeafletTooltipOptimizer(map);** // 2. 使用优化后的tooltip绑定方法* markers.forEach(marker => {*     const tooltipContent = `<div>纬度: ${marker.getLatLng().lat}</div><div>经度: ${marker.getLatLng().lng}</div>`;*     const tooltipOptions = {*         permanent: false,*         direction: "top",*         offset: [0, -10]*     };**     // 替换原来的 marker.bindTooltip(content, options)*     tooltipOptimizer.bindTooltipIfVisible(marker, tooltipContent, tooltipOptions);* });** // 3. 在需要清理marker时调用* map.eachLayer(layer => {*     if (layer instanceof L.Marker) {*         tooltipOptimizer.cleanupMarkerTooltip(layer);*         map.removeLayer(layer);*     }* });** // 4. 组件销毁时清理* tooltipOptimizer.destroy();*/export default LeafletTooltipOptimizer;

http://www.dtcms.com/a/305001.html

相关文章:

  • 机器学习-十大算法之一线性回归算法
  • 通用算法与深度学习基础
  • 机器学习课程介绍
  • 机器学习线性回归:从基础到实践的入门指南
  • 机器学习——线性回归(LinearRegression)
  • 出现错误,Microsoft store初始化失败。请尝试刷新或稍后返回。
  • 深入理解异或运算(XOR)及应用
  • 【变更性别】
  • Webpack基本概念及核心流程
  • Docker初学者需要了解的几个知识点(一):传统虚拟机 VS容器
  • vscode开发微信小程序
  • Shader开发(四)计算机图形学中的颜色定义
  • pthread库和thread库
  • 42、鸿蒙HarmonyOS Next开发:应用上下文Context
  • 20250729使用WPS打开xlsx格式的电子表格时候隐藏显示fx的编辑栏的方法
  • Linux ssh服务安装、启动与开机自启
  • ESim电工仿真软件(电脑版)使用说明
  • 在CSS中,如果你想设置一个元素的高度(height)与其宽度(width)相匹配,但又希望宽度使用百分比来定义,你可以通过几种方式来实现。
  • imx6ull-驱动开发篇2——字符设备驱动开发步骤
  • Cursor(编程ai) 使用 - 2025.7.26
  • Linux - 权限的理解(深入浅出,详细细微)
  • 安装新的cuda在bashrc中更新路径
  • Java中的代理
  • 2025年06月03日 Go生态洞察:语法层面的错误处理支持
  • word中rtf格式介绍
  • 游戏分享网站|基于SprinBoot+vue的游戏分享网站系统(源码+数据库+文档)
  • #C语言——学习攻略:深挖指针路线(三)--数组与指针的结合、冒泡排序
  • 前端路由
  • Mysql 图形化界面
  • JVM全面解析