Найти центр тяжести (простое среднее) множества значений - PullRequest
3 голосов
/ 19 декабря 2011

Я хотел бы использовать JavaScript на стороне клиента, чтобы найти центр тяжести набора широт + долгот (фактически объектов Google LatLng), используя простое вычисление среднего значения.

Я вижу, что подобные вопросы задавались много раз в Stack Overflow, но я не могу найти простой ответ для JavaScript. (Это может быть просто ошибкой моего Google, извинения, если это дубликат.)

У меня есть что-то подобное, но это не работает для случая, когда вы усредняете, скажем, широты 179 и -179, и поэтому центроид должен быть 180, а не 0.

var avg_lat, avg_lng;
for (var i = 0; i < google_latlngs.length; i++) { 
    avg_lat += google_latlngs[0].lat();
    avg_lng += google_latlngs[1].lng();
}
avg_lat = avg_lat / google_latlngs.length; 
avg_lng = avg_lng / google_latlngs.length; 

Мне нужно сделать это эффективно в JavaScript на стороне клиента, и мои очки вряд ли будут находиться на расстоянии более нескольких километров друг от друга, поэтому в этом случае расстояние большого круга или что-то необычное действительно не нужно.

Спасибо за вашу помощь.

ОБНОВЛЕНИЕ: ОК, любой метод для поиска центроида в JavaScript подойдет.

Ответы [ 2 ]

6 голосов
/ 19 декабря 2011

Если вы имеете дело только с 2 точками, убедитесь, что разница между вашими двумя точками широты меньше или равна 180, прежде чем применять вашу функцию. Вы можете сделать это, добавив или вычтя на 360, что изменит -179 на 181 (или 179 на -181). Когда вы получите окончательный результат, добавьте / вычтите на 360, пока окончательное значение не окажется в пределах желаемого диапазона.

Обновление

Если вы хотите, чтобы это работало с более чем двумя точками, нам нужно сделать некоторую геометрию. Мы рассматриваем каждую точку широты как точку на единичном круге с определенным расстоянием x и y от начала координат и определенным углом a (широта):

Latitude on a unit circle

Мы должны усреднить все x и y, а затем взять угол полученной точки, чтобы получить нашу окончательную широту для центроида. Вот JavaScript:

var latXTotal = 0;
var latYTotal = 0;
var lonDegreesTotal = 0;

var currentLatLong;
for (var i = 0; currentLatLong = google_latlngs[i]; i++) { 
    var latDegrees = currentLatLong.lat();
    var lonDegrees = currentLatLong.lng();

    var latRadians = Math.PI * latDegrees / 180;
    latXTotal += Math.cos(latRadians);
    latYTotal += Math.sin(latRadians);

    lonDegreesTotal += lonDegrees;
}

var finalLatRadians = Math.atan2(latYTotal, latXTotal);
var finalLatDegrees = finalLatRadians * 180 / Math.PI;

var finalLonDegrees = lonDegreesTotal / google_latlngs.length;
0 голосов
/ 19 декабря 2011

Я не уверен, что правильно понял алгоритм, но попробую:

var avg_lat, avg_lng;
for (var i = 0; i < google_latlngs.length; i++) { 
    avg_lat += (google_latlngs[0].lat() > 0 ? google_latlngs[0].lat() : 360 + google_latlngs[0].lat());
    avg_lng += (google_latlngs[1].lng() > 0 ? google_latlngs[1].lng() : 360 + google_latlngs[1].lng());
}
avg_lat = avg_lat / google_latlngs.length; 
avg_lng = avg_lng / google_latlngs.length; 

Если это правильно, то среднее значение от -44 до +45 равно 180,5 - это яЯ обеспокоенЯ бы сказал, что среднее значение для -44 и +45 составляет 0,5.Поправь меня, если я ошибаюсь.

...