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

时间:2020-02-04 02:46:06

标签: r distance latitude-longitude

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

1 个答案:

答案 0 :(得分:0)

这是一个玩具示例,用于查找m个点与n个城市之间的质量距离。它应该直接转换为您的车站/房屋问题。

我抚养了大城市,旋转了地球(可以这么说),然后停在了四个城市。然后我再次旋转并停在两点。这里的两个数无关紧要:如果我们有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")

(快速笔记……通常,至少在我的经验中,工具会给我们提供“经度,纬度”的坐标。geosphere函数却假定为“经度,纬度”。因此我上面的坐标是直接从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 

所以,它不是瞬时的,但是对于10,000,000个距离计算而言,70秒并不可怕。你能使它更快吗?也许,不确定确切的方法,轻松。我认为有些启发式方法可能会将其从O(m*log(n))时间减少到O(m*n),但是我不知道这是否值得它引入的编码复杂性。