Карта ассортимента самолетов

10

Я хотел бы создать (веб) карту, которая показывает дальность полета Самолета вокруг некоторых аэропортов.

Я пытался рассчитать буфер с дальностью полета самолета. Здесь вы можете увидеть результат здесь .

Но теперь я понял, что результат неправильный, потому что самолеты не идут по прямому маршруту, а летят по кривой, потому что она короче.

Есть ли способ рассчитать диапазон с более короткой кривой?

Райкер
источник

Ответы:

20

Вы можете использовать библиотеку proj4, чтобы описать круг, используя расстояние большого круга.

Например, вот радиус 3000 км от Эдинбурга, Токио, Кейптауна и Кито в wgs84 / Equirectangular. Только Кито смутно «круглый» из-за его близости к экватору. Я также добавил в единую уплотненную спицевую линию с азимутом 36 градусов (приблизительно к северо-востоку)

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

Если мы перейдем к азимутальной эквидистантной проекции с центром в Эдинбурге, вы увидите, что радиус вокруг Эдинбурга переходит в круг ...

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

В Mercator (как и в вашем веб-приложении) вы видите больше искажений по мере удаления от экватора, но буферы более эллиптические.

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

Следующий код Python делает это (требует pyproj и shapely )

import pyproj
from shapely.geometry import Polygon, MultiPoint, LineString
import math

def geodesicpointbuffer(longitude, latitude,
                        segments, distance_m,
                        geom_type=MultiPoint):
    """
    Creates a buffer in meters around a point given as long, lat in WGS84
    Uses the geodesic, so should be more accurate over larger distances

    :param longitude: center point longitude
    :param latitude: center point latitude
    :param segments: segments to approximate (more = smoother)
    :param distance_m: distance in meters
    :param geom_type: shapely type (e.g. Multipoint, Linestring, Polygon)
    :return: tuple (proj4 string, WKT of buffer geometry)
    """
    geodesic = pyproj.Geod(ellps='WGS84')
    coords = []
    for i in range(0, segments):
        angle = (360.0 / segments) * float(i)
        x1, y1, z1 = geodesic.fwd(lons=longitude,
                                  lats=latitude,
                                  az=angle,
                                  dist=distance_m,
                                  radians=False)
        coords.append((x1, y1))
        # makes a great circle for one spoke.
        if i==200:
            example = geodesic.npts(longitude,latitude,x1,y1,1000)
            coords2 = []
            for xx,yy in example:
                coords2.append((xx,yy))
            coords2.append((x1,y1)) # make sure we include endpoint ;-)
            flight = LineString(coords2)
            print(flight.wkt)

    ring = geom_type(coords)
    return "+init=EPSG:4326", ring.wkt


def main():
    # example : Cape Town. 3000km buffer.
    spec, wkt = geodesicpointbuffer(18.4637082653, -33.8496404007, 2000, 3000000.0, Polygon)
    print(spec)
    print(wkt)

if __name__ == "__main__":
    main()

Вы можете вставить вывод WKT в QGIS, используя полезный плагин QuickWKT .

Вы можете использовать другие методы - как упоминалось в coneypylon, вы можете создать круг на собственной эквидистантной проекции в метрах, центрированной по вашей начальной точке. Я обнаружил, что на больших расстояниях появляется ошибка (всего несколько километров на 2000 км, но на межконтинентальных расстояниях эти ошибки могут возрасти)

По памяти плагин mmqgis позволяет буферизовать в км. Я не уверен, какой метод он использует, хотя.

Обратите внимание, что у вас могут возникнуть проблемы с рендерингом полигонов в QGIS, которые пересекают антимеридиан, если вы начинаете в Азии - здесь может помочь ogr2ogr с опцией -wrapdateline . Вы можете обнаружить, что это меньше проблем с открытыми слоями / листовкой, IIRC они позволяют долготы больше 180 и меньше -180.

В блоге esri есть хорошая статья о геодезической буферизации .

Стивен Кей
источник
8

В зависимости от того, откуда берется информация о расстоянии, это может не иметь значения. Если у вас есть простое число, указывающее расстояние, расстояние будет одинаковым на любой проекции карты, которая точно показывает расстояние (не Меркатора, подумайте в значительной степени о любой «равноудаленной» проекции, такой как азимутальная ортографическая проекция или аналогичная. Конформная проекция, как Ламберт Конформный Коник будет делать достаточно хорошо на расстоянии.). Если вы вычисляете и создаете буферы в равноудаленной проекции, они будут (довольно) точными, см. Здесь, как рассчитывается расстояние: Справка ArcGIS

Убедитесь, что система координат слоя находится в эквидистантной проекции, а не только во фрейме данных.

После расчета буфер будет соответствующим образом деформироваться при помещении в Web Mercator или любую другую веб-проекцию, которую вы собираетесь использовать.

Что касается того, почему сами линии изогнуты и почему это может создать проблемы:

Основная проблема заключается в том, что плоские маршруты на проекции Меркатора, такие как эта, отображаются в виде кривой, например:

Карта маршрута Air Canada

Это фундаментальная проблема с картами Меркатора, так как они предназначены для морской навигации, где свойства прямых линий на этих проекциях являются ценными (прямая линия на проекции Меркатора - прямая линия; линия с тем же компасом, проходящая через целое путешествие).

Однако самолеты не летают по прямолинейным линиям, потому что эффективность использования топлива важнее, чем простая навигация, и, следовательно, летают вдоль больших кругов, которые отображаются в виде кривых на проекции Меркатора.

coneypylon
источник
эффективность использования топлива и добраться до места назначения как можно быстрее .
cffk
... который, почему фактический путь будет принимать во внимание Jet Stream.
Винс
2
Галл-Петерс - проекция равной площади, а не равноудаленная. Для эквидистант вы хотите что-то вроде азимутальной ортографической проекции с центром в вашем источнике.
HeikkiVesanto
Да, я не думал. Конформная проекция также сделает разумную работу по сохранению расстояния, да
coneypylon