¿Cómo puedo hacer una envoltura de polilínea alrededor del mundo?


14

Estoy usando mapas de folletos para crear una representación de un desafío alrededor del mundo. Me gustaría agregar una polilínea que se dirige al este desde Tokio y luego aparece al oeste de América del Sur en el mapa, pero en su lugar obtengo una línea que cruza el mapa en la dirección opuesta (ver línea amarilla).

ingrese la descripción de la imagen aquí

Creo que esto probablemente esté relacionado con las líneas de datos y / o los sistemas de coordenadas, pero soy un poco esquemático en los detalles. ¿Alguien puede explicar la teoría detrás de lo que necesito hacer para que esto funcione? Estoy usando la proyección bluemarble de la NASA:

var bluemarble = new L.TileLayer.WMS("http://demo.opengeo.org/geoserver/wms", {
layers: 'bluemarble',
attribution: "Data © NASA Blue Marble, image service by OpenGeo",
minZoom: 2,
maxZoom: 5
});

2
Debe romper la polilínea en el meridiano de + -180 grados. Esto requiere encontrar la latitud a la cual la polilínea cruza ese meridiano. Su SIG probablemente tiene métodos para romper. De lo contrario, se puede derivar una solución simple del código que se muestra en un hilo relacionado . ¿Eres capaz de ejecutar código como este en tu plataforma?
whuber

Estoy de acuerdo con whuber. He tenido que realizar una tarea similar con polígonos que cruzan + - 180. Debe dividirse en múltiples polilíneas / polígonos cada vez que cruza el + -180.
Steve

Respuestas:


13

Debe romper la polilínea en el meridiano de + -180 grados. Esto requiere encontrar la latitud a la cual la polilínea cruza ese meridiano. Su SIG probablemente tiene métodos para romper. De lo contrario, se puede derivar una solución simple del código que se muestra en un hilo relacionado . Aquí hay algunos detalles.

  • Una polilínea se representa como una secuencia de vértices , cada uno dado en forma (lat, lon), con -180 <= lon <= 180. Debe verificar cada par sucesivo para ver si cruza el meridiano + -180. Hay una prueba rápida: si el valor absoluto de la diferencia de longitudes es 180 o mayor, hay un cruce.

  • Dentro de cada segmento (lat0, lon0) -> (lat1, lon1) que cruza el meridiano + -180, debe dividir la polilínea en dos partes donde se cruza.

La clave es encontrar la latitud del punto de ruptura con una precisión razonable. Esto se hace más fácilmente con un modelo de tierra esférica: el error (en comparación con un modelo elipsoidal más preciso) será demasiado pequeño para notarlo.

Deje que el segmento en cuestión vaya del punto 0 en (lat0, lon0) al punto 1 en (lat1, lon1). El punto de ruptura se puede encontrar ejecutando un segmento de línea recta en 3D entre los dos puntos como se representa en las coordenadas cartesianas y encontrando dónde la coordenada y es cero. Las coordenadas cartesianas son

(x0, y0, z0) = (cos(lon0)*sin(lat0), sin(lon0)*sin(lat0), cos(lat0))

y una expresión similar que da (x1, y1, z1) para el punto 1. Resuelva la ecuación

t * y0 + (1-t) * y1 = 0

para t; es decir,

t = y1 / (y1 - y0).

Por lo tanto, las coordenadas de la intersección son

(x, y, z) = (t * x0 + (1-t) * x1, 0, t * z0 + (1-t) * z1)

Este punto (que se encuentra debajo de la superficie de la tierra en algún lugar debajo del meridiano + -180) tiene una latitud igual a

lat2 = ATan(z/x).

El punto de ruptura debe representarse de dos maneras. Cuando lo adjunte después (lat0, lon0) para terminar la primera parte de la polilínea rota, use (lat2, -180) si lon0 es negativo y, de lo contrario, use (lat2, 180). Cuando lo adjunte antes (lat1, lon1) para comenzar la segunda parte de la polilínea rota, siga una regla similar.

En casos excepcionales, uno o ambos puntos 0 y 1 pueden estar en el meridiano + -180. Seguir este procedimiento hará que coloque un segmento de longitud cero en una de las piezas de polilínea que cree. Si esto puede causar un problema con el SIG, pruebe esta condición.

Tenga en cuenta que una polilínea puede cruzar este meridiano más de una vez. Por lo tanto, después de encontrar la primera ruptura y dividir la polilínea en dos partes, debe procesar la segunda parte de la misma manera.


1
Lo que dijo Whuber está bien, pero creo que hay un error tipográfico en la siguiente oración:> Cuando lo adjunte después (lat0, lon0) para terminar la primera parte de la polilínea rota>, use (lat2, -180) si lat0 es negativo y de lo contrario, use (lat2, 180). Creo que debe ser:> use (lat2, -180) si lon0 es negativo y de lo contrario use (lat2, 180)
Georgi

@Georgi Gracias por atrapar eso; Creo que tienes razón y haré el cambio.
whuber

Tuve que implementar esto en Leaflet.js, aquí está mi código: gist.github.com/mikeatlas/0b69b354a8d713989147
Mike Atlas

Gracias @ Mike. Me encanta la ilustración en zig-zag: ese es exactamente el tipo de circunstancia que estaba imaginando mientras escribía esta respuesta. Si desea una prueba realmente severa, ¡vea lo que le sucede a una polilínea que corre a lo largo del meridiano de + -180 grados (y cruza ambos polos)!
whuber

@whuber Puede que necesite probar eso: / Publicaré resultados
Mike Atlas

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.