Faire de grands arcs de cercle qui ont l'air bien sur la carte Web Mercator?


11

J'essaie de créer une carte, avec des données indiquant certains vols, et je veux utiliser Great Circle Arcs, pour connecter la source et les destinations.

Fondamentalement, je veux faire quelque chose de similaire à la célèbre carte Facebook: entrez la description de l'image ici

J'ai utilisé les fonctions données dans cet article: https://gis.stackexchange.com/a/5205/442 , (c'est-à-dire cet article de blog: http://anitagraser.com/2011/08/20/visualizing-global-connections / ) et je pourrais obtenir des lignes, mais ils traversent la ligne de date internationale, ainsi que des tas, aux pôles:

entrez la description de l'image ici

@underdark, a mentionné dans le blog lié que ces lignes doivent être divisées, mais je ne sais pas comment les diviser automatiquement dans PostGIS.

De plus, le regroupement des lignes près des pôles doit également être résolu.

Comment est-ce que je fais ces deux, quand j'ai les emplacements de point pour le début et la fin de ces vols?


Pourriez-vous utiliser une projection polaire?
Ian Turton

2
J'ai donné quelques exemples ici: gis.stackexchange.com/questions/133026/… . Notez que eqdc ne fournit pas de vrais grands cercles, mais aeqd le fait.
AndreJ

Réponses:



8

Vous pouvez calculer les géodésiques. En disant que vous voulez montrer la géodésique de A à B, vous pouvez d'abord calculer la distance et l'azimut de A à B (problème géodésique inverse), puis calculer les points de A à plusieurs points entre A et B (problème géodésique direct). J'ai ajouté un script simple en Python en utilisant GeographicLib juste en sortant les trucs dans 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))

Le résultat est la véritable géodésique entre les points du WGS-84. Bien sûr, vous pouvez ensuite transformer les coordonnées en n'importe quelle projection dont vous avez besoin. Le résultat visualisé sur geojson.io ressemble à ceci:

entrez la description de l'image ici


2
Voir Geographiclib.sourceforge.net/html/python/… pour une manière alternative (et plus rapide!) De le faire avec GeographicLib. Notez également l'utilisation du drapeau LONG_UNROLL pour assurer la continuité des longitudes.
cffk
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.