基于Openlayers3的地图轨迹及其优化

2023-11-02 00:10

本文主要是介绍基于Openlayers3的地图轨迹及其优化,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、背景
项目线上系统经常出现一个问题,当地图轨迹点较多后者出现跨度较大的跳跃点时,地图缩放轨迹计算会导致浏览器比较卡,非常影响用户体验,根本原因是因为地图轨迹在进行缩放时,会在前端重新计算轨迹箭头图层的位置信息,当看到计算入口代码时,发现计算比较暴力,计算时间复杂度太高,需要进行优化,通过网上查询,发现一个博主的做法能有效降低计算的时间复杂度(https://blog.csdn.net/freeland1/article/details/82113809),但实践后发现其存在一个问题,当存在两个点间来回的轨迹时,其做法只能显示一个方向的箭头,没有展示反向的箭头。

二、轨迹绘制及优化

组件地址
openlayershttps://openlayers.org/
rbushhttps://unpkg.com/rbush@2.0.1/rbush.min.js

注意:openlayers版本需v3.13.0及以上,低版本不支持不支持getCoordinateAt方法

附地图缩放时,轨迹箭头更新逻辑代码:

	/***地图缩放时,更新轨迹箭头*/updateTrackArrowStyle: function (geometry, lineWidth, lineColor, arrowIcon) {var _this = this;var trackLine = geometry;var zoom = window.map.getView().getZoom();var distance = 57*(19-zoom)*(19-zoom);//箭头间隔随地图层级变化var styles = [new ol.style.Style({stroke: new ol.style.Stroke({color: lineColor,width: lineWidth})})];var length = _this.getLineLength(trackLine);if(length < 2 * distance){if(length < distance){distance = length / 3;}else{distance = length / 4;}}//对segments建立btree索引var tree = rbush();//路段数var max_num = 1;var geomLength = 0;trackLine.forEachSegment(function(start, end) {var dx = end[0] - start[0];var dy = end[1] - start[1];var rotation = Math.atan2(dy, dx);var geom = new ol.geom.LineString([start,end]);var extent = geom.getExtent();geomLength += _this.getLineLength(geom);var min_num = max_num;max_num = parseInt(geomLength / distance);//计算每一段轨迹上箭头在整段轨迹中的索引var item = {minX: extent[0],minY: extent[1],maxX: extent[2],maxY: extent[3],geom: geom,min_num: min_num,max_num: max_num,rotation_o : null,rotation_n : null,rotation: rotation};tree.insert(item);});var recExtent = map.getView().calculateExtent(map.getSize());//箭头总数var arrowsNum = parseInt(length / distance);var isRepeat = true;for(var i = 1;i < arrowsNum;i++){var arrowIcon = arrowIcon;var arraw_coor = trackLine.getCoordinateAt(i*1.0/arrowsNum);var tol = 0.1;var arraw_coor_buffer = [arraw_coor[0]-tol,arraw_coor[1]-tol,arraw_coor[0]+tol,arraw_coor[1]+tol];//进行btree查询var treeSearch = tree.search({minX: arraw_coor_buffer[0],minY: arraw_coor_buffer[1],maxX: arraw_coor_buffer[2],maxY: arraw_coor_buffer[3]});var arrow_rotation;if(treeSearch.length == 1){isRepeat = true;arrow_rotation = treeSearch[0].rotation;}else if(treeSearch.length > 1){var results = treeSearch.filter(function(item){var _tol = 0.1;//消除精度误差的容差if(item.geom.intersectsExtent([arraw_coor[0]-_tol, arraw_coor[1]-_tol, arraw_coor[0]+_tol, arraw_coor[1]+_tol]))return true;})if(results.length > 0){for(var j = 0;j < results.length;j++){if(i >= results[j].min_num && i <= results[j].max_num){//判断箭头是否在该段轨迹上if(i == results[j].min_num + 1){if(!results[j].rotation_o){isRepeat = true;for(var k=0;k<results.length;k++){results[k].rotation_o = results[j].rotation;}}else if(results[j].rotation_o == results[j].rotation){isRepeat = false;}else if(!results[j].rotation_n){isRepeat = true;for(var k=0;k<results.length;k++){results[k].rotation_n = results[j].rotation;}}else if(results[j].rotation_n == results[j].rotation){isRepeat = false;}}arrow_rotation = results[j].rotation;break;}}}}if(isRepeat){//判断是否已显示,当轨迹来回次数比较多时,如果不去冲,会在轨迹上堆积很多箭头styles.push(new ol.style.Style({geometry: new ol.geom.Point(arraw_coor),image: new ol.style.Icon({src: arrowIcon,anchor: [0.75, 0.5],rotateWithView: false,rotation: -arrow_rotation})}));}}return styles;},/***计算轨迹长度*/getLineLength : function(line){var coordinates = line.getCoordinates();var length = 0;var sourceProj = map.getView().getProjection();for (var i = 0, ii = coordinates.length - 1; i < ii; ++i) {var c1 = ol.proj.transform(coordinates[i], sourceProj, 'EPSG:4326');var c2 = ol.proj.transform(coordinates[i + 1], sourceProj, 'EPSG:4326');length += new ol.Sphere(6378137).haversineDistance(c1, c2);}return (Math.round(length * 100) / 100);}

三、效果图
1、无来回点
在这里插入图片描述
2、有来回点
在这里插入图片描述

如果您有好的改进建议,还请留言,不吝赐教!

这篇关于基于Openlayers3的地图轨迹及其优化的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/326747

相关文章

Deepseek使用指南与提问优化策略方式

《Deepseek使用指南与提问优化策略方式》本文介绍了DeepSeek语义搜索引擎的核心功能、集成方法及优化提问策略,通过自然语言处理和机器学习提供精准搜索结果,适用于智能客服、知识库检索等领域... 目录序言1. DeepSeek 概述2. DeepSeek 的集成与使用2.1 DeepSeek API

Tomcat高效部署与性能优化方式

《Tomcat高效部署与性能优化方式》本文介绍了如何高效部署Tomcat并进行性能优化,以确保Web应用的稳定运行和高效响应,高效部署包括环境准备、安装Tomcat、配置Tomcat、部署应用和启动T... 目录Tomcat高效部署与性能优化一、引言二、Tomcat高效部署三、Tomcat性能优化总结Tom

解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)

《解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)》该文章介绍了使用Redis的阻塞队列和Stream流的消息队列来优化秒杀系统的方案,通过将秒杀流程拆分为两条流水线,使用Redi... 目录Redis秒杀优化方案(阻塞队列+Stream流的消息队列)什么是消息队列?消费者组的工作方式每

Oracle查询优化之高效实现仅查询前10条记录的方法与实践

《Oracle查询优化之高效实现仅查询前10条记录的方法与实践》:本文主要介绍Oracle查询优化之高效实现仅查询前10条记录的相关资料,包括使用ROWNUM、ROW_NUMBER()函数、FET... 目录1. 使用 ROWNUM 查询2. 使用 ROW_NUMBER() 函数3. 使用 FETCH FI

C#使用HttpClient进行Post请求出现超时问题的解决及优化

《C#使用HttpClient进行Post请求出现超时问题的解决及优化》最近我的控制台程序发现有时候总是出现请求超时等问题,通常好几分钟最多只有3-4个请求,在使用apipost发现并发10个5分钟也... 目录优化结论单例HttpClient连接池耗尽和并发并发异步最终优化后优化结论我直接上优化结论吧,

Java内存泄漏问题的排查、优化与最佳实践

《Java内存泄漏问题的排查、优化与最佳实践》在Java开发中,内存泄漏是一个常见且令人头疼的问题,内存泄漏指的是程序在运行过程中,已经不再使用的对象没有被及时释放,从而导致内存占用不断增加,最终... 目录引言1. 什么是内存泄漏?常见的内存泄漏情况2. 如何排查 Java 中的内存泄漏?2.1 使用 J

MySQL不使用子查询的原因及优化案例

《MySQL不使用子查询的原因及优化案例》对于mysql,不推荐使用子查询,效率太差,执行子查询时,MYSQL需要创建临时表,查询完毕后再删除这些临时表,所以,子查询的速度会受到一定的影响,本文给大家... 目录不推荐使用子查询和JOIN的原因解决方案优化案例案例1:查询所有有库存的商品信息案例2:使用EX

MySQL中my.ini文件的基础配置和优化配置方式

《MySQL中my.ini文件的基础配置和优化配置方式》文章讨论了数据库异步同步的优化思路,包括三个主要方面:幂等性、时序和延迟,作者还分享了MySQL配置文件的优化经验,并鼓励读者提供支持... 目录mysql my.ini文件的配置和优化配置优化思路MySQL配置文件优化总结MySQL my.ini文件

正则表达式高级应用与性能优化记录

《正则表达式高级应用与性能优化记录》本文介绍了正则表达式的高级应用和性能优化技巧,包括文本拆分、合并、XML/HTML解析、数据分析、以及性能优化方法,通过这些技巧,可以更高效地利用正则表达式进行复杂... 目录第6章:正则表达式的高级应用6.1 模式匹配与文本处理6.1.1 文本拆分6.1.2 文本合并6

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义