Uma solução aproximada (baseada em uma projeção equirretangular), muito mais rápida (requer apenas 1 trigonometria e 1 raiz quadrada).
Esta aproximação é relevante se seus pontos não estiverem muito distantes. Ele sempre superestimará em comparação com a distância real do haversine. Por exemplo, não adicionará mais do que 0,05382% à distância real se a latitude delta ou longitude entre seus dois pontos não exceder 4 graus decimais .
A fórmula padrão (Haversine) é a exata (ou seja, funciona para qualquer par de longitude / latitude na Terra), mas é muito mais lenta , pois precisa de 7 raízes trigonométricas e 2 raízes quadradas. Se seus dois pontos não estiverem muito distantes e a precisão absoluta não for fundamental, você pode usar esta versão aproximada (Equirretangular), que é muito mais rápida, pois usa apenas um trigonométrico e uma raiz quadrada.
// 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;
Você pode otimizar ainda mais :
- Remover a raiz quadrada se você simplesmente comparar a distância com outra (nesse caso, compare ambas as distâncias quadradas);
- Fatorar o cosseno se você calcular a distância de um ponto mestre a muitos outros (nesse caso, você faz a projeção equirretangular centrada no ponto mestre, de modo que pode calcular o cosseno uma vez para todas as comparações).
Para obter mais informações, consulte: http://www.movable-type.co.uk/scripts/latlong.html
Há uma boa implementação de referência da fórmula Haversine em vários idiomas em: http://www.codecodex.com/wiki/Calculate_Distance_Between_Two_Points_on_a_Globe