计算第180个子午线上的经度中心

时间:2018-10-13 19:33:31

标签: php geography

我正在计算纬度/经度对的简单平均值来获取中心点(投影在平面上),并且我正在努力开发一种算法来正确地计算第180个子午线。我正在用PHP开发。

我正在计算一个简单的平均值,将所有经度相加并除以计数。但是,在有-175和175点的情况下,它返回的平均值为0,而我需要的值为180。

我尝试的方法是将360加到所有负值上,取平均值,然后减去360。这解决了第180个子午线上的问题,但它对本初子午线(0个子午线上)产生了相同的问题。 / p>

$neg_lng_flag = false;
//calculate centerpoint
$i = 0;
while($i < $vertice_count) {
    $lat_sum += $vertice_obj[$i]->lat;
    //if lng is negative, add 360
    if($vertice_obj[$i]->lng < 0) {
        $lng_sum += $vertice_obj[$i]->lng + 360;
        $neg_lng_flag = true;
    } else {
        $lng_sum += $vertice_obj[$i]->lng;
    }
    $i++;
}
$avg_lat = round($lat_sum / $vertice_count,2);
$avg_lng = round($lng_sum / $vertice_count,2);

if($neg_lng_flag) {
    $avg_lng = $avg_lng - 360;
    if($avg_lng < -180) {
        $avg_lng = $avg_lng + 180;
    }
}

我不确定我能做些什么来得出一致的算法来返回所有情况下的真实中心纵向点。无论是在这里还是通过Google,我都无法找到可靠的解决方案。我将不胜感激任何外部考虑/想法。谢谢。

1 个答案:

答案 0 :(得分:0)

我能够为我的目的提供一个可靠的解决方案。就我而言,我只需要计算最小和最大经度坐标,并且如果差值超过180,我就知道将负值移动+360,然后计算平均值。如果平均值大于180,则需要减去360;如果平均值小于-180,则需要加上360。

//COMPUTE LONGITUDAL MIDPOINT
function getLngMidpoint($vertice_obj) {
    //get min and max vals
    $i = 0;
    while($i < count($vertice_obj)) {
        $min = $vertice_obj[$i]->lng;
        $max = $vertice_obj[$i]->lng;

        if($vertice_obj[i]->lng > $max) {
            $max = $vertice_obj[$i]->lng;
        }
        if($vertice_obj[$i]->lng < $min) {
            $min = $vertice_obj[$i]->lng;
        }

        $i += 1;
    }

    $shift = 0;
    //check if distance between min and max > 180. If so, need to shift
    if(($max - $min) > 180) {
        //shift all lng by 180
        $shift = 360;
    }

    $i = 0;
    $sum_lng = 0;
    while($i < count($vertice_obj)) {
        if($vertice_obj[$i] < 0) {
            $sum_lng += $vertice_obj[$i]->lng + $shift;
        } else {
            $sum_lng += $vertice_obj[$i]->lng;
        }
        $i += 1;
    }

    $avg_lng = $sum_lng / count($vertice_obj);
    if($avg_lng > 180) {
        $avg_lng = $avg_lng - 360;
    }
    if($avg_lng < -180) {
        $avg_lng = $avg_lng + 360;
    }

    return $avg_lng;
}