PHP 将百度地图上的一条线的点位进行平滑处理,画出一条曲线

/**
    *将一条地图上的线平滑
    *@param  originPoint:点位数组    
    *@method POST
    *@return aray curvePoint
    */
    public function createCurve($originPoint){  
        $curvePoint = [];  //返回的数组
        //$originPoint = [['LON'=>116.394855,'LAT'=>39.987338],['LON'=>116.419145,'LAT'=>39.998835],['LON'=>116.444154,'LAT'=>39.996348],['LON'=>116.462407,'LAT'=>39.981146]];
        $originCount = count($originPoint);
        $scale = 0.4;   //平滑系数
        
        $midpoints = [];    //创建一个长度是$originCount的空数组$midpoints
        for ($i=0; $i < $originCount; $i++) { 
            $midpoints[$i] = [];
        }
        //生成中点       
        for($i = 0 ;$i < $originCount ; $i++){      
            $nexti = ($i + 1) % $originCount;  
            $midpoints[$i]['LON'] = ($originPoint[$i]['LON'] + $originPoint[$nexti]['LON'])/2.0;  
            $midpoints[$i]['LAT'] = ($originPoint[$i]['LAT'] + $originPoint[$nexti]['LAT'])/2.0;  
        }      
          //var_dump($midpoints);die;
        //平移中点  
        $extrapoints = [];      //创建一个2 * originCount的空数组$extrapoints
        //for ($i=0; $i < 2; $i++) { 
             /*for ($j=0; $j < $originCount; $j++) { 
                $extrapoints[$j] = ['LON'=>'','LAT'=>''];
            }*/
         //} 
        for($i = 0 ;$i < $originCount ; $i++){  
             $nexti = ($i + 1) % $originCount;  
             $backi = ($i + $originCount - 1) % $originCount;  
             $midinmid = []; 
             $midinmid['LON'] = ($midpoints[$i]['LON'] + $midpoints[$backi]['LON'])/2.0;  
             $midinmid['LAT'] = ($midpoints[$i]['LAT'] + $midpoints[$backi]['LAT'])/2.0;  
             $offsetx = $originPoint[$i]['LON'] - $midinmid['LON'];  
             $offsety = $originPoint[$i]['LAT'] - $midinmid['LAT'];  
             /*var_dump($originPoint[$i]['LON']);
               echo $scale;echo "<br />";
               var_dump($midinmid['LON']);echo "<br />";*/
             $extraindex = 2 * $i;  
             $extrapoints[$extraindex]['LON'] = $midpoints[$backi]['LON'] + $offsetx;  
             $extrapoints[$extraindex]['LAT'] = $midpoints[$backi]['LAT'] + $offsety;  
             //朝 originPoint[i]方向收缩   
             $addx = ($extrapoints[$extraindex]['LON'] - $originPoint[$i]['LON']) * $scale;  
             $addy = ($extrapoints[$extraindex]['LAT'] - $originPoint[$i]['LAT']) * $scale;  
             $extrapoints[$extraindex]['LON'] = $originPoint[$i]['LON'] + $addx;  
             $extrapoints[$extraindex]['LAT'] = $originPoint[$i]['LAT'] + $addy;  
                /*var_dump($extrapoints[$extraindex]['LON']);
               echo $scale;echo "<br />";
               var_dump($originPoint[$i]['LON']);echo "<br />";*/
             $extranexti = ($extraindex + 1)%(2 * $originCount);  
             $extrapoints[$extranexti]['LON'] = $midpoints[$i]['LON'] + $offsetx;  
             $extrapoints[$extranexti]['LAT'] = $midpoints[$i]['LAT'] + $offsety;  
             //朝 originPoint[i]方向收缩   
             $addx = ($extrapoints[$extranexti]['LON'] - $originPoint[$i]['LON']) * $scale;  
             $addy = ($extrapoints[$extranexti]['LAT'] - $originPoint[$i]['LAT']) * $scale;  
             $extrapoints[$extranexti]['LON'] = $originPoint[$i]['LON'] + $addx;  
             $extrapoints[$extranexti]['LAT'] = $originPoint[$i]['LAT'] + $addy;  
               
        }      
          
        $controlPoint = [];    //创建一个长度是4的数组$controlPoint
        for ($i=0; $i < 4; $i++) { 
            $controlPoint[$i] = [];
        }
        //生成4控制点,产生贝塞尔曲线  
        for($i = 0 ;$i < $originCount ; $i++){  
               $controlPoint[0] = $originPoint[$i];  
               $extraindex = 2 * $i;  
               $controlPoint[1] = $extrapoints[$extraindex + 1];  
               $extranexti = ($extraindex + 2) % (2 * $originCount);  
               $controlPoint[2] = $extrapoints[$extranexti];  
               $nexti = ($i + 1) % $originCount;  
               $controlPoint[3] = $originPoint[$nexti];      
               $u = 1;  
               while($u >= 0){  
                   $px = $this->bezier3funcX($u,$controlPoint);  
                   $py = $this->bezier3funcY($u,$controlPoint);  
                   //u的步长决定曲线的疏密  
                   $u -= 0.05;  
                   $tempP = ['LON'=>$px,'LAT'=>$py];
                   
                   //存入曲线点   
                   $curvePoint[] = $tempP;
               }      
        }  

        //var_dump($curvePoint);
        foreach ($curvePoint as $key => $value) {
           if($key>(count($curvePoint)-31)){
                unset($curvePoint[$key]);
           }
        }
        //var_dump($curvePoint);die;
        foreach ($curvePoint as $key => $value) {
           if( $key>0 && $key<10  ){
                unset($curvePoint[$key]);
           }
        }
        $curvePoint[] = $originPoint[count($originPoint)-1];
        $curvePoint = array_values($curvePoint);
        //var_dump($curvePoint);
        /*$str = '';
        foreach ($curvePoint as $key => $value) {
           // $str .= '['.$value['LON'].','.$value['LAT'].'],';
           $str .= 'new BMap.Point('.$value['LON'].', '.$value['LAT'].'),';

        }
        $str = rtrim($str,',');
        echo $str;*/
        return $curvePoint;
    }  
    //三次贝塞尔曲线  
    private function bezier3funcX($uu,$controlP){  
       $part0 = $controlP[0]['LON'] * $uu * $uu * $uu;  
       $part1 = 3 * $controlP[1]['LON'] * $uu * $uu * (1 - $uu);  
       $part2 = 3 * $controlP[2]['LON'] * $uu * (1 - $uu) * (1 - $uu);  
       $part3 = $controlP[3]['LON'] * (1 - $uu) * (1 - $uu) * (1 - $uu);     
       return $part0 + $part1 + $part2 + $part3;   
    }      
    private function bezier3funcY($uu,$controlP){  
       $part0 = $controlP[0]['LAT'] * $uu * $uu * $uu;  
       $part1 = 3 * $controlP[1]['LAT'] * $uu * $uu * (1 - $uu);  
       $part2 = 3 * $controlP[2]['LAT'] * $uu * (1 - $uu) * (1 - $uu);  
       $part3 = $controlP[3]['LAT'] * (1 - $uu) * (1 - $uu) * (1 - $uu);     
       return $part0 + $part1 + $part2 + $part3;   
    }   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值