/**
*将一条地图上的线平滑
*@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;
}