当前位置: 首页 > 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.lryc.cn/news/603394.html

相关文章:

  • HTTP 与 HTTPS 的区别
  • div 封装日历
  • C++学习之继承
  • scrapy框架新浪新闻
  • linux中简易云盘系统项目实战:基于 TCP协议的 Socket 通信、json数据交换、MD5文件区别与多用户文件管理实现
  • uniapp 微信小程序 列表点击分享 不同的信息
  • YOLO--目标检测基础
  • 计算机视觉-图像基础处理
  • TailWindCss安装使用教程
  • eudev是什么东西,有什么作用
  • 1768. 交替合并字符串
  • 无线网络优化实践
  • [学习记录]URP流程解析(2)--初始化阶段
  • 虚拟机网络修复
  • 充电宝自燃隐患引发关注:如何确保充电宝安全?
  • 门控激活函数:GLU/GTU/Swish/HSwish/Mish/SwiGLU
  • 机器学习sklearn:泰坦尼克幸存预测(决策树、网格搜索找最佳参数)
  • 【深度学习新浪潮】什么是世界模型?
  • fastApi中的ocr
  • 译 | 介绍PyTabKit:一个试图超越 Scikit-Learn的新机器学习库
  • 如何查询并访问路由器的默认网关(IP地址)?
  • 主应用严格模式下,子应用组件el-date-picker点击无效
  • 【Dify】-进阶14- 用 Dify 搭建法律文档解析助手
  • Vue.js 指令系统完全指南:深入理解 v- 指令
  • 智能图书馆管理系统开发实战系列(一):项目架构设计与技术选型
  • Ubuntu上开通Samba网络共享
  • Ambari 3.0.0 全网首发支持 Ubuntu 22!
  • Kafka——消费者组重平衡全流程解析
  • cpolar 内网穿透 ubuntu 使用石
  • Spark SQL 数组函数合集:array_agg、array_contains、array_sort…详解