计算坐标列表之间的地理距离(lat,lng)

时间:2016-12-20 09:19:07

标签: python gps distance

我正在使用从GPS传感器提取的一些数据来编写烧瓶应用程序。我能够在地图上绘制路线,我想计算GPS传感器行进的距离。一种方法是获得开始和结束坐标,但是由于传感器行进的方式,这是非常不准确的。因此,我对每50个传感器样本进行采样。如果实际传感器样本大小为1000,我现在将有20个样本(通过提取每50个样本)。

现在我希望能够通过函数放置我的样本列表来计算距离。到目前为止,我已经能够使用软件包geopy,但是当我采用大型gps样本集时,我确实得到了太多的请求"错误,更不用说处理请求会有额外的处理时间,这不是我想要的。

有没有更好的方法来计算包含纬度和经度坐标的列表元素的累积距离?

positions = [(lat_1, lng_1), (lat_2, lng_2), ..., (lat_n, lng_n)]

我找到了许多不同数学方法的方法,只用2个坐标(lat1,lng1和lat2和lng2)计算距离,但没有一个支持坐标列表。

这是我使用geopy的当前代码:

from geopy.distance import vincenty

def calculate_distances(trips):
    temp = {}
    distance = 0
    for trip in trips:
        positions = trip['positions']
        for i in range(1, len(positions)):
            distance += ((vincenty(positions[i-1], positions[i]).meters) / 1000)
            if i == len(positions):
                temp = {'distance': distance}
                trip.update(temp)
                distance = 0

trips是一个列表元素,包含关于行程的信息键值对的字典(持续时间,距离,起点和终点坐标等),并且行程内的对象位置是元组坐标列表可视化上面。

trips = [{data_1}, {data_2}, ..., {data_n}]

2 个答案:

答案 0 :(得分:1)

我建议将你的(x,y)坐标变换为复数,因为计算距离更容易计算。因此,以下功能应该起作用:

def calculate_distances(trips):
    for trip in trips:
        positions = trip['positions']
        c_pos = [complex(c[0],c[1]) for c in positions]
        distance = 0
        for i in range(1, len(c_pos)):
            distance += abs(c_pos[i] - c_pos[i-1])
        trip.update({'distance': distance})

我正在做的是将每个(lat_1, lng_1) touple转换为单个复数c1 = lat_1 + j*lng_1,并创建一个由[c1, c2, ... , cn]组成的列表。

总的来说,复数是一个二维数,因此,如果你有二维坐标,你可以做到这一点,这对于地理定位是完美的,但是对于三维空间坐标是不可能的,例如

完成此操作后,您可以轻松计算两个复数c1c2之间的距离dist12 = abs(c2 - c1)。递归地执行此操作可获得总距离。

希望这有帮助!

答案 1 :(得分:1)

这是我最终使用的解决方案。如果你想查找它为自己做的事情,那就称之为Haversine(距离)功能。

我也改变了我的方法。我的输入(positions)是元组坐标列表:

def calculate_distance(positions):
    results = []
    for i in range(1, len(positions)):
        loc1 = positions[i - 1]
        loc2 = positions[i]

        lat1 = loc1[0]
        lng1 = loc1[1]

        lat2 = loc2[0]
        lng2 = loc2[1]

        degreesToRadians = (math.pi / 180)
        latrad1 = lat1 * degreesToRadians
        latrad2 = lat2 * degreesToRadians
        dlat = (lat2 - lat1) * degreesToRadians
        dlng = (lng2 - lng1) * degreesToRadians

        a = math.sin(dlat / 2) * math.sin(dlat / 2) + math.cos(latrad1) * \
        math.cos(latrad2) * math.sin(dlng / 2) * math.sin(dlng / 2)
        c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))
        r = 6371000

        results.append(r * c)

    return (sum(results) / 1000)  # Converting from m to km