Создание дуг большого круга, которые хорошо смотрятся на карте 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

Вы можете рассчитать геодезические. Говоря, что вы хотите показать геодезическую от A до B, вы можете сначала вычислить расстояние и азимут от A до B (обратная геодезическая задача), а затем вычислить точки от A до нескольких точек между A и B (прямая геодезическая задача). Я добавил простой скрипт в 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