Estou tentando desenvolver uma "fórmula" para corrigir os valores de lat-lng.
Estou usando o vue-leaflet, mas quando você se desloca para fora do "primeiro" mundo, obtém grandes números. Acima de +180 ou abaixo de -180.
Por exemplo: quando percorro a América para a direita (direção leste), fico com o número 215. Em minha mente, eu o corrigia com 215-360=-145
O mesmo é para quando eu movo para o leste da Rússia à esquerda (direção oeste) e recebo, por exemplo, -222. Agora eu preciso calcular-222+360=138
No entanto, como o mundo é indefinido, o usuário pode se deslocar para o 8º mundo e eu tive que ajustar os valores.
É possível calcular a longitude correta? (e outro requisito é quando o usuário está no primeiro mundo, 24 lng ainda deve ser 24 lng.
fonte
while (Math.abs(lon) > 180) { lon -= Math.sign(lon) * 360 }
Não estou fornecendo como resposta, porque sua versão realmente corresponde à explicação, enquanto minha versão é apenas uma otimização que provavelmente não faz diferença. Eu mantenho isso como um comentário apenas como um lembrete de que as coisas podem ser feitas de várias maneiras, algumas mais otimizadas que outras.lon %= 180
?Uma resposta que evita condicionais e chamadas de função:
Eu escrevi uma marca rápida de microbench em https://jsperf.com/longitude-normalisation e o código condicional parece ser mais rápido (no Chrome na minha máquina) para intervalos 'razoáveis' de valores de entrada. Em geral, você provavelmente não deve se preocupar com o desempenho em pequenos cálculos como esse, dando mais peso à legibilidade e consistência com o restante da sua base de código.
Provavelmente mais importante nesse caso é a questão de saber se o seu código pode se deparar com valores extremos de entrada (1e10, Infinity etc.). Nesse caso, a implementação de loop pode acabar sendo executada muito lenta ou silenciosamente, interrompendo seu programa. Isso pode ocorrer com cálculos realizados perto dos polos, por exemplo, tentar deslocar-se para leste ou oeste a alguma distância (em vez de ângulo) de um polo pode facilmente resultar em uma longitude infinita.
fonte
Uma linha:
Explicação: Você deseja saber o que resta depois de desconsiderar as rotações completas (360 °).
Esse processo é chamado de normalização.
Exemplo (cpp.sh)
fonte
remainder
comomodulus
. O módulo em JS resultaria em [0, 360).-1 % 3
é -1, e não 2, pois seria necessário para que ele funcionasse aqui.remainder
é uma ótima solução C ++, mas infelizmente não há função / operador em JS que seja semelhante o suficiente para ser útil.Outra opção: longitude = atan2 (cos (long), sin (long))
fonte
Se a linguagem de programação que você está usando suportar o operador% (mod) em números de ponto flutuante (como Python e Ruby), eu recomendo usar isso. Caso contrário, algumas outras linguagens (como C e C ++) permitem que você use fmod ().
(Qualquer que seja o operador de mod que você usa, verifique com antecedência que ele fará operações de mod em números de ponto flutuante e que sempre fornecerá respostas não negativas. Caso contrário, você terá uma surpresa desagradável mais tarde, quando muitos de seus os pontos lat / lon não estão corretos.)
Use-o assim:
Se você preferir fazer tudo em uma linha:
Essas abordagens não possuem loops, portanto normalizam os valores da longitude sem a necessidade de adicionar ou subtrair repetidamente, não importa quantas vezes sua observação tenha circulado pela Terra.
Editar:
Hmmm ... Acabei de perceber que o Javascript não parece lidar
%
com valores negativos como eu pensava.Nesse caso, tente este one-liner:
O
36180
que estamos adicionando é 36.000 + 180. O 36.000 é mover um valor negativo para o domínio positivo, e o 180 é movê-lo para que, quando modificado360
, ele esteja no intervalo de [0,360) . A- 180
peça volta para o intervalo de [-180.180).Aqui está outra linha única, que não depende de 36.000 serem grandes o suficiente:
A
longitude % 360 + 360
peça garantirá que o valor permaneça no domínio positivo quando mais tarde for modificado por360
. A+ 180
parte a desloca para que, quando mais tarde ela for subtraída 180 (com- 180
), ela esteja no intervalo desejado de [-180.180).fonte
fmod(longitude, 360)
-> (-360,0 ... +360,0) eilongitude % 360
-> [-359 ... +359].