飞机地图范围


10

我想创建一个(网络)地图,该地图显示飞机在某些机场周围的范围。

我试图用飞机的范围来计算缓冲区。在这里,您可以在这里看到结果。

但是现在我已经意识到结果是错误的,因为飞机不走直线路线,而是因为走线较短而弯曲。

有没有办法用较短的曲线来计算范围?

Answers:


20

您可以使用proj4库使用大圆距离来描述一个圆。

例如,这是wgs84 / Equirectangular中距爱丁堡,东京,开普敦和基多3000公里的半径。由于只有基多(Quito)靠近赤道,所以它隐约是“圆形”的。我还添加了一条单一的密集辐条线,其方位角为36度(大约NE)

在此处输入图片说明

如果我们更改为以爱丁堡为中心的方位角等距投影,您会看到爱丁堡周围的半径解析为一个圆...

在此处输入图片说明

在Mercator(如您的Web应用程序)上,当您离开赤道时会看到更多的失真,但是缓冲区更加椭圆化。

在此处输入图片说明

下面的Python代码确实是(需要pyproj匀称

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()

您可以使用有用的QuickWKT插件将WKT输出粘贴到QGIS中。

您可以使用其他方法-如锥面提到的那样,您可以在以米为单位的自定义等距投影上以起点为中心创建一个圆。我发现尽管距离很远,但误差会逐渐增加(2000公里处只有几公里,但是对于洲际距离,这些误差会增加)

从内存中,mmqgis插件允许以km 为单位进行缓冲。我不确定它使用哪种方法。

请注意,你可能有渲染QGIS跨越逆子午线如果你开始在亚洲多边形问题- ogr2ogr-wrapdateline选项可帮助在这里。您可能会发现这对于openlayers / leaflet来说不是问题,IIRC允许经度大于180且小于-180。

esri博客上有一篇关于测地线缓冲的好文章


8

取决于您的距离信息来自何处,这可能并不重要。如果您有一个简单的数字来给出距离,则在任何能精确显示距离的地图投影上,距离都将是相同的(不是墨卡托投影,请考虑几乎所有“等距”投影,例如方位角正投影或类似的投影。例如Lambert Conformal Conic将在远处做得相当不错。)如果以等距投影计算并创建缓冲区,它们将(相当)准确,请参见此处有关距离的计算方法:ArcGIS Help

确保将图层的坐标系设置为等距投影,而不仅仅是数据框。

一旦计算,缓冲区将在放入Web Mercator或您打算使用的任何其他Web投影时相应地扭曲。

至于为什么线条本身是弯曲的,以及为什么这会产生问题:

关键问题在于,像这样的墨卡托投影上的平面路线显示为弯曲的,如下所示:

加拿大航空路线图

这是墨卡托地图的一个基本问题,因为它们打算用于航海导航,在这些投影上,直线的属性很有价值(墨卡托投影上的直线是菱形线;具有与指南针相同的线穿过地图的线)。全程)。

但是,飞机不可以沿菱形线飞行,因为燃油效率比简单的导航更为重要,因此可以沿“大圆圈”飞行,该大圆圈在墨卡托投影上显示为曲线。


燃油效率高,尽快到达目的地
cffk

...这就是为什么实际路径会考虑喷射流的原因。
文斯

2
Gall-Peters是等面积投影,不是等距的。对于等距,您需要像以源为中心的方位正交投影一样的东西。
HeikkiVesanto

是的,我没有在想。保形投影也将在保持距离的基础上做得合理,是的
锥状体
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.