php多個經緯度合併

//start----------------------合併多個經緯度點--------------------------------

/**
 * 求兩個已知經緯度之間的距離,單位爲米
 * @param lng1 $ ,lng2 經度
 * @param lat1 $ ,lat2 緯度
 * @return float 距離,單位米
 */
function getDistance($lng1, $lat1, $lng2, $lat2) {
    // 將角度轉爲狐度
    $radLat1 = deg2rad($lat1); //deg2rad()函數將角度轉換爲弧度
    $radLat2 = deg2rad($lat2);
    $radLng1 = deg2rad($lng1);
    $radLng2 = deg2rad($lng2);
    $a = $radLat1 - $radLat2;
    $b = $radLng1 - $radLng2;
    $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6378.137 * 1000;
    return $s;
}


/*
 * 合併多個經緯度點,獲取中心座標
 * @param   data        需要合併的經緯度點數組
 * @param   latName     data中緯度的鍵名
 * @param   lngName     data中經度的鍵名
 * @return  newData     合併後的經緯度
 *              num爲原本座標數
 *      形式 :
 *          Array (['count']=>num, [$latName] => 45.813538469271, [$lngName] => 75.682996448603 )
 * */
function getCenterFromDegrees($data,$latName,$lngName){

    if (!is_array($data)) return FALSE;

    $num_coords = count($data);

    $X = 0.0;
    $Y = 0.0;
    $Z = 0.0;

    foreach ($data as $coord){

        $lat = deg2rad((float)$coord[$latName]);
        $lon = deg2rad((float)$coord[$lngName]);

        $a = cos($lat) * cos($lon);
        $b = cos($lat) * sin($lon);
        $c = sin($lat);

        $X += $a;
        $Y += $b;
        $Z += $c;
    }

    $X /= $num_coords;
    $Y /= $num_coords;
    $Z /= $num_coords;

    $lon = atan2($Y, $X);
    $hyp = sqrt($X * $X + $Y * $Y);
    $lat = atan2($Z, $hyp);

    return array('count'=>count($data), $latName=>rad2deg($lat), $lngName=>rad2deg($lon));
}

/*
 * 合併多個經緯度點
 * @param   data        需要合併的經緯度點一維數組
 * @param   distance    指定經緯度點間距離小於多少合併
 * @param   latName     data中緯度的鍵名
 * @param   lngName     data中經度的鍵名
 * @return  newData     經緯度合併後的新數組
 * */
function coordMerge($data,$distance,$latName,$lngName,$centerSpot=[])
{
    if (count($data) <= 0){
        return $centerSpot;
    }
    //獲取合併基礎
    if (count($data)>0) {
        $basics = $data[0];
        unset($data[0]);
        if (count($data)>0){
            //聲明接收符合條件的數組
            $mergeData = [];
            $mergeData[] = $basics;
            foreach ($data as $k => $v) {
                //獲取兩個經緯度間距離
                $dis = getDistance($basics[$lngName], $basics[$latName], $v[$lngName], $v[$latName]);
                //判斷是否符合要求
                if ($dis < $distance) {
                    $mergeData[] = $v;
                    unset($data[$k]);
                }
            }
            //合併在一定範圍內的經緯度
            $centerSpot[] = getCenterFromDegrees($mergeData, $latName, $lngName);
            //遞歸執行
            $data = array_values($data);
            //此處爲遞歸時返回需要加上return
            return coordMerge($data, $distance, $latName, $lngName, $centerSpot);
        } else {
            $one[$latName] = $basics[$latName];
            $one[$lngName] = $basics[$lngName];
            $centerSpot[] = $one;
        }
    }



}



//end-------------------------合併多個經緯度點-------------------------------

使用時調用coordMerge即可。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章