计算几个位置之间的全局距离

Posted

技术标签:

【中文标题】计算几个位置之间的全局距离【英文标题】:Calculate global distance between several locations 【发布时间】:2018-05-16 22:34:51 【问题描述】:

我正在根据坐标计算两个全局位置之间的距离。仅使用两个位置时,我得到了结果:

def global_distance(location1, location2):
    lat1, lon1 = location1
    lat2, lon2 = location2
    radius = 6371 # radius of the Earth

    dlat = math.radians(lat2-lat1)
    dlon = math.radians(lon2-lon1)
    a = math.sin(dlat/2) * math.sin(dlat/2) + math.cos(math.radians(lat1)) \
        * math.cos(math.radians(lat2)) * math.sin(dlon/2) * math.sin(dlon/2)
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
    d = radius * c

    return d

lat1 = 55.32; lat2 = 54.276; long1 = -118.8634; long2 = -117.276


print( global_distance((lat1, long1), (lat2, long2)))

如果我想计算几个位置之间的距离怎么办?假设我有一个包含三个位置的 CSV 文件:

Location   Lat1      Long1      
 A         55.322    -117.17
 B         57.316    -117.456
 C         54.275    -116.567

如何遍历这两列并生成 (A,B)、(A,C) 和 (B,C) 之间的距离?

【问题讨论】:

首先,您是如何读取该 CSV 文件的?列表/元组、字典或对象的列表、2D numpy 数组、pandas DataFrame ......? 我的意思是我想将它作为 pandas 数据框来阅读,并想遍历所有三个元素。但任何阅读方式都可以。我只是不知道如何正确地迭代它们 【参考方案1】:

假设您已将该 CSV 读入某种序列序列(例如,list(csv.reader(f))),您需要做的就是遍历所有位置组合。这正是itertools.combinations 所做的:

>>> locs = [('A', 55.322, -117.17), ('B', 57.316, -117.456), ('C', 54.275, 116.567)]
>>> for (loc1, lat1, lon1), (loc2, lat2, lon2) in itertools.combinations(locs, 2):
...     print(loc1, loc2, global_distance((lat1, lon1), (lat2, lon2)))
A B 222.42244003744995
A C 122.66829007875741
B C 342.67144769115316

当您查看上面链接的文档时,请注意 combinations_with_replacementpermutationsproduct,它们通常是类似但略有不同的问题的答案。

这应该很容易适应字典序列或Location 实例的字典等。另一方面,如果您有类似 2D numpy 数组或 pandas DataFrame 的东西,您可能想要做一些不同的事情。 (尽管通过快速搜索,看起来只是将itertoolsfromiter 组合成一个数组并不比其他任何东西慢得多,即使你想用空间换取时间来广播你的global_distance 函数.)

【讨论】:

【参考方案2】:

我会通过 pandas 从您的文件中导入数据:

import pandas as pd
df = pd.read_table(filename, sep='\s+', index_col=0)

另外还可以导入itertools:

import itertools as it

有了这个,你可以得到一个像这样的迭代的所有组合,作为数据帧索引的例子:

for i in it.combinations(df.index, 2): print(i)
('A', 'B')
('A', 'C')
('B', 'C')

这表明,您将获得所需的组合。 现在对你的数据框的数据做同样的事情:

for i in it.combinations(df.values, 2): print(global_distance(i[0], i[1]))
222.4224400374507
122.66829007875636
342.671447691153

如果你想在输出中包含位置名称,你可以在导入时去掉index_col=0,这样A、B和C也是df.values的一部分,你可以写:

for i in it.combinations(df.values, 2): print(i[0][0], '-', i[1][0], global_distance(i[0][1:], i[1][1:]))
A - B 222.4224400374507
A - C 122.66829007875636
B - C 342.671447691153

【讨论】:

以上是关于计算几个位置之间的全局距离的主要内容,如果未能解决你的问题,请参考以下文章

使用距位置的距离有效地计算最近的 5 个位置

如何在谷歌地图 api 中计算从 1 个位置到许多其他位置的距离? [复制]

查找超过 100K 个位置之间的距离

Android - 沿街 2 个位置之间的距离和时间

2 个位置之间未显示多段线,但显示了时间和距离

计算我的位置与多个位置之间的距离