Приближенное решение (на основе равнопрямоугольной проекции) намного быстрее (требуется только 1 триггер и 1 квадратный корень).
Это приближение актуально, если ваши точки не слишком далеко друг от друга. Он всегда будет завышен по сравнению с реальным гаверсинусным расстоянием. Например, это добавит не более 0,05382% к реальному расстоянию, если дельта широты или долготы между вашими двумя точками не превышает 4 десятичных градуса .
Стандартная формула (Хаверсинус) является точной (то есть она работает для любой пары долготы / широты на Земле), но намного медленнее, так как для этого требуется 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