在两个经度-纬度点之间生成更多点

时间:2018-11-10 23:01:12

标签: python python-3.x latitude-longitude

在2D平面中,给定两个点(x1, y1)(x2, y2),很容易沿两个点之间的直线生成N等距的点。这也适用于3D平面。

但是,我正在尝试找出如何处理地理坐标点。为了进一步说明我的观点,假设您有一个带有(latA, lonA)的点A,代表其纬度和经度,另一个是带有(latB, lonB)的点B。您将如何在A和B之间产生N点? python中是否有一个简单的库可以实现这一目标?

1 个答案:

答案 0 :(得分:1)

您可以直接使用numpy执行此操作。这个想法是对3D空间使用标准的插值公式,例如A + d * (B - A)。这样计算的点位于A和B之间的弦上,但可以投影回球体上。

为了在角度上具有均匀的分布,我们需要从角度到弦上距离的映射,如图所示

Geometry

由于所有角度和三角函数都很容易弄乱,因此它显示了等距角度的和弦位置,并通过下面的代码生成以检查正确性。

def embed_latlon(lat, lon):
    """lat, lon -> 3d point"""
    lat_, lon_ = np.deg2rad(lat), np.deg2rad(lon)
    r = np.cos(lat_)
    return np.array([
        r * np.cos(lon_),
        r * np.sin(lon_),
        np.sin(lat_)
    ]).T

def project_latlon(x):
    """3d point -> (lat, lon)"""
    return (
        np.rad2deg(np.arcsin(x[:, 2])),
        np.rad2deg(np.arctan2(x[:, 1], x[:, 0]))
    )

def _great_circle_linspace_3d(x, y, n):
    """interpolate two points on the unit sphere"""
    # angle from scalar product
    alpha = np.arccos(x.dot(y))
    # angle relative to mid point
    beta = alpha * np.linspace(-.5, .5, n)
    # distance of interpolated point to center of sphere
    r = np.cos(.5 * alpha) / np.cos(beta)
    # distance to mid line
    m = r * np.sin(beta)
    # interpolation on chord
    chord = 2. * np.sin(.5 * alpha) 
    d = (m + np.sin(.5 * alpha)) / chord

    points = x[None, :] + (y - x)[None, :] * d[:, None]
    return points / np.sqrt(np.sum(points**2, axis=1, keepdims=True))

def great_circle_linspace(lat1, lon1, lat2, lon2, n):
    """interpolate two points on the unit sphere"""
    x = embed_latlon(lat1, lon1)
    y = embed_latlon(lat2, lon2)
    return project_latlon(_great_circle_linspace_3d(x, y, n))

# example on equator
A = 0, 0.
B = 0., 30.

great_circle_linspace(*A, *B, n=5)
(array([0., 0., 0., 0., 0.]), array([ 0. ,  7.5, 15. , 22.5, 30. ]))