Расчет долготы центра над 180-м меридианом - PullRequest
0 голосов
/ 13 октября 2018

Я вычисляю простое среднее значение пар широта / долгота, чтобы получить центральную точку (проецируемую на плоскую плоскость), и я изо всех сил пытаюсь разработать алгоритм для правильного учета 180-го меридиана.Я разрабатываю это на PHP.

Я вычисляю простое среднее значение, складываю все долготы и делю на количество.Тем не менее, в ситуации, когда есть, например, точки -175 и 175, он возвращает среднее значение 0, тогда как мне нужно значение 180.

Однажды я попытался прибавить 360 ко всемотрицательные значения, возьмите среднее, а затем вычтите 360. Это решает проблему с 180-м меридианом, но создает ту же проблему с основным меридианом (0 меридиан).

$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 голосов
/ 14 октября 2018

Мне удалось найти надежное решение для моих целей.В моем случае мне просто нужно было вычислить минимальную и максимальную координаты долготы, и если разница превысила 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;
}
...