Seja usando vincenty ou haversine ou a lei esférica dos cossenos, há sabedoria em tomar conhecimento de possíveis problemas com o código que você planeja usar, coisas a observar e mitigar e como lidar com questões vincenty vs haversine vs sloc diferirá à medida que se tornar ciente dos problemas / edgecases ocultos de cada um, que podem ou não ser conhecidos popularmente. O programador experiente sabe disso. Iniciantes não podem. Espero poupar alguns deles de frustração quando um trecho de um fórum faz algo inesperado, em certos casos. Se alguém usar seriamente alguma versão de qualquer um desses, vincenty, haversine, sloc, SE, SO, Reddit, Quora, etc., poderá ter fornecido ajuda limitada em alguma codificação inicial de uma solução, mas isso não significa que sua solução ou 'resposta' aceita está livre de problemas. Se um projeto é importante o suficiente, ele merece uma quantidade razoável e razoável de pesquisa. Leia o manual, leia os documentos e, se houver uma revisão desse código, leia-o. Copiar e colar um snippet ou essência que foi votado cem ou mais vezes não significa que sua segurança seja abrangente e garantida.
A resposta intrigante postada pelo cffk levanta o ponto de estar ciente de que as coisas estão à espreita, em soluções empacotadas, que podem produzir exceções ou outras dificuldades . As reivindicações específicas feitas nesse post estão além do meu orçamento de tempo a ser perseguido no momento, mas retiro que há realmente problemas ocultos em determinados pacotes, incluindo pelo menos uma implementação vincenty, sobre a qual pelo menos uma pessoa propôs melhorar de uma maneira ou de outra, a fim de minimizar ou eliminar o risco de encontrar essas dificuldades. Não acrescentarei mais a esse tópico referente à vincenty (sendo muito ignorante), mas, em vez disso, me voltarei para o haversine, pelo menos em parte no tópico com o OP.
A fórmula haversine popularmente publicada, seja em python ou em outra linguagem, porque provavelmente usará a especificação de ponto flutuante IEEE 754 na maioria dos sistemas intel e afins da atualidade, além de processadores ARM, powerPC, etc. também ser suscetível a erros de exceção raros, reais e repetíveis, muito próximos ou a uma distância de arco de 180 graus, pontos antipodais, devido a aproximações e arredondamentos de pontos flutuantes. Alguns iniciantes ainda podem não ter sido mordidos por essa situação. Como essa especificação fp se aproxima e arredonda, isso não significa que qualquer código que chama fp64 possa causar erros de exceção, não. Mas algum código, algumas fórmulas podem não ter resultados tão óbvios em que as aproximações e os arredondamentos do IEEE 754 fp64 podem fazer com que um valor se desvie um pouco do domínio de um método matemático que se espera que avalie esse valor na perfeição. Um exemplo ... sqrt (). Se um valor negativo chegar a um sqrt (), como sqrt (-0.00000000000000000122739), haverá um erro de exceção. Na fórmula haversine, a maneira pela qual ela progride em direção a uma solução, existem dois métodos sqrt () no atan2 (). oum que é calculado e depois usado no sqrt (), pode, nos pontos antipodais do globo, desviar-se ligeiramente abaixo de 0,0 ou acima de 1,0, muito levemente devido às aproximações e arredondamentos de fp64, raramente, mas repetidamente. A repetibilidade confiável e consistente, nesse contexto, torna esse risco de exceção, uma base de dados para proteger, mitigar, em vez de um acaso aleatório isolado. Aqui está um exemplo de um pequeno trecho python3 de haversine, sem a proteção necessária:
import math as m
a = m.sin(dlat / 2)**2 + m.cos(lat1) * m.cos(lat2) * m.sin(dlon / 2)**2
c = 2 * m.atan2(m.sqrt(a), m.sqrt(1 - a))
distance = Radius * c
Muito próximo ou em pontos antípodas, um cálculo calculado na primeira linha da fórmula pode se desviar negativo, raramente, mas repetidamente com as mesmas coordenadas posteriores. Para proteger / corrigir essas ocorrências raras, pode-se simplesmente acrescentar, após a um cálculo, como visto abaixo:
import math as m
note = ''
a = m.sin(dlat / 2)**2 + m.cos(lat1) * m.cos(lat2) * m.sin(dlon / 2)**2
if a < 0.0: a = 0.0 ; note = '*'
if a > 1.0: a = 1.0 ; note = '**'
c = 2 * m.atan2(m.sqrt(a), m.sqrt(1 - a))
distance = Radius * c
# note = '*' # a went below 0.0 and was normalized back to 0.0
# note = '**' # a went above 1.0 and was normalized back to max of 1.0
É claro que eu não mostrei a função inteira aqui, mas um pequeno trecho, como é frequentemente publicado. Mas este mostra a proteção para o sqrt (), testando a um , e normalizando-se necessário, também poupando a necessidade de colocar a coisa toda em uma tentativa exceto. A nota = '' na parte superior é para impedir que o estágio de bytecode proteste que a nota está sendo usada antes de receber um valor, se for retornada com o resultado da função.
Com esta mudança simples, de adicionar os dois de testes, o sqrt () funções serão felizes, e o código agora tem um adicional de nota que pode ser retornado para o código de chamada, de alerta que resultado foi ligeiramente normalizada, e por quê. Alguns podem se importar, outros podem não, mas está lá, impedindo um erro de exceção, que 'pode' ocorrer de outra forma. Um bloco try try pode capturar a exceção, mas não corrigi-la, a menos que seja explicitamente escrito para isso. Parece mais fácil de codificar a linha de correção (s) imediatamente após a uma linha de cálculo. A entrada completamente limpa não deve, portanto, exigir uma tentativa, exceto o bloco aqui.
Resumo, se estiver usando haversine, codificado explicitamente em vez de usar um pacote ou biblioteca, não importa o idioma de sua escolha, seria uma boa idéia testar e normalizar uma volta ao intervalo necessário de 0,0 <= a <= 1,0, para para proteger a próxima linha com seus cálculos c . Mas a maioria dos trechos de código haversine não o mostra e não menciona o risco.
Experiência: durante testes detalhados em todo o mundo, em incrementos de 0,001 graus, preenchi um disco rígido com combinações de latitude que causaram uma exceção, uma exceção repetível consistente e confiável, durante um mês também testando em conjunto a confiabilidade do resfriamento da CPU fã e minha paciência. Sim, eu apaguei a maioria desses logs, pois o objetivo deles era principalmente provar o argumento (se o trocadilho for permitido). Mas eu tenho alguns registros mais curtos de "valores de problemas futuros", mantidos para fins de teste.
Precisão: Será um e todo o resultado haversine perder alguma precisão, normalizando-se que pouco para trás pequeno em domínio? Não muito, talvez não mais do que as aproximações e arredondamentos do fp64 já estavam sendo introduzidos, o que causou essa ligeira mudança de domínio. Se você já achou que a haversine é aceitável acima de muitos - mais simples, mais rápido, mais fácil de personalizar, solucionar problemas e manter, a haversine pode ser uma boa solução para o seu projeto.
Eu usei haversine em uma skysphere projetada acima para medir distâncias angulares entre objetos no céu, como visto de uma posição na terra, mapeando azimute e alt para skysphere lat lon coordenadas equivalentes, sem elipsóide a considerar, desde que o A skysphere teórica projetada é uma esfera perfeita, quando se trata de medir a distância angular, olhar ângulos entre dois objetos de uma posição na superfície da Terra. Atende perfeitamente às minhas necessidades. Portanto, o haversine ainda é muito útil e preciso em certas aplicações (bem dentro dos meus propósitos) ... mas se você o usar, seja na Terra para SIG ou navegação, ou nas observações e medições de objetos no céu, proteja no caso de pontos antipodais ou pontos antipodais muito próximos, testando ume empurrando-o de volta ao seu domínio necessário, quando necessário.
O haversine desprotegido está em toda a Internet, e eu só vi um post antigo da usenet que mostrou alguma proteção, acho de alguém da JPL, e que pode ter sido antes de 1985, antes da especificação IEEE 754 de ponto flutuante. Duas outras páginas mencionaram possíveis problemas próximos a pontos antipodais, mas não os descreveram, ou como alguém poderia mitigá-los. Portanto, existe uma preocupação com os novatos (como eu), que nem sempre entendem as boas práticas o suficiente para continuar pesquisando e testando alguns códigos que eles copiaram e colaram em um projeto de confiança. A publicação intrigante do cffk foi refrescante, pois era pública com esses tipos de problemas, que não são mencionados com frequência, raramente codificados publicamente para proteção em trechos e raramente discutidos dessa maneira, em comparação com a quantidade de versões desprotegidas e não discutidas publicadas.
A partir de 20190923, a página wiki da fórmula haversine realmente menciona o problema possível em pontos antipodais, devido a problemas de ponto flutuante em dispositivos de computação ... encorajadores ...
https://en.wikipedia.org/wiki/Haversine_formula
(como essa página da wiki não possui, no momento, uma âncora html para a seção à qual eu vincularia diretamente, portanto, após o carregamento da página, faça uma pesquisa nessa página do navegador por 'Ao usar essas fórmulas' e você veja o problema do haversine com os pontos antipodais mencionados, mais oficialmente.)
E este outro site também possui uma breve menção a ele:
https://www.movable-type.co.uk/scripts/latlong.html
Se alguém encontrar nessa página informações sobre 'incluindo proteção contra erros de arredondamento', existe isso ...
Se atan2 não estiver disponível, c poderá ser calculado a partir de 2 ⋅ asin (min (1, √a)) (incluindo proteção contra erros de arredondamento).
Agora, há um caso raro em que erros de arredondamento são mencionados e a proteção é mostrada para a versão asin (), ainda não mencionada ou mostrada para a versão atan2 (). Mas pelo menos o risco de erros de arredondamento é mencionado.
imho, qualquer aplicativo 24/7/365 usando haversine, precisa dessa proteção perto dos pontos antipodais como um detalhe importante e simples.
Não sei quais pacotes haversine incluem ou não essa proteção, mas se você é novo em tudo isso e usará a (s) versão (ões) de snippet (s) popularmente publicada (s), agora sabe que precisa de proteção e essa proteção é muito simples de implementar, ou seja, se você não estiver usando o vincenty e não estiver usando um haversine empacotado sem acesso fácil para modificar o código do pacote.
IOW, seja usando vincenty, haversine ou sloc, é preciso ficar ciente de quaisquer problemas com o código, coisas a serem observadas e mitigadas, e como lidar com questões vincenty vs haversine vs sloc será diferente à medida que se tornar consciente de cada um. questões ocultas / edgecases, que podem ou não ser conhecidas popularmente.