计算连续 GPS 点之间的距离,并根据该距离降低 GPS 密度

Posted

技术标签:

【中文标题】计算连续 GPS 点之间的距离,并根据该距离降低 GPS 密度【英文标题】:Calculate distance between consecutive GPS points and reduce GPS density based on this distance 【发布时间】:2021-06-09 16:10:43 【问题描述】:

我有一个代表车辆 GPS 轨迹的 pandas 数据框

d1 = 'id': [1, 2, 3, 4, 5, 6, 7, 8, 9], 'longitude': [4.929783, 4.932333, 4.933950, 4.933900, 4.928467, 4.924583, 4.922133, 4.921400, 4.920967], 'latitude': [52.372250, 52.370884, 52.371101, 52.372234, 52.375282, 52.375950, 52.376301, 52.376232, 52.374481]
df1 = pd.DataFrame(data=d1)

id   longitude   latitude     
1    4.929783    52.372250    
2    4.932333    52.370884    
3    4.933950    52.371101    
4    4.933900    52.372234    
5    4.928467    52.375282    
6    4.924583    52.375950    
7    4.922133    52.376301    
8    4.921400    52.376232    
9    4.920967    52.374481    

我已经计算出连续 GPS 点之间的(正弦)距离,如下所示:

import numpy as np
def haversine(lat1, lon1, lat2, lon2, earth_radius=6371):
    lat1, lon1, lat2, lon2 = np.radians([lat1, lon1, lat2, lon2])

    a = np.sin((lat2-lat1)/2.0)**2 + np.cos(lat1) * np.cos(lat2) * np.sin((lon2-lon1)/2.0)**2
    km = earth_radius * 2 * np.arcsin(np.sqrt(a))
    m = km * 1000
    return m

df1['distance'] = haversine(df1['latitude'], df1['longitude'],
                       df1['latitude'].shift(), df1['longitude'].shift())

id  longitude   latitude    distance
1   4.929783    52.372250   NaN
2   4.932333    52.370884   230.305288
3   4.933950    52.371101   112.398101
4   4.933900    52.372234   126.029572
5   4.928467    52.375282   500.896578
6   4.924583    52.375950   273.918990
7   4.922133    52.376301   170.828592
8   4.921400    52.376232   50.345227
9   4.920967    52.374481   196.908503

现在我想创建一个函数

    如果连续 GPS 点之间的距离小于 150 米,则删除第二个点,即下一个点。

    始终保留最后一个(和第一个)GPS 点,无论之前保留的要素之间的距离如何

意思应该是输出:

id  longitude   latitude    distance
1   4.929783    52.372250   NaN
2   4.932333    52.370884   230.305288
5   4.928467    52.375282   500.896578
6   4.924583    52.375950   273.918990
7   4.922133    52.376301   170.828592
9   4.920967    52.374481   196.908503

在 python 中实现这一目标的最佳方法是什么?

【问题讨论】:

您也要保持最大距离吗?即,如果您的点 A、B、C 使得 A、B “靠得太近”,但 A、C “相距太远”,会发生什么?在这种情况下你想删除 A 并保留 B 吗? 好点。我想将最大距离保持为最小距离的 2 倍(在这种情况下为 100 米)。这意味着也应该保留 id nr 7 的点 【参考方案1】:

注意:这不考虑最大距离...这需要一些前瞻性和优化。


我会遍历并只传回您想要保留的行的索引值。在loc 调用中使用这些索引值。

距离

使用您想要的任何指标。我使用了 OP 的半正弦距离。

def haversine(lat1, lon1, lat2, lon2, earth_radius=6371):
    lat1, lon1, lat2, lon2 = np.radians([lat1, lon1, lat2, lon2])

    a = np.sin((lat2-lat1)/2.0)**2 + np.cos(lat1) * np.cos(lat2) * np.sin((lon2-lon1)/2.0)**2
    km = earth_radius * 2 * np.arcsin(np.sqrt(a))
    m = km * 1000
    return m

def dis(t0, t1):
    lat0 = t0.latitude
    lon0 = t0.longitude
    lat1 = t1.latitude
    lon1 = t1.longitude
    return haversine(lat0, lon0, lat1, lon1)

循环

def f(d, threshold=50):
    itups = d.itertuples()
    
    last = next(itups)
    
    indices = [last.Index]
    distances = [0]

    for tup in itups:
        distance = dis(tup, last)
        if distance > threshold:
            indices.append(tup.Index)
            distances.append(distance)
            last = tup
            
    return indices, distances
        

结果

idx, distances = f(df1, 150)
df1.loc[idx].assign(distance=distances)

   id  longitude   latitude    distance
0   1   4.929783  52.372250    0.000000
1   2   4.932333  52.370884  230.305288
3   4   4.933900  52.372234  183.986479
4   5   4.928467  52.375282  500.896578
5   6   4.924583  52.375950  273.918990
6   7   4.922133  52.376301  170.828592
8   9   4.920967  52.374481  217.302775

【讨论】:

感谢您的回复!输出距离确实似乎与实际距离不匹配。我已经用正确计算的距离更新了我的帖子 我已经使用你的 hasrsine 函数更新了我的帖子。 谢谢。不过,我仍然在结果表中看到了一些意想不到的距离。例如,id 为4 的坐标对的距离为183.986479。但是,我在未处理的表中看不到这个距离。这同样适用于 ID 为9 的坐标对,其计算距离为217.302775,但在未处理的表中距离为196.908503。知道问题可能是什么吗?

以上是关于计算连续 GPS 点之间的距离,并根据该距离降低 GPS 密度的主要内容,如果未能解决你的问题,请参考以下文章

计算gps点之间的步行距离

python 计算两个GPS点之间的距离。

我如何计算Java中两个gps点之间的距离?

计算 n 个 GPS 点之间的最短距离

GPS怎样根据测点计算距离

计算大量 GPS 坐标之间的成对路由距离