¿Haciendo arcos de Great Circle que se ven bien en el mapa de Web Mercator?

11

Estoy tratando de crear un mapa, con datos que indiquen algunos vuelos, y quiero usar Great Circle Arcs para conectar la fuente y los destinos.

Básicamente, quiero hacer algo similar al famoso mapa de Facebook: ingrese la descripción de la imagen aquí

Utilicé las funciones dadas en esta publicación: https://gis.stackexchange.com/a/5205/442 , (es decir, este artículo de blog: http://anitagraser.com/2011/08/20/visualizing-global-connections / ) y podría obtener líneas, pero cruzan la línea de fecha internacional, así como se agrupan en los polos:

ingrese la descripción de la imagen aquí

@underdark, ha mencionado en el blog vinculado que estas líneas deben dividirse, pero no sé cómo dividirlas automáticamente en PostGIS.

Además, el agrupamiento de las líneas cerca de los polos también debe resolverse.

¿Cómo hago ambas cosas cuando tengo las ubicaciones de puntos para el inicio y el final de estos vuelos?

Devdatta Tengshe
fuente
¿Podrías usar una proyección polar?
Ian Turton
2
He dado algunos ejemplos aquí: gis.stackexchange.com/questions/133026/… . Tenga en cuenta que eqdc no ofrece verdaderos grandes círculos, pero aeqd sí.
AndreJ

Respuestas:

5

Los principios de esta publicación de blog se transfieren a PostGIS de uso general.

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

Básicamente, use ST_Segmentizeen geografía y un poco de magia para cortar líneas de cruce de línea de fecha.

Paul Ramsey
fuente
8

Podrías calcular la geodésica. Al decir que desea mostrar la geodésica de A a B, primero puede calcular la distancia y el acimut de A a B (problema geodésico inverso) y luego calcular puntos de A a varios puntos entre A y B (problema geodésico directo). He agregado un script simple en Python usando GeographicLib simplemente generando las cosas en 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))

El resultado es la verdadera geodésica entre los puntos en WGS-84. Por supuesto, podría transformar las coordenadas a la proyección que necesite. El resultado visualizado en geojson.io se ve así:

ingrese la descripción de la imagen aquí

sema
fuente
2
Ver geographiclib.sourceforge.net/html/python/... de una alternativa (y más rápido!) Manera de hacer esto con GeographicLib. Tenga en cuenta también el uso de la bandera LONG_UNROLL para garantizar la continuidad de las longitudes.
cffk