Приближенное решение (на основе равносторонней проекции), намного быстрее (для этого требуется только 1 триг и 1 квадратный корень).
Это приближение уместно, если ваши точки не слишком далеко друг от друга. Он будет всегда переоценивать по сравнению с реальным расстоянием хаверсин. Например, он добавит не более 0,05382% к реальному расстоянию, если разность широты или долготы между вашими двумя точками не превышает 4 десятичных градуса .
Стандартная формула (Haversine) - это точная единица (то есть она работает для любой пары долготы / широты на земле), но она намного медленнее , поскольку ей требуется 7 тригонометрических и 2 квадратных корня. Если ваша пара точек не слишком далеко друг от друга, и абсолютная точность не имеет первостепенного значения, вы можете использовать эту приблизительную версию (Equirectangular), которая намного быстрее, поскольку она использует только один тригонометрический и один квадратный корень.
// Approximate Equirectangular -- works if (lat1,lon1) ~ (lat2,lon2)
int R = 6371; // km
double x = (lon2 - lon1) * Math.cos((lat1 + lat2) / 2);
double y = (lat2 - lat1);
double distance = Math.sqrt(x * x + y * y) * R;
Вы можете оптимизировать это далее любым из следующих способов:
- Удаление квадратного корня , если вы просто сравниваете расстояние с другим (в этом случае сравниваете оба квадрата расстояния);
- Вычисление косинуса , если вы вычисляете расстояние от одной мастер-точки до многих других (в этом случае вы делаете равностороннюю проекцию с центром в мастер-точке, так что вы можете вычислить косинус один раз для всех сравнения).
Для получения дополнительной информации см .: http://www.movable -type.co.uk / scripts / latlong.html
Хорошая справочная реализация формулы Хаверсайна на нескольких языках: http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe