简体   繁体   English

使用R识别到某个位置的最近点并计算沿网络/道路的距离

[英]Using R to identify nearest point to a location and calculate the distance between them along a network/road

I have a series of locations (Points_B) and would like to find the closest point to them from a different set of points (Points_A) and the distance between them in kms. 我有一系列位置(Points_B),想从一组不同的点(Points_A)中找到最接近它们的点,以及它们之间的距离(以kms为单位)。 I can do this as the crow flies but cannot work out how to do the same along a road network (the 'Roads' object in the code). 我可以在乌鸦飞翔时做到这一点,但无法弄清楚如何在道路网(代码中的“ Roads”对象)上做同样的事情。 The code I have so far is a follows: 到目前为止,我的代码如下:

library(sp)
library(rgdal)
library(rgeos)

download.file("https://dl.dropboxusercontent.com/u/27869346/Road_Shp.zip", "Road_Shp.zip")
#2.9mb 
unzip("Road_Shp.zip")
Roads <- readOGR(".", "Subset_Roads_WGS")

Points_A <- data.frame(ID = c("A","B","C","D","E","F","G","H","I","J","K","L"), ID_Lat  = c(50.91487, 50.92848, 50.94560, 50.94069, 50.92275, 50.94109, 50.92288, 50.92994, 50.92076, 50.90496, 50.89203, 50.88757), ID_Lon  = c(-1.405821, -1.423619, -1.383509, -1.396910, -1.441801, -1.459088, -1.466626, -1.369458, -1.340104, -1.360153, -1.344662, -1.355842))
rownames(Points_A) <- Points_A$ID

Points_B <- data.frame(Code = 1:30, Code_Lat  = c(50.92658, 50.92373, 50.93785, 50.92274, 50.91056, 50.88747, 50.90940, 50.91328, 50.91887, 50.92129, 50.91326, 50.91961, 50.91653, 50.90910, 50.91432, 50.93742, 50.91848, 50.93196, 50.94209, 50.92080, 50.92127, 50.92538, 50.88418, 50.91648, 50.91224, 50.92216, 50.90526, 50.91580, 50.91203, 50.91774), Code_Lon  = c(-1.417311, -1.457155, -1.400106, -1.374250, -1.335896, -1.362710, -1.360263, -1.430976, -1.461693, -1.417107, -1.426709, -1.439435, -1.429997, -1.413220, -1.415046, -1.440672, -1.392502, -1.459934, -1.432446, -1.357745, -1.374369, -1.458929, -1.365000, -1.426285, -1.403963, -1.344068, -1.340864, -1.399607, -1.407266, -1.386722))
rownames(Points_B) <- Points_B$Code

Points_A_SP <- SpatialPoints(Points_A[,2:3])
Points_B_SP <- SpatialPoints(Points_B[,2:3])
Distances <- (gDistance(Points_A_SP, Points_B_SP, byid=TRUE))*100

Points_B$Nearest_Points_A_CF <- colnames(Distances)[apply(Distances,1,which.min)]
Points_B$Distance_Points_A_CF <- apply(Distances,1,min)

The output I am after would be two additional columns in 'Points_B' with 1) having the nearest Point A object ID along the road network and 2) having the distance along the network in km . 我得到的输出将是'Points_B'中的另外两列,其中1)沿道路网络具有最近的Point A对象ID2)沿网络的距离为km Any help would be appreciated. 任何帮助,将不胜感激。 Thanks. 谢谢。

I've been working on this kind of problem all day. 我整天都在研究这种问题。 Try mapdist() in the ggmap package and see if this works: ggmap包中尝试mapdist() ,看看是否ggmap

library(dplyr)
library(ggmap)
#Your data
   Points_A <- data.frame(ID = c("A","B","C","D","E","F","G","H","I","J","K","L"), ID_Lat  = c(50.91487, 50.92848, 50.94560, 50.94069, 50.92275, 50.94109, 50.92288, 50.92994, 50.92076, 50.90496, 50.89203, 50.88757), ID_Lon  = c(-1.405821, -1.423619, -1.383509, -1.396910, -1.441801, -1.459088, -1.466626, -1.369458, -1.340104, -1.360153, -1.344662, -1.355842))
   Points_B <- data.frame(Code = 1:30, Code_Lat  = c(50.92658, 50.92373, 50.93785, 50.92274, 50.91056, 50.88747, 50.90940, 50.91328, 50.91887, 50.92129, 50.91326, 50.91961, 50.91653, 50.90910, 50.91432, 50.93742, 50.91848, 50.93196, 50.94209, 50.92080, 50.92127, 50.92538, 50.88418, 50.91648, 50.91224, 50.92216, 50.90526, 50.91580, 50.91203, 50.91774), Code_Lon  = c(-1.417311, -1.457155, -1.400106, -1.374250, -1.335896, -1.362710, -1.360263, -1.430976, -1.461693, -1.417107, -1.426709, -1.439435, -1.429997, -1.413220, -1.415046, -1.440672, -1.392502, -1.459934, -1.432446, -1.357745, -1.374369, -1.458929, -1.365000, -1.426285, -1.403963, -1.344068, -1.340864, -1.399607, -1.407266, -1.386722))

#Combine coords into one field (mapdist was doing something funny with the commas so I had to specify "%2C" here)
   Points_A$COORD <- paste(ID_Lat, ID_Lon, sep="%2C")
   Points_B$COORD <- paste(Code_Lat, Code_Lon, sep="%2C")

#use expand grid to generate all combos
   get_directions <- expand.grid(Start = Points_A$COORD,
                                 End = Points_B$COORD,
                                 stringsAsFactors = F,
                                 KEEP.OUT.ATTRS = F) %>%
                     left_join(select(Points_A, COORD, ID), by = c("Start" = "COORD")) %>%
                     left_join(select(Points_B, COORD, Code), by = c("End" = "COORD"))

#make a base dataframe
   route_df <- mapdist(from = get_directions$Start[1], 
                       to = get_directions$End[1], 
                       mode = "driving") %>% 
               mutate(Point_A = get_directions$ID[1],
                      Point_B = get_directions$Code[1])

#get the rest in a for-loop
  start <- Sys.time()
    for(i in 2:nrow(get_directions)){
      get_route <- mapdist(from = get_directions$Start[i], 
                           to = get_directions$End[i], 
                           mode = "driving") %>% 
                  mutate(Point_A = get_directions$ID[i],
                         Point_B = get_directions$Code[i])

      route_df <<- rbind(route_df, get_route) #add to your original file

      Sys.sleep(time = 1) #so google doesn't get mad at you for speed

      end <- Sys.time()

      print(paste(i, "of", nrow(get_directions), 
                  round(i/nrow(get_directions),4)*100, "%", sep=" "))
      print(end-start)
  }

#save if you want   
write.csv(route_df, "route_df.csv", row.names = F)    

#Route Evaluation
   closest_point <-route_df %>% 
                     group_by(Point_A) %>%
                     filter(km == min(km)) %>%
                     ungroup()

I'm still kind of new at this so there may be a better way to do the data wrangling. 我对此还是有点陌生​​,因此可能会有更好的方法来处理数据。 Hope this helps & good luck 希望这有帮助,祝你好运

The packages igraph, osmr and walkalytics all seem to provide this functionality these days. 如今,igraph,osmr和walkalytics软件包似乎都提供了此功能。 Mode-specific routing networks exist (in various degrees of functionality). 存在特定于模式的路由网络(具有不同程度的功能)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何用R计算参考线(或点)与长/纬点数据框之间的道路网络距离? - How to calculate road network distances between a reference line(or point) and a dataframe of long/lat points with R? 如何使用R计算点与参考点之间的距离? - How to Calculate Distance between points from a reference point using R? 使用 sf 通过两个数据帧之间的不同年份计算最近点坐标和距离 - Calculate nearest point coordinate and distance by differing years between two data frames using sf R/GIS:查找位置和最近线之间的正交距离 - R/GIS: Find orthogonal distance between a location and nearest line 如何计算R中沿线的两个点之间的地理距离? - How to calculate geographic distance between two points along a line in R? R - 计算沿折线的两点之间的距离 - R - Calculate distance between two points along a polyline 计算R中点与最近邻居之间的平均距离 - Calculate average distance between point and closest neighbors in R 如何计算椭球体与R中的点之间的最小距离 - how to calculate minimum distance between an ellipsoid hull and a point in R R:计算每组连续点之间的距离并将其分组 - R: Calculate distance between consecutive points per group and group them R:如何使用GPS识别道路类型? - R: How to identify a road type using GPS?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM