码迷,mamicode.com
首页 > 编程语言 > 详细

道格拉斯-普克算法(JavaScript实现)

时间:2018-10-24 00:58:04      阅读:241      评论:0      收藏:0      [点我收藏+]

标签:content   tran   asc   技术   rip   null   gps   asp   javascrip   

需求:

有时候当移动速度很慢,GPS定位的轨迹点就非常的多,这时候为了缩减数据量,需要将不突出的点去掉。

思路:

  (1) 在曲线首尾两点间虚连一条直线,求出其余各点到该直线的距离。

(2)选其最大者与阈值相比较,若大于阈值,则离该直线距离最大的点保留,否则将直线两端点间各点全部舍去。
(3)依据所保留的点,将已知曲线分成两部分处理,重复第1、2步操作,迭代操作,即仍选距离最大者与阈值比较,依次取舍,直到无点可舍去,最后得到满足给定精度限差的曲线点坐标
技术分享图片

 

这里使用道格拉斯-普克算法实现,易于理解。效果图如下,:

技术分享图片

 

源代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
   <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
   <title>DouglasPeucker</title>    
</head>
<body>
   <canvas id="drawing" style="height:300px;width:100%"></canvas>
    <canvas id="drawing2" style="height:300px;width:100%"></canvas>
</body>
<script type="text/javascript" >

    var points1=[];
    var pointsshao=[];
    var pts=[]; 
    var hval=30;//阀值
    
    //随机生成1000个点
    for(var i=0;i<1000;i++){
    var  oldx=i*10,oldy=Math.random()*150;
      points1.push([oldx,oldy,i]);
    }
    
    //求斜率
    function xielv(pt1,pt2)
    {
      var k,b;
      var canshu={};
      canshu.k=(pt1[1]-pt2[1])/(pt1[0]-pt2[0]);
      canshu.b=pt1[1]-canshu.k*pt1[0];
      return canshu;
    }
    //求点到直线的距离
    function distanceToline(pt,cs){
       return (Math.abs(cs.k*pt[0]-pt[1]+cs.b))/Math.sqrt(cs.k*cs.k+1);
    }
    
    //开始计算(道格拉斯普克算法)
    pts.push(points1[0]);
    countPoint(points1);
    pts.push(points1[points1.length-1]);

    //排序
    function sort(pts){
      for(var i=0;i<pts.length-1;i++)
      {
         var a=pts[i];
         var b=pts[i+1];
         if(b[2]>a[2]){
         pts[i]=b;
         pts[i+1]=a;
         for(var j=i;j>0;j--)
         {
             var c=pts[j-1];
             if(b[2]>c[2]){
               pts[j-1]=b;
               pts[j]=c;
             }
         }
         }
      }
    }
    
 function countPoint(points){
 
       var maxD=0;
       var maxPoint=null;
       var maxindex=0;
       //大于2个点才开始计算
       if(points.length>2){
             var pt1=points[0];
           var pt2=points[points.length-1];
           var cs=xielv(pt1,pt2);
           for(var i=0;i<points.length;i++){
             var pt=points[i];
             var dis=distanceToline(pt,cs);
            //判断该线段中是否有点到由该线段端点组成的直线的距离大于限值
             if(dis>maxD)
             {
               maxD=dis;
               maxPoint=pt;
               maxindex=i;
             }
           }
               if(maxD>hval) //如果最大值就从该点位置将线段进行切分
             {
                 var pts1=points.slice(maxindex);//中分末尾数组
                 var pts2=points.slice(0,maxindex+1);//中分前面数组
                if(pts1.length>2 && pts2.length>2)
                {
                 if(!countPoint(pts1) && !countPoint(pts2)){  //如果两个线段都没有超过限制就结束计算
                   pts.push(maxPoint);
                 }
                }else if(pts1.length>2 && pts2.length<=2){ //计算pts1
                    if(!countPoint(pts1))pts.push(maxPoint);
                    
                }else if(pts1.length<=2 && pts2.length>2){ //计算pts2
                   if(! countPoint(pts2))pts.push(maxPoint);
                    
                }
             } return false;
       }
     }
    //由大到小
    sort(pts);
    drawWay("drawing2",pts);
    drawWay("drawing",points1)
    function drawWay(name,points){
      var drawing=document.getElementById(name);
      if(drawing.getContext){
        var context=drawing.getContext("2d");
        context.beginPath();
        var oldx=points[0][0];
        var oldy=points[0][1];
        for(var i=0;i<points.length;i++){
          var p=points[i];
          context.moveTo(oldx,oldy);
          oldx=p[0];
          oldy=p[1];
          context.lineTo(oldx,oldy);
       }
       context.closePath();
       context.stroke();
    }
}
</script>

 

道格拉斯-普克算法(JavaScript实现)

标签:content   tran   asc   技术   rip   null   gps   asp   javascrip   

原文地址:https://www.cnblogs.com/GIScore/p/9840454.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!