【问题标题】:R - How to calculate distance between two sets of coordinate points?R - 如何计算两组坐标点之间的距离?
【发布时间】:2019-08-20 10:04:07
【问题描述】:

我有一个与此 SO 帖子非常相似的问题:

Geographic / geospatial distance between 2 lists of lat/lon points (coordinates)

这是一个经过编辑的坐标示例集,用于说明我的情况:

require(tidyverse)

list1 <- data.frame(longitude = c(72, 74, 76, 78, 79, 82), 
                    latitude = c(20.5, 19, 19.5, 20, 22, 21),
                    area = "A")
list2 <- data.frame(longitude = c(71, 73, 75, 77, 79, 78.5, 72), 
                    latitude = c(21.5, 22, 20.5, 23, 23.5, 24, 24), 
                    area = "B")

df <- bind_rows(list1, list2)

ggplot(data = df) +
    geom_point(aes(x = longitude, y = latitude, color = area)) +
    geom_line(data = list1, aes(x = longitude, y = latitude, color = area)) +
    geom_line(data = list1[c(2,6),], aes(x = longitude, y = latitude, color = area)) +
    geom_line(data = list1[c(1,4),], aes(x = longitude, y = latitude, color = area)) +
    geom_line(data = list2[c(1,7),], aes(x = longitude, y = latitude, color = area)) +
    geom_line(data = list2[c(7,6),], aes(x = longitude, y = latitude, color = area)) +
    geom_line(data = list2[c(6,5),], aes(x = longitude, y = latitude, color = area)) +
    geom_line(data = list2[c(5,3),], aes(x = longitude, y = latitude, color = area)) +
    geom_line(data = list2[c(3,1),], aes(x = longitude, y = latitude, color = area))

所以我需要计算两个坐标点列表之间的最小距离。我已经能够完成这项工作,但我注意到我需要更高效的东西 - 数据太大了。

我想到的一种可能性是形成这些区域的非重叠多边形并计算一组点到相邻多边形的距离。有没有办法形成这些多边形?凸面外壳不是一种选择,因为这些区域非常粗糙。

另一种选择是在区域之间形成一条线。

编辑:我在图中添加了一些线条来说明多边形。

【问题讨论】:

  • 你能和我们分享sample of your data吗?帮助你会更容易
  • 我对地理空间主题不太熟悉,但也许你可以调整this answer 来计算最小距离,如果需要也可以使用不同的距离。
  • patL:我现在包含了一个带有一些虚假数据的小示例。
  • "是对这些区域形成不重叠的多边形,并计算一组点到相邻多边形的距离。" - 你能为你的测试数据画出你正在谈论的多边形吗? (也许使用绘画程序?)

标签: r geospatial


【解决方案1】:

也许这就是你要找的?

#load libraries
library(dplyr)
library(sf)

#create row_id's, and make it a simple (spatial) feature
list1.sf <- list1 %>% 
  mutate( id = row_number() ) %>% 
  st_as_sf( coords = c("longitude", "latitude"), crs = 4326 )
list2.sf <- list2 %>% 
  mutate( id = row_number() ) %>% 
  st_as_sf( coords = c("longitude", "latitude"), crs = 4326 )

#find nearest points in list2 for each id in list1, and as a bonus, calculate the distance to this point
list1.sf %>% 
  dplyr::group_by( id ) %>%
  dplyr::mutate( np = sf::st_nearest_feature( geometry, list2.sf ),
                 dist_np = as.numeric( sf::st_distance( geometry, list2.sf[np,] ) ) )


# Simple feature collection with 6 features and 4 fields
# geometry type:  POINT
# dimension:      XY
# bbox:           xmin: 72 ymin: 19 xmax: 82 ymax: 22
# epsg (SRID):    4326
# proj4string:    +proj=longlat +datum=WGS84 +no_defs
# # A tibble: 6 x 5
# # Groups:   id [6]
# area     id    geometry    np dist_np
# * <fct> <int> <POINT [°]> <int>   <dbl>
# 1 A         1   (72 20.5)     1 151880.
# 2 A         2     (74 19)     3 196361.
# 3 A         3   (76 19.5)     3 152335.
# 4 A         4     (78 20)     3 318287.
# 5 A         5     (79 22)     5 166111.
# 6 A         6     (82 21)     5 415019.

【讨论】:

  • 我认为这是计算两组点之间距离的另一个版本。我在这里追求的是我可以将一个集合转换为一个不与另一个集合重叠的多边形,然后计算到该多边形的距离。或者,我可以在这两组之间构建一条线,然后计算到那条线的距离。
【解决方案2】:

你可以计算欧几里得距离 我改变了一点数据集。我放弃最后一列。

x1 <- data.frame(longitude = c(72, 74, 76, 78, 79, 82), 
                    latitude = c(20.5, 19, 19.5, 20, 22, 21))
x2 <- data.frame(longitude = c(71, 73, 75, 77, 79, 78.5, 72), 
                    latitude = c(21.5, 22, 20.5, 23, 23.5, 24, 24))

euc.dist <- function(x1, x2) sqrt(sum((x1 - x2) ^ 2))


dist <- NULL
for(i in 1:nrow(x1)) dist[i] <- euc.dist(x1[i,],x2[i,])
dist

【讨论】:

  • 我不认为这就是我所追求的。我想计算从每个点到由属于另一组的点构成的多边形或线的距离。