如何计算多个经纬度数据之间的距离?

How can I calculate distance between multiple latitude and longitude data?

我有1100个站位(经纬度)数据和10000个房屋位置(经纬度)数据。是否可以使用R代码计算每栋房屋的车站与房屋之间的最短距离?我还想要为每个房屋提供最短距离的车站。可能吗?

这是一个玩具示例,用于查找 m 点和 n 城市之间的质量距离。它应该直接转化为您的 station/house 问题。

我提出了世界城市,旋转了地球(可以这么说),并停在了四个城市。然后我再次旋转并停在两个点上。这里的两个计数是无关紧要的:如果我们有 4 和 2 或者 1100 和 10000,应该没什么关系。

worldcities <- read.csv(header = TRUE, stringsAsFactors = FALSE, text = "
lat,lon
39.7642548,-104.9951942
48.8588377,2.2770206
26.9840891,49.4080842
13.7245601,100.493026")

coords <- read.csv(header = TRUE, stringsAsFactors = FALSE, text = "
lat,lon
27.9519571,66.8681431
40.5351151,-108.4939948")

(快速说明...通常,工具会在 "latitude, longitude" 中为我们提供坐标,至少根据我的经验。geosphere 函数假定 "longitude, latitude"。所以我的坐标上面是直接从 google 地图中的随机视图复制的,我不想编辑它们;因此,我用 [,2:1] 列索引反转下面的列。如果你忘记并给出坐标不可否认是不正确的,你会得到错误 Error in .pointsToMatrix(p1) : latitude < -90,这应该是你可能颠倒坐标顺序的结果。此时你挠头想知道是否所有其他项目都使用了错误的坐标,质疑你的结论。不是我,我从来没有去过那里。今年。)

让我们找出每个 coords(每行)和每个城市(每列)之间的距离(以米为单位):

dists <- outer(seq_len(nrow(coords)), seq_len(nrow(worldcities)),
               function(i, j) geosphere::distHaversine(coords[i,2:1], worldcities[j,2:1]))
dists
#            [,1]    [,2]     [,3]     [,4]
# [1,] 12452329.0 5895577  1726433  3822220
# [2,]   309802.8 7994185 12181477 13296825

找到距离每个坐标最近的城市应该是直截了当的,

apply(dists, 1, which.min)
# [1] 3 1

即第一个点离第三个城市最近,第二个点离第一个城市最近

为了证明这是一个适用于大量对的可行解决方案,这里将同样的问题放大了一点。

worldcities_big <- do.call(rbind, replicate(250, worldcities, simplify = FALSE))
nrow(worldcities_big)
# [1] 1000
coords_big <- do.call(rbind, replicate(5000, coords, simplify = FALSE))
nrow(coords_big)
# [1] 10000
system.time(
  dists <- outer(seq_len(nrow(coords_big)), seq_len(nrow(worldcities_big)),
                 function(i, j) geosphere::distHaversine(coords_big[i,2:1], worldcities_big[j,2:1]))
)
#    user  system elapsed 
#   67.62    2.22   70.03 

所以是的,不是瞬时的,但是70秒对于10,000,000的距离计算来说并不可怕。你能让它更快吗?也许,不确定具体如何,很容易。我认为一些启发式方法可能会将它从 O(m*n) 时间减少到 O(m*log(n)),但我不知道这是否值得它引入的编码复杂性。