Tworzenie wielkich łuków koła, które wyglądają dobrze na mapie Web Mercator?


11

Próbuję utworzyć mapę z danymi wskazującymi niektóre loty i chcę użyć Great Circle Arcs, aby połączyć źródło i cele podróży.

Zasadniczo chcę zrobić coś podobnego do słynnej mapy na Facebooku: wprowadź opis zdjęcia tutaj

Korzystałem z funkcji podanych w tym poście: https://gis.stackexchange.com/a/5205/442 , (tj. W tym artykule na blogu: http://anitagraser.com/2011/08/20/visualizing-global-connections / ) i mogłem uzyskać linie, ale przecinają one międzynarodową linię daty, a także grupują się na biegunach:

wprowadź opis zdjęcia tutaj

@underdark, w linkowanym blogu wspomniał, że linie te muszą zostać podzielone, ale nie wiem, jak je automatycznie podzielić w PostGIS.

Ponadto należy również rozwiązać wiązanie linii w pobliżu biegunów.

Jak to zrobić, gdy mam lokalizacje punktów na początek i koniec tych lotów?


Czy możesz użyć projekcji polarnej?
Ian Turton

2
Podałem kilka przykładów tutaj: gis.stackexchange.com/questions/133026/... . Zauważ, że eqdc nie dostarcza prawdziwych wielkich kręgów, ale aeqd tak.
AndreJ

Odpowiedzi:



8

Możesz obliczyć geodezję. Mówiąc, że chcesz pokazać geodezję od A do B, możesz najpierw obliczyć odległość i azymut od A do B (odwrotny problem geodezyjny), a następnie obliczyć punkty od A do kilku punktów między A i B (bezpośredni problem geodezyjny). Dodałem prosty skrypt w Pythonie, używając GeographicLib, po prostu wypisując rzeczy w GeoJSON:

from geographiclib.geodesic import Geodesic
from geojson import MultiLineString

def geodesic(lat1, lon1, lat2, lon2, steps):
    inverse = Geodesic.WGS84.Inverse(lat1, lon1, lat2, lon2)
    linestrings = []
    coordinates = []

    for i in range(0, steps + 1):
        direct = Geodesic.WGS84.Direct(inverse['lat1'], inverse['lon1'], inverse['azi1'], (i / float(steps)) * inverse['s12'])
        if len(coordinates) > 0:
            if (coordinates[-1][0] < -90 and direct['lon2'] > 90) or (coordinates[-1][0] > 90 and direct['lon2'] < -90):
                linestrings.append(coordinates)
                coordinates = []
        coordinates.append((direct['lon2'], direct['lat2']))

    linestrings.append(coordinates)
    geojson = MultiLineString(linestrings)
    return geojson

linestrings = []

# San Francisco: 37.7793, -122.4192
# Bangalore: 12.9, 77.616667
for linestring in geodesic(37.7793, -122.4192, 12.95, 77.616667, 100)['coordinates']:
    linestrings.append(linestring)

# Boston: 42.357778, -71.059444
# Bangalore: 12.9, 77.616667
for linestring in geodesic(42.357778, -71.059444, 12.95, 77.616667, 100)['coordinates']:
    linestrings.append(linestring)

print(MultiLineString(linestrings))

Wynikiem jest prawdziwa geodezyjność między punktami w WGS-84. Oczywiście możesz następnie przekształcić współrzędne na dowolną potrzebną projekcję. Wynik wizualizowany na geojson.io wygląda następująco:

wprowadź opis zdjęcia tutaj


2
Zobacz geographiclib.sourceforge.net/html/python/..., aby uzyskać alternatywny (i szybszy!) Sposób na zrobienie tego za pomocą GeographicLib. Zwróć także uwagę na użycie flagi LONG_UNROLL, aby zapewnić ciągłość długości.
cffk 17.03.16
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.