Estoy tratando de desarrollar una "fórmula" para corregir los valores de lat-lng.
Estoy usando vue-leaflet pero cuando se desplaza fuera del "primer" mundo obtiene grandes números. Más de +180 o menos de -180.
Por ejemplo: cuando me desplazo hacia América a la derecha (dirección este), obtengo como lng 215. En mi mente, simplemente lo corregiría con 215-360=-145
Lo mismo ocurre cuando me desplazo hacia el este de Rusia hacia la izquierda (dirección oeste) y obtengo, por ejemplo, -222. Ahora necesito calcular-222+360=138
Sin embargo, dado que el mundo es indefinido, el usuario podría desplazarse al octavo mundo y tuve que ajustar los valores.
¿Es posible calcular la longitud correcta? (y otro requisito es cuando el usuario está en el primer mundo, 24 lng aún debe ser 24 lng.
fuente
while (Math.abs(lon) > 180) { lon -= Math.sign(lon) * 360 }
. Sin embargo, no lo estoy proporcionando como respuesta porque tu versión realmente coincide con la explicación, mientras que mi versión es solo una optimización que probablemente no haga ninguna diferencia. Lo mantengo como un comentario solo como un recordatorio de que las cosas se pueden hacer de múltiples maneras, algunas más optimizadas que otras.lon %= 180
?Una respuesta que evita condicionales y llamadas a funciones:
Escribí un microbenchmark rápido en https://jsperf.com/longitude-normalisation y el código condicional parece ser más rápido (en Chrome en mi máquina) para rangos 'razonables' de valores de entrada. En general, probablemente no debería preocuparse de antemano por el rendimiento en pequeños cálculos como este, lo que da más peso a la legibilidad y la coherencia con el resto de su base de código.
Probablemente más importante en este caso es la cuestión de si su código podría encontrarse con valores de entrada extremos (1e10, Infinito, etc.). Si es así, la implementación en bucle podría terminar ejecutándose muy lenta o silenciosamente colgando su programa. Esto podría ocurrir con los cálculos realizados cerca de los polos, por ejemplo, intentar desplazarse hacia el este o el oeste a cierta distancia (en lugar de ángulo) desde un poste podría resultar fácilmente en una longitud infinita.
fuente
Un trazador de líneas:
Explicación: Desea saber qué queda después de ignorar las rotaciones completas (360 °).
Este proceso se llama normalización.
Ejemplo (cpp.sh)
fuente
remainder
comomodulus
. El módulo en JS daría como resultado [0, 360).-1 % 3
es -1, no 2, ya que sería necesario para que funcione aquí.remainder
es una excelente solución de C ++, pero desafortunadamente no hay una función / operador en JS que sea lo suficientemente similar como para ser útil.Otra opción: longitud = atan2 (cos (largo), sin (largo))
fuente
Si el lenguaje de programación que está utilizando admite el operador% (mod) en números de coma flotante (como Python y Ruby), recomendaría usarlo. De lo contrario, algunos otros lenguajes (como C y C ++) le permiten usar fmod ().
(Cualquiera que sea el operador de mod que utilice, asegúrese con anticipación de que realizará operaciones de mod en números de punto flotante, y que siempre le dará respuestas no negativas. De lo contrario, recibirá una desagradable sorpresa más tarde cuando muchos de sus los puntos lat / lon no son correctos)
Úselo así:
Si prefiere hacerlo todo en una línea:
Estos enfoques no tienen bucles, por lo que normalizarán los valores de longitud sin necesidad de sumar o restar repetidamente, sin importar cuántas veces su observación haya dado vueltas alrededor de la tierra.
Editar:
Hmmm ... acabo de notar que Javascript no parece manejarse
%
con valores negativos como pensé que lo haría.En ese caso, intente con esta frase:
Lo
36180
que estamos agregando es 36,000 + 180. El 36,000 es mover un valor negativo al dominio positivo, y el 180 es desplazarlo para que cuando sea modificado por360
, esté en el rango de [0,360) . La- 180
parte la desplaza nuevamente al rango de [-180,180).Aquí hay otro one-liner, uno que no depende de que 36,000 sean lo suficientemente grandes:
La
longitude % 360 + 360
parte asegurará que el valor permanezca en el dominio positivo cuando luego sea modificado por360
. La+ 180
parte lo desplaza de modo que cuando luego se reste 180 (con- 180
), esté en el rango deseado de [-180,180).fuente
fmod(longitude, 360)
-> (-360.0 ... +360.0) yilongitude % 360
-> [-359 ... +359].