Jak mogę owinąć polilinię na całym świecie?

14

Korzystam z map ulotek, aby stworzyć reprezentację globalnego wyzwania. Chciałbym dodać polilinię, która kieruje się na wschód od Tokio, a następnie pojawia się na mapie na zachód od Ameryki Południowej - ale zamiast tego otrzymuję linię, która przecina mapę w przeciwnym kierunku (patrz żółta linia).

wprowadź opis zdjęcia tutaj

Myślę, że jest to prawdopodobnie związane z liniami danych i / lub układami współrzędnych, ale jestem nieco szkicowy w szczegółach. Czy ktoś może wyjaśnić teorię, co muszę zrobić, aby to zadziałało? Korzystam z niebieskiej projekcji 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
});
codecowboy
źródło
2
Musisz złamać polilinię na południku + -180 stopni. Wymaga to znalezienia szerokości geograficznej, na której polilinia przecina ten południk. Twój GIS prawdopodobnie ma metody na złamanie. Jeśli nie, proste rozwiązanie można uzyskać z kodu pokazanego w powiązanym wątku . Czy jesteś w stanie wykonać taki kod na swojej platformie?
whuber
Zgadzam się z jacuzzi. Musiałem wykonać podobne zadanie z wielokątami przecinającymi + - 180. Musisz za każdym razem przecinać + -180 na wiele polilinii / wielokątów.
Steve,

Odpowiedzi:

13

Musisz złamać polilinię na południku + -180 stopni. Wymaga to znalezienia szerokości geograficznej, na której polilinia przecina ten południk. Twój GIS prawdopodobnie ma metody na złamanie. Jeśli nie, proste rozwiązanie można uzyskać z kodu pokazanego w powiązanym wątku . Oto kilka szczegółów.

  • Polilinia jest reprezentowana jako sekwencja wierzchołków , każda podana w formie (lat, lon), z -180 <= lon <= 180. Musisz sprawdzić każdą kolejną parę, aby zobaczyć, czy przecina południk + -180. Jest szybki test: jeśli wartość bezwzględna różnicy długości wynosi 180 lub więcej, następuje przekroczenie.

  • W obrębie każdego segmentu (lat0, lon0) -> (lat1, lon1), który przecina południk + -180, musisz rozbić polilinię na dwie części, w których przecina się.

Kluczem jest znalezienie szerokości geograficznej punktu przerwania z rozsądną dokładnością. Najłatwiej to zrobić za pomocą kulistego modelu ziemi: błąd (w porównaniu z bardziej dokładnym modelem elipsoidalnym) będzie zbyt mały, aby go zauważyć.

Niech dany segment przechodzi od punktu 0 w (lat0, lon0) do punktu 1 w (lat1, lon1). Punkt przerwania można znaleźć, prowadząc odcinek linii prostej w 3D między dwoma punktami przedstawionymi we współrzędnych kartezjańskich i znajdując, gdzie współrzędna y wynosi zero. Te współrzędne kartezjańskie

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

i podobne wyrażenie dające (x1, y1, z1) dla punktu 1. Rozwiąż równanie

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

dla t; to jest,

t = y1 / (y1 - y0).

Współrzędne przecięcia są zatem

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

Ten punkt (który leży pod powierzchnią ziemi gdzieś pod południkiem + -180) ma szerokość równą

lat2 = ATan(z/x).

Punkt przerwania należy przedstawić na dwa sposoby. Dołączając go po (lat0, lon0), aby zakończyć pierwszą część łamanej polilinii, użyj (lat2, -180), jeśli lon0 jest ujemny, a w przeciwnym razie użyj (lat2, 180). Dołączając go wcześniej (lat1, lon1), aby rozpocząć drugą część łamanej polilinii, postępuj zgodnie z podobną zasadą.

W wyjątkowych przypadkach jeden lub oba z punktów 0 i 1 mogą znajdować się na południku + -180. Postępowanie zgodnie z tą procedurą spowoduje umieszczenie segmentu o zerowej długości na jednym z utworzonych elementów polilinii. Jeśli może to powodować problem z GIS, przetestuj ten warunek.

Zauważ, że polilinia może przekroczyć ten południk więcej niż jeden raz. Dlatego po znalezieniu pierwszego podziału i podzieleniu polilinii na dwie części drugą część należy przetworzyć w ten sam sposób.

Whuber
źródło
1
To, co powiedział whuber, jest OK, ale myślę, że w następującym zdaniu jest literówka:> Przy dołączaniu go po (lat0, lon0), aby zakończyć pierwszą część złamanej> polilinii, użyj (lat2, -180), jeśli lat0 jest ujemne i w przeciwnym razie użyj (lat2, 180). Myślę, że to musi być:> zastosowanie (lat2, -180) jeżeli lon0 jest ujemny i inaczej zastosowanie (lat2, 180)
Georgi
@Georgi Dzięki za złapanie tego; Myślę, że masz rację, a ja dokonam zmiany.
whuber
Musiałem zaimplementować to w Leaflet.js, oto mój kod: gist.github.com/mikeatlas/0b69b354a8d713989147
Mike Atlas
Dziękuję, @Mike. Uwielbiam zygzakowatą ilustrację: właśnie taką okoliczność wyobrażałem sobie, pisząc tę ​​odpowiedź. Jeśli chcesz naprawdę ciężkiego testu, zobacz, co stanie się z polilinią, która biegnie wzdłuż samego południka + -180 stopni (i przecina oba bieguny)!
whuber
@ whuber Być może będę musiał spróbować: / Zamieszczę wyniki
Mike Atlas,