首页>>前端>>JavaScript->JavaScript实现地图轨迹点抽稀

JavaScript实现地图轨迹点抽稀

时间:2023-11-30 本站 点击:1

在处理矢量化数据时,记录中往往会有很多重复数据,对进一步数据处理带来诸多不便。多余的数据一方面浪费了较多的存储空间,另一方面造成所要表达的图形不光滑或不符合标准。因此要通过某种规则,在保证矢量曲线形状不变的情况下, 最大限度地减少数据点个数,这个过程称为抽稀。

起因

公司做的一款应用,要实时显示人员位置,并显示走过的轨迹路线。然而轨迹点太多了,可能一天的数据就会有几千甚至几万个,过多点会影响性能,于是想到了抽稀。

解决方案

使用Douglas-Peuker算法,也称抽稀算法。

该算法是在曲线 起始点S和结束点E 之间连接一条直线SE,该直线为曲线的弦;

首先找到曲线上离直线距离最远的点A,计算其与曲线弦的距离B;

比较该距离与预先给定的阈值threshold的大小,如果小于threshold,则该直线段作为曲线的近似,该段曲线处理完毕;

如果距离大于阈值,则用A将曲线分为两段SA和EA,并分别对两段取信进行第1~3的处理;

当所有曲线都处理完毕时,依次连接各个分割点形成的折线,即可以作为曲线的近似

代码实现

//计算两点间距离functioncalculationDistance(point1,point2){//point1[0]此处的字段要与自己定义的一致,如果是对象,可以如下操作;如果是json数据按照point1.latitude的形式操作constx1=point1[0];consty1=point1[1];constx2=point2[0];consty2=point2[1];constxy=Math.sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));returnxy;}//计算点pX到点pA和pB所确定的直线的距离functiondistToSegment(start,end,center){consta=Math.abs(calculationDistance(start,end));constb=Math.abs(calculationDistance(start,center));constc=Math.abs(calculationDistance(end,center));constp=(a+b+c)/2.0;consts=Math.sqrt(Math.abs(p*(p-a)*(p-b)*(p-c)));return(s*2.0)/a;}//递归方式压缩轨迹functioncompressLine(coordinate,result,start,end,dMax){if(start<end){letmaxDist=0;letcurrentIndex=0;conststartPoint=coordinate[start];constendPoint=coordinate[end];for(leti=start+1;i<end;i++){constcurrentDist=distToSegment(startPoint,endPoint,coordinate[i]);if(currentDist>maxDist){maxDist=currentDist;currentIndex=i;}}if(maxDist>=dMax){//将当前点加入到过滤数组中//console.warn('maxDist'+maxDist);result.push(coordinate[currentIndex]);//将原来的线段以当前点为中心拆成两段,分别进行递归处理compressLine(coordinate,result,start,currentIndex,dMax);compressLine(coordinate,result,currentIndex,end,dMax);}}returnresult;}//供调用的抽稀入口函数/***coordinate原始轨迹Array<{latitude,longitude}>*dMax允许的最大误差距离;默认为10,同时此值需参考currentDist值进行设置,例如currentDist=0.00000134724232,则dMax设置为0.000001比较合适*resultLatLng抽稀后的数据*/functiondouglasPeucker(coordinate,dMax=10){if(!coordinate||!(coordinate.length>2)){returnnull;}coordinate.forEach((item,index)=>{item.id=index;});constresult=compressLine(coordinate,[],0,coordinate.length-1,dMax);result.push(coordinate[0]);result.push(coordinate[coordinate.length-1]);constresultLatLng=result.sort((a,b)=>{if(a.id<b.id){return-1;}elseif(a.id>b.id)return1;return0;});resultLatLng.forEach((item)=>{item.id=0;});returnresultLatLng;}//调用datas=douglasPeucker(newData,0.000001);


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