计算坐标与参考点之间的距离

4

我想计算经纬度(lat1, lon1)与参考点(52.92343, 5.04127)之间的距离。我希望对数据集中每一行都执行此操作,因此距离将使用每一行中的参考点来计算。这意味着我需要创建一个新的列用于存储以公里为单位的距离。我可以想象您需要使用某种循环函数,但是到目前为止,我还没有找到如何完成此操作的方法。我认为我将不得不使用geodistgeosphere软件包,但可惜我没有成功。请问如何计算这些距离?

structure(list(Day = c("26", "05", "17", "18", "19", "19"), Month = c("07", 
"08", "08", "08", "08", "08"), Year = c("2021", "2021", "2021", 
"2021", "2021", "2021"), Location.Receiver = c("Den Oever Ijsselmeer", 
"Medemblik Ijsselmeer, gemaal", "Den Oever Ijsselmeer", "Den Oever Ijsselmeer", 
"Den Oever Ijsselmeer", "Den Oever Ijsselmeer"), Transmitter = c("A69-1602-59776", 
"A69-1602-59777", "A69-1602-59776", "A69-1602-59776", "A69-1602-59769", 
"A69-1602-59776"), Batch.location = c("Den Oever", "Den Oever", 
"Den Oever", "Den Oever", "Den Oever", "Den Oever"), BatchNr = c(8, 
9, 8, 8, 1, 8), Latitude = c(52.92343, 52.76098, 52.92343, 52.92343, 
52.92343, 52.92343), Longitude = c(5.04127, 5.12172, 5.04127, 
5.04127, 5.04127, 5.04127), Date = structure(c(18834, 18844, 
18856, 18857, 18858, 18858), class = "Date")), row.names = c(1095729L, 
1180267L, 1072657L, 1092667L, 716601L, 1077415L), class = "data.frame")

你的 dput() 输出不完整。 - Phil
修好了,谢谢! - Pepijn95
3个回答

2

无需循环,您可以使用geodist计算坐标数组中的条目与单个点y之间的距离。只需将经纬度坐标明确地传递并保存为数值向量到Distance,而不是作为原始矩阵输出。

library(geodist)

df$Distance <- as.numeric(geodist(df[,9:8], c(5.04127, 52.92343)))
#> object has no named columns; assuming order is lon then lat

df$Distance
#> [1]     0.00 18843.92     0.00     0.00     0.00     0.00

2
"points_in_circle()"函数返回距离参考点给定半径内的点。以下代码将返回距离参考点1000公里以内的所有点:

library(spatialrisk)
points_in_circle(df, lat_center = 52.92343, lon_center = 5.04127, 
                 lon = Longitude, lat = Latitude, radius = 1e6)
#>         Day Month Year            Location.Receiver    Transmitter
#> 1095729  26    07 2021         Den Oever Ijsselmeer A69-1602-59776
#> 1072657  17    08 2021         Den Oever Ijsselmeer A69-1602-59776
#> 1092667  18    08 2021         Den Oever Ijsselmeer A69-1602-59776
#> 716601   19    08 2021         Den Oever Ijsselmeer A69-1602-59769
#> 1077415  19    08 2021         Den Oever Ijsselmeer A69-1602-59776
#> 1180267  05    08 2021 Medemblik Ijsselmeer, gemaal A69-1602-59777
#>         Batch.location BatchNr Latitude Longitude       Date distance_m
#> 1095729      Den Oever       8 52.92343   5.04127 2021-07-26       0.00
#> 1072657      Den Oever       8 52.92343   5.04127 2021-08-17       0.00
#> 1092667      Den Oever       8 52.92343   5.04127 2021-08-18       0.00
#> 716601       Den Oever       1 52.92343   5.04127 2021-08-19       0.00
#> 1077415      Den Oever       8 52.92343   5.04127 2021-08-19       0.00
#> 1180267      Den Oever       9 52.76098   5.12172 2021-08-05   18875.55

reprex package (v2.0.1) 于2021年12月02日创建


1
太好了!这对我很有帮助。谢谢你的帮忙! - Pepijn95

1
请使用 sfunits 库找到另一种解决方案(参见下面的示例)。 示例代码
  • 代码
library(sf)
library(units)

# Convert the df into 'sf' object
df_sf <- df %>% 
  st_as_sf(coords = c("Longitude", "Latitude"), crs = 4326)

# Create the reference 'sf' object
ref_point_sf <- st_point(c(5.04127, 52.92343)) %>% 
  st_coordinates() %>% 
  as.data.frame() %>% 
  st_as_sf(coords = c("X", "Y"), crs = 4326)

# Compute the distance between the reference point and points from 'df_sf'
results <- st_distance(ref_point_sf, df_sf) %>% 
  set_units("km")
  • 输出
results
#> Units: [km]
#>      [,1]     [,2] [,3] [,4] [,5] [,6]
#> [1,]    0 18.85446    0    0    0    0

reprex软件包(v2.0.1)于2021年12月01日创建


作为对您评论的跟进

  • 代码
library(sf)
library(units)
library(dplyr)


# Convert df into 'sf' object
df_sf <- df %>% 
  st_as_sf(coords = c("Longitude", "Latitude"), crs = 4326)

# Create the reference 'sf' object
ref_point_sf <- st_point(c(5.04127, 52.92343)) %>% 
  st_coordinates() %>% as.data.frame() %>% 
  st_as_sf(coords = c("X", "Y"), crs = 4326)

# Compute the distance between the reference point and points from 'df_sf'
results <- st_distance(df_sf, ref_point_sf) %>% 
  set_units("km") %>% 
  as.data.frame() %>% 
  drop_units() %>% 
  `colnames<-`(., "dist_km")

# Add 'results' in the original dataframe
df <- df %>% 
  mutate(dist_km = results)
  • 输出
df
#>         Day Month Year            Location.Receiver    Transmitter
#> 1095729  26    07 2021         Den Oever Ijsselmeer A69-1602-59776
#> 1180267  05    08 2021 Medemblik Ijsselmeer, gemaal A69-1602-59777
#> 1072657  17    08 2021         Den Oever Ijsselmeer A69-1602-59776
#> 1092667  18    08 2021         Den Oever Ijsselmeer A69-1602-59776
#> 716601   19    08 2021         Den Oever Ijsselmeer A69-1602-59769
#> 1077415  19    08 2021         Den Oever Ijsselmeer A69-1602-59776
#>         Batch.location BatchNr Latitude Longitude       Date  dist_km
#> 1095729      Den Oever       8 52.92343   5.04127 2021-07-26  0.00000
#> 1180267      Den Oever       9 52.76098   5.12172 2021-08-05 18.85446
#> 1072657      Den Oever       8 52.92343   5.04127 2021-08-17  0.00000
#> 1092667      Den Oever       8 52.92343   5.04127 2021-08-18  0.00000
#> 716601       Den Oever       1 52.92343   5.04127 2021-08-19  0.00000
#> 1077415      Den Oever       8 52.92343   5.04127 2021-08-19  0.00000

reprex软件包(v2.0.1)于2021年12月02日创建


我已将你的代码应用于我的脚本,看起来它能正常工作。但是,按照我的理解,results 的值现在是1行,2525个单元。我想在原始数据集中增加一个额外的列,其中包含你在 results 中计算的距离。最佳的方法是什么? - Pepijn95
嗨,@Pepijn Vermeiren,请查看上面我对您的评论所做的编辑。希望这就是您要找的。干杯。 - lovalery
非常惊人,完全符合我的要求。谢谢! - Pepijn95
非常感谢您的反馈,@Pepijn95。很高兴我能帮到您。请考虑将此答案标记为“已接受”,以便其他SO用户更容易找到正确的答案。祝您工作顺利。干杯。 - lovalery

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