Створення великих кругових дуг, які добре виглядають на карті Web Mercator?


11

Я намагаюся створити карту із даними, що вказують на деякі рейси, і хочу використовувати Дуги Великого кола, щоб з'єднати джерело та пункти призначення.

В основному, я хочу зробити щось подібне до відомої карти Facebook: введіть тут опис зображення

Я використовував функції, наведені в цій публікації: https://gis.stackexchange.com/a/5205/442 , (тобто ця стаття в блозі: http://anitagraser.com/2011/08/20/visualizing-global-connections / ) і я міг би отримати лінії, але вони перетинають Міжнародну лінію дати, а також збираються біля полюсів:

введіть тут опис зображення

@underdark, у зв'язаному блозі писав, що ці рядки потрібно розділити, але я не знаю, як їх розділити автоматично в PostGIS.

Крім того, потрібно також вирішити зв'язок ліній біля полюсів.

Як мені це зробити, коли у мене є точки розташування для початку та кінця цих рейсів?


Чи можете ви використовувати полярну проекцію?
Ян Тертон

2
Я дав кілька прикладів тут: gis.stackexchange.com/questions/133026 / ... . Зауважте, що eqdc не забезпечує справжні великі кола, але aeqd.
AndreJ

Відповіді:


5

Принципи передачі цього блогу переходять до загального призначення PostGIS.

http://blog.cartodb.com/jets-and-datelines/

В основному, використовуйте ST_Segmentizeгеографію та трохи чарівництва, щоб нарізати лінії перетину дати.


8

Ви можете розрахувати геодезику. Скажімо, ви хочете показати геодезичну від А до В, ви можете спочатку обчислити відстань і азимут від А до В (обернена геодезична задача), а потім обчислити точки від А до декількох точок між А і В (пряма геодезична задача). Я додав простий скрипт у Python, використовуючи GeographicLib, щойно виводить речі в 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))

В результаті виходить справжня геодезична між точками в WGS-84. Звичайно, ви можете потім перетворити координати на будь-яку проекцію, яка вам потрібна. Результат, візуалізований на geojson.io, виглядає приблизно так:

введіть тут опис зображення


2
Дивіться geographiclib.sourceforge.net/html/python/… про альтернативний (і швидший!) Спосіб зробити це за допомогою GeographicLib. Зверніть увагу також на використання прапора LONG_UNROLL для забезпечення безперервності довжин.
cffk
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.