0

I would like to calculate the shortest route on a road network between both an origin point and multiple points and between all points.

I am using osmdata to get the road network for my area and I would then like to use stplanr to calculate the distances. However, I can't create a SpatialLinesNetwork with all the roads - I assume because they are not connected? Is there a way of connecting the different road types into a single layer? If this is possible, can route_local in stplanr be used to calculate the shortest distance between one point (Origin in my example) to multiple points (Points in my example) and between all the points (in Points in my example)?

This is the code I have so far:

library(dplyr)
library(sf)
library(osmdata)
library(stplanr)

# Input data
Points <- data.frame(
ID = replicate(72, paste(sample(LETTERS, 5, replace=TRUE), collapse="")),
x = c(440605.3,440327.5,440833.7,442260.5,441453.3,440957.9,441535.5,441209.3,440679.3,440514.1,442210.7,440844.9,440529.3,
440917.1,442072.9,440839.9,440519.5,440219.6,441537.1,441000.2,441767.0,440637.7,441638.0,441049.4,440682.9,440879.3,
440305.4,440379.2,441083.3,442062.8,442269.6,442241.2,442105.1,441805.5,440835.9,442135.3,441721.2,442109.9,442265.8,
440601.6,440815.2,442271.3,442250.1,440647.5,440376.0,440360.9,440162.3,441304.8,440549.5,440749.2,440617.5,442047.8,
440198.9,440473.3,442260.1,440579.9,440397.6,440743.9,440331.6,440948.2,440540.3,442065.0,441037.1,441703.2,441516.6,
442025.2,441178.3,441739.8,441378.6,440403.6,440674.5,440875.9),
y = c(114430.1,113941.9,113886.1,114033.8,115375.1,115389.1,115618.7,115331.5,115612.2,115637.2,115019.2,114576.5,114602.0,
114799.0,113878.9,113444.9,113320.6,114492.2,113637.6,114494.9,113356.4,113484.9,113571.0,113351.1,114253.4,114217.8,
114434.1,114255.2,114045.8,113627.7,113610.2,113756.9,113823.5,113613.0,113331.8,114668.2,115453.0,114000.8,113418.1,
115310.1,115151.6,114696.5,114885.8,113312.3,114855.8,115195.4,114887.0,115239.8,115042.5,113972.7,114048.5,114350.9,
114089.9,114186.8,114295.4,113833.0,113690.2,114842.9,113465.0,113649.2,113591.4,114121.3,115240.1,115774.5,115858.3,
115622.9,115575.7,113506.3,113332.3,114743.6,115147.7,113716.7)
) %>% st_as_sf(coords = c("x", "y"), crs = 27700)

Origin <- data.frame(
ID = "START",
x = c(441889),
y = c(113756)
) %>% st_as_sf(coords = c("x", "y"), crs = 27700)

# OSM roads
Roads <- opq(bbox =  st_bbox(Points %>% st_transform(., crs=4326) )) %>% 
add_osm_feature(key = 'highway',
value = c ("motorway", "motorway_link","trunk","trunk_link","primary","primary_link","secondary","secondary_link","tertiary","tertiary_link","residential")) %>% 
osmdata_sf() %>%
osm_poly2line()

Roads_sf <- Roads$osm_lines %>% st_transform(., crs=27700) 

# Retain only roads that touching
Touching_roads <- st_touches(Roads_sf, sparse = FALSE)
Roads_hclust <- hclust(as.dist(!Touching_roads), method = "single")
Road_groups <- cutree(Roads_hclust, h = 0.5)
Roads_sf <- Roads_sf[Road_groups == 1, ]

# Snap points to roads
Nearest_point <- Points %>%
  mutate(
    index_of_nearest_feature = st_nearest_feature(., Roads_sf),
    nearest_feature = st_geometry(Roads_sf[index_of_nearest_feature,]),
    Nearest_point = purrr::pmap(
      list(geometry, nearest_feature),
      ~ st_nearest_points(.x, .y) %>% st_cast("POINT") %>% magrittr::extract2(2)
    )
  ) %>%
  pull(Nearest_point) %>%
  st_sfc(crs = 27700)

Points_Snapped <- Points %>% 
  st_drop_geometry() %>% 
  st_as_sf(., geometry = Nearest_point)

sln = SpatialLinesNetwork(Roads_sf)
#Warning message:
#In SpatialLinesNetwork.sf(Roads_sf) :
# Graph composed of multiple subgraphs, consider cleaning it with sln_clean_graph().
Chris
  • 1,197
  • 9
  • 28
  • Hi! Are you still interested in this problem? – agila Mar 07 '21 at 21:26
  • I am. However, I've had to spend the last few weeks working on something else. I did however make some progress when using data not from osmdata. I need to look at it further to understand what's causing the issue i.e. is it a particular package or the restricted (in terms of pulling data in) version of R that I have to use. – Chris Mar 07 '21 at 22:41
  • Are you interested in the routes or just the distances? – agila Mar 08 '21 at 10:07

0 Answers0