我想计算一个起点和多个点之间以及所有点之间的道路网络上的最短路线。
我osmdata
用来获取我所在地区的道路网络,然后我想stplanr
用来计算距离。但是,我无法创建包含所有道路的 SpatialLinesNetwork - 我假设是因为它们没有连接?有没有办法将不同的道路类型连接成一层?如果这是可能的,是否可以route_local
用于stplanr
计算一个点(在我的示例中为原点)到多个点(在我的示例中为点)以及所有点之间(在我的示例中为点)之间的最短距离?
这是我到目前为止的代码:
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().