Come posso avvolgere una polilinea in tutto il mondo?


14

Sto usando le mappe dei volantini per creare una rappresentazione di una sfida intorno al mondo. Vorrei aggiungere una polilinea che si dirige verso est da Tokyo e poi appare a ovest del sud america sulla mappa - ma invece ottengo una linea che attraversa la mappa nella direzione opposta (vedi linea gialla).

inserisci qui la descrizione dell'immagine

Penso che questo sia probabilmente correlato a linee dati e / o sistemi di coordinate, ma sono un po 'impreciso nei dettagli. Qualcuno può spiegare la teoria dietro ciò che devo fare per farlo funzionare? Sto usando la proiezione bluemarble della 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
È necessario interrompere la polilinea al meridiano + -180 gradi. Ciò richiede di trovare la latitudine alla quale la polilinea attraversa quel meridiano. Il tuo GIS probabilmente ha metodi per fare la rottura. In caso contrario, una semplice soluzione può essere derivata dal codice mostrato in un thread correlato . Sei in grado di eseguire codice come questo sulla tua piattaforma?
whuber

Sono d'accordo con whuber. Ho dovuto svolgere un compito simile con i poligoni che attraversano + - 180. Devi dividere in più polilinee / poligoni ogni volta che attraversi il + -180.
Steve

Risposte:


13

È necessario interrompere la polilinea al meridiano + -180 gradi. Ciò richiede di trovare la latitudine alla quale la polilinea attraversa quel meridiano. Il tuo GIS probabilmente ha metodi per fare la rottura. In caso contrario, una semplice soluzione può essere derivata dal codice mostrato in un thread correlato . Ecco alcuni dettagli

  • Una polilinea è rappresentata come una sequenza di vertici , ciascuno dato in forma (lat, lon), con -180 <= lon <= 180. Devi controllare ogni coppia successiva per vedere se attraversa il meridiano + -180. C'è un test rapido: se il valore assoluto della differenza di longitudini è 180 o maggiore, c'è un incrocio.

  • All'interno di ogni segmento (lat0, lon0) -> (lat1, lon1) che attraversa il meridiano + -180, è necessario spezzare la polilinea in due parti in cui incrocia.

La chiave sta trovando la latitudine del punto di interruzione con ragionevole precisione. Ciò è più semplice con un modello di terra sferica: l'errore (rispetto a un modello ellissoidale più accurato) sarà troppo piccolo per essere notato.

Lascia che il segmento in questione vada dal punto 0 a (lat0, lon0) al punto 1 a (lat1, lon1). Il punto di interruzione può essere trovato eseguendo un segmento di linea retta in 3D tra i due punti come rappresentato nelle coordinate cartesiane e trovando dove la coordinata y è zero. Le coordinate cartesiane sono

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

e un'espressione simile che dà (x1, y1, z1) per il punto 1. Risolvi l'equazione

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

per t; questo è,

t = y1 / (y1 - y0).

Le coordinate dell'intersezione sono quindi

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

Questo punto (che si trova sotto la superficie terrestre da qualche parte sotto il meridiano + -180) ha una latitudine uguale a

lat2 = ATan(z/x).

Il punto di interruzione deve essere rappresentato in due modi. Quando lo si collega dopo (lat0, lon0) per terminare la prima parte della polilinea spezzata, usare (lat2, -180) se lon0 è negativo e altrimenti usare (lat2, 180). Quando lo si collega prima (lat1, lon1) per iniziare la seconda parte della polilinea rotta, seguire una regola simile.

In casi eccezionali, uno o entrambi i punti 0 e 1 possono trovarsi sul meridiano + -180. Seguendo questa procedura, verrà posizionato un segmento di lunghezza zero su uno dei pezzi di polilinea creati. Se ciò potrebbe causare un problema con il GIS, verificare questa condizione.

Si noti che una polilinea può attraversare questo meridiano più di una volta. Pertanto, dopo aver trovato la prima rottura e spezzato la polilinea in due parti, è necessario elaborare la seconda parte allo stesso modo.


1
Quello che ha detto whuber è OK ma penso che ci sia un refuso alla seguente frase:> Quando lo si attacca dopo (lat0, lon0) per terminare la prima parte della polilinea> rotta, usare (lat2, -180) se lat0 è negativo e altrimenti usa (lat2, 180). Penso che debba essere:> usa (lat2, -180) se lon0 è negativo e altrimenti usa (lat2, 180)
Georgi

@Georgi Grazie per averlo colto; Penso che tu abbia ragione e farò il cambiamento.
whuber

Ho dovuto implementarlo in Leaflet.js, ecco il mio codice: gist.github.com/mikeatlas/0b69b354a8d713989147
Mike Atlas

Grazie, @Mike. Adoro l'illustrazione a zig-zag: questo è esattamente il tipo di circostanza che stavo immaginando mentre scrivevo questa risposta. Se vuoi un test davvero severo, vedi cosa succede a una polilinea che corre lungo il meridiano + -180 gradi stesso (e attraversa entrambi i poli)!
whuber

@whuber Forse dovrei solo provarlo: / Pubblicherò i risultati
Mike Atlas,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.