如何计算多个经纬度数据之间的距离?
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))
,但我不知道这是否值得它引入的编码复杂性。
我有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))
,但我不知道这是否值得它引入的编码复杂性。