从点列表创建路线并在 R 中的路段/道路网络上覆盖路线(点列表)
Creating a route from a list of points and Overlaying the route (list of points) on the road segment/ road network in R
我有一个道路网络形状文件和点列表。我必须从点列表创建一条路线,然后覆盖/空间连接(整合覆盖路段的点的属性)
示例道路网络形状文件可在此处找到https://drive.google.com/drive/folders/103Orz6NuiWOaFoEkM18SlzFTjGYi1rju?usp=sharing
以下是带有纬度(x)和经度(y)信息的点的代码。 “顺序”列表示路线中目的地的顺序。
points <-tribble (
~x,~y, ~order,
78.14358, 9.921388,1,
78.14519, 9.921123,2,
78.14889, 9.916954,3,
78.14932, 9.912807,4,
78.14346, 9.913828,5,
78.13490, 9.916551,6,
78.12904, 9.918782,7
)
我想要的输出是按照上述顺序连接所有点的路线层。而且我还想整合/做一个到路段的路线的空间连接。
提前致谢
以下答案基于 R
包 sfnetworks
,可以按如下方式安装:
install.packages("remotes")
remotes::install_github("luukvdmeer/sfnetworks")
首先加载包
library(sf)
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
library(sfnetworks)
library(tidygraph)
和数据。点对象转换为 sf
格式。
roads <- st_read("C:/Users/Utente/Desktop/Temp/roads_test.shp") %>% st_cast("LINESTRING")
#> Reading layer `roads_test' from data source `C:\Users\Utente\Desktop\Temp\roads_test.shp' using driver `ESRI Shapefile'
#> Simple feature collection with 785 features and 0 fields
#> geometry type: MULTILINESTRING
#> dimension: XY
#> bbox: xmin: 78.12703 ymin: 9.911192 xmax: 78.15389 ymax: 9.943905
#> geographic CRS: WGS 84
points <- tibble::tribble (
~x,~y, ~order,
78.14358, 9.921388,1,
78.14519, 9.921123,2,
78.14889, 9.916954,3,
78.14932, 9.912807,4,
78.14346, 9.913828,5,
78.13490, 9.916551,6,
78.12904, 9.918782,7
)
points <- st_as_sf(points, coords = c("x", "y"), crs = 4326)
绘制网络和点(只是为了更好地理解问题)
par(mar = rep(0, 4))
plot(roads, reset = FALSE)
plot(points, add = TRUE, cex = (1:7)/1.5, col = sf.colors(7), lwd = 4)
将道路转换为 sfnetwork 对象
network <- as_sfnetwork(roads, directed = FALSE)
细分边缘和select主要成分。查看 https://luukvdmeer.github.io/sfnetworks/articles/preprocess_and_clean.html 了解更多详情。
network <- network %>%
convert(to_spatial_subdivision, .clean = TRUE) %>%
convert(to_components, .select = 1, .clean = TRUE) %E>%
mutate(weight = edge_length())
现在我想估计每对连续点之间的最短路径。 sfnetwork
不支持many-to-many路由,所以我们需要定义一个for-loop。如果你需要重复这个操作几个点,我觉得你应该检查R包dodgr
.
routes <- list()
for (i in 1:6) {
path <- st_network_paths(
network,
from = st_geometry(points)[i],
to = st_geometry(points)[i + 1]
)
routes[[i]] <- path
}
提取组成所有最短路径的边的id
idx <- unlist(pull(do.call("rbind", routes), edge_paths))
因此,如果要从原始网络中提取边缘
network_shortest_path <- network %E>% slice(idx)
roads_shortest_path <- network_shortest_path %E>% st_as_sf()
绘制网络和点
par(mar = rep(0, 4))
plot(roads, reset = FALSE)
plot(st_geometry(roads_shortest_path), add = TRUE, col = "darkgreen", lwd = 4)
plot(points, add = TRUE, cex = (1:7)/1.5, col = sf.colors(7), lwd = 4)
由 reprex package (v0.3.0)
于 2021-03-07 创建
我有一个道路网络形状文件和点列表。我必须从点列表创建一条路线,然后覆盖/空间连接(整合覆盖路段的点的属性)
示例道路网络形状文件可在此处找到https://drive.google.com/drive/folders/103Orz6NuiWOaFoEkM18SlzFTjGYi1rju?usp=sharing
以下是带有纬度(x)和经度(y)信息的点的代码。 “顺序”列表示路线中目的地的顺序。
points <-tribble (
~x,~y, ~order,
78.14358, 9.921388,1,
78.14519, 9.921123,2,
78.14889, 9.916954,3,
78.14932, 9.912807,4,
78.14346, 9.913828,5,
78.13490, 9.916551,6,
78.12904, 9.918782,7
)
我想要的输出是按照上述顺序连接所有点的路线层。而且我还想整合/做一个到路段的路线的空间连接。
提前致谢
以下答案基于 R
包 sfnetworks
,可以按如下方式安装:
install.packages("remotes")
remotes::install_github("luukvdmeer/sfnetworks")
首先加载包
library(sf)
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
library(sfnetworks)
library(tidygraph)
和数据。点对象转换为 sf
格式。
roads <- st_read("C:/Users/Utente/Desktop/Temp/roads_test.shp") %>% st_cast("LINESTRING")
#> Reading layer `roads_test' from data source `C:\Users\Utente\Desktop\Temp\roads_test.shp' using driver `ESRI Shapefile'
#> Simple feature collection with 785 features and 0 fields
#> geometry type: MULTILINESTRING
#> dimension: XY
#> bbox: xmin: 78.12703 ymin: 9.911192 xmax: 78.15389 ymax: 9.943905
#> geographic CRS: WGS 84
points <- tibble::tribble (
~x,~y, ~order,
78.14358, 9.921388,1,
78.14519, 9.921123,2,
78.14889, 9.916954,3,
78.14932, 9.912807,4,
78.14346, 9.913828,5,
78.13490, 9.916551,6,
78.12904, 9.918782,7
)
points <- st_as_sf(points, coords = c("x", "y"), crs = 4326)
绘制网络和点(只是为了更好地理解问题)
par(mar = rep(0, 4))
plot(roads, reset = FALSE)
plot(points, add = TRUE, cex = (1:7)/1.5, col = sf.colors(7), lwd = 4)
将道路转换为 sfnetwork 对象
network <- as_sfnetwork(roads, directed = FALSE)
细分边缘和select主要成分。查看 https://luukvdmeer.github.io/sfnetworks/articles/preprocess_and_clean.html 了解更多详情。
network <- network %>%
convert(to_spatial_subdivision, .clean = TRUE) %>%
convert(to_components, .select = 1, .clean = TRUE) %E>%
mutate(weight = edge_length())
现在我想估计每对连续点之间的最短路径。 sfnetwork
不支持many-to-many路由,所以我们需要定义一个for-loop。如果你需要重复这个操作几个点,我觉得你应该检查R包dodgr
.
routes <- list()
for (i in 1:6) {
path <- st_network_paths(
network,
from = st_geometry(points)[i],
to = st_geometry(points)[i + 1]
)
routes[[i]] <- path
}
提取组成所有最短路径的边的id
idx <- unlist(pull(do.call("rbind", routes), edge_paths))
因此,如果要从原始网络中提取边缘
network_shortest_path <- network %E>% slice(idx)
roads_shortest_path <- network_shortest_path %E>% st_as_sf()
绘制网络和点
par(mar = rep(0, 4))
plot(roads, reset = FALSE)
plot(st_geometry(roads_shortest_path), add = TRUE, col = "darkgreen", lwd = 4)
plot(points, add = TRUE, cex = (1:7)/1.5, col = sf.colors(7), lwd = 4)
由 reprex package (v0.3.0)
于 2021-03-07 创建