如何测量不同数据框中点之间的距离?

3

我创建了两个包含几何列(POINT类型)的数据框。现在我想要计算每对点之间的距离,例如第一个数据框中第一行的点与第二个数据框中第一行的点之间的距离等。以下是我的数据框:

df1 <- table %>%
  st_as_sf(coords = c("lonCust","latCust"), crs = 4326)

df2 <- table %>%
  st_as_sf(coords = c("lonApp","latApp"), crs = 4326)

我使用了 st_distance 函数:
distance <- st_distance(df1$geometry,df2$geometry)

但是我得到了一个矩阵,其中计算了每个几何列的每对距离:
           [,1]      [,2]        [,3]         [,4]        [,5]  ...
[1,]   139.7924 7735.5718 15225.02995   558.104089  1016.58121
[2,]  8503.0544  755.2915  8764.75396  7957.289600  8788.02800
[3,] 15306.5855 9336.9008    18.96914 14876.589918 15929.51643
[4,]   548.3045 7232.0164 14898.70637     8.094068  1078.38236
[5,]   911.5635 8084.3086 15993.36365  1127.730022    46.97799
.
.

我希望在一个列中计算距离,只在对应的几何行之间进行计算:

           [,1]     
[1,]   139.7924 
[2,]  8503.0544
[3,] 15306.5855 
[4,]   548.3045
[5,]   911.5635
.
.


我了解到有关geosphere包的内容,但是sf具有非常好用的st_distance函数来测量距离,我想使用它。最重要的是,我需要先将这些数据框连接起来吗?简单的dplyr中的inner_join无法连接两个空间数据框,而st_join则不适用于我,因为我不想通过几何形状进行连接(两个数据框中的几何形状完全不同)。

2
你离成功很近了。st_distance(df1$geometry, df2$geometry, by_element = TRUE) - mrhellmann
谢谢!顺便说一下,我有大约25000行数据,计算速度很慢,我认为最好在服务器端计算距离。 - mustafa00
4
иү™з§Қ情况下пәЊдҢүз”Ёlibrary(geodist)еЏҮиѓҢж›өеү«пәЊиЂЊдё”еЏҮд»Өз›өжҺӨењЁdata.frameдёЉж“ҚдҢњгЂ‚иҮ·жџӨзњ‹geodist()е’Њ/ж€–geodist_vec()пәЊе№¶и®ңзҢ®paired = TRUEгЂ‚ - SymbolixAU
2个回答

3

正如@mrhellmann所提到的,您可以添加by_element=T即可。 如果速度仍然是一个问题,我建议使用geosphere包中的DistGeo()。但请确保查看文档以确定您的数据是否适用于此函数。

library(geosphere)
library(tidyverse)
library(sf)

df1 <- table %>%
  st_as_sf(coords = c("lonCust","latCust"), crs = 4326)

doParallel::registerDoParallel()
df_crs4326 <- df1 %>%
  group_by(your_id_here) %>% 
  mutate(
    lonCust = map(geometry, 2) %>% unlist(),
    latCust= map(geometry, 1) %>% unlist(),
    # geometry_2 = st_as_sfc(coords = c("lonApp","latApp"), crs = 4326)
    ) %>%
  mutate(
    distance_to_next = distGeo(c(lonCust, latCust), c(lonApp, latApp)) %>% set_units(m),
    # distance_2 = st_distance(geometry, geometry_2, by_element = TRUE)
    ) %>%
    ungroup()

请注意,我不确定注释部分在可重现的数据上是否有效。

2

超快向量化计算

该方法的实现过程如下:

  1. 将(经度,纬度)坐标投影到一个与您感兴趣的区域等距离的相关坐标系中。(等距坐标系统保持点之间的距离测量,因此您可以使用基本几何知识来计算距离)。
  2. 将几何形状转换为具有X和Y列的Base R矩阵。
  3. 最后,只需使用勾股定理计算成对点之间的距离。

首先要正确获取坐标参考系统(CRS)

为了使此方法起作用,您需要一个等距的坐标参考系统(CRS)。这意味着在感兴趣的区域内,任何距离计算都会被保留。

假设您想计算在美国境内的距离,您可以使用EPSG:102005。请参阅此GIS答案获取更多详细信息。选择CRS至关重要,因此请确保正确选择,否则答案将毫无意义。

应用于您的示例

crs.source = 4326
crs.dest = st_crs("+proj=eqdc +lat_0=39 +lon_0=-96 +lat_1=33 +lat_2=45 +x_0=0 +y_0=0 +datum=NAD83 +units=m +no_defs")

# coords1 and coords2 are matrixes with columns X and Y and rows of points in the `crs.dest` coordinate system.
coords1 <- table %>%
  st_as_sf(coords = c("lonCust","latCust"), crs = crs.source) %>%
  st_transform(crs.dest) %>%
  st_coordinates()
  
coords2 <- table %>%
  st_as_sf(coords = c("lonApp","latApp"), crs = crs.source) %>%
  st_transform(crs.dest) %>%
  st_coordinates()

# This is a vectorised computation, and so should be instant for a mere 25,000 rows :-)
table$distances = local({
  x_diff = coords1[, 'X'] - coords2[, 'X']
  y_diff = coords1[, 'Y'] - coords2[, 'Y']
  return(sqrt(x^2 + y^2))
})


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接