Создание маршрута из списка точек и наложение маршрута (списка точек) на участок дороги/дорожную сеть в 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
)
В качестве вывода я хочу получить слой маршрута, соединяющий все точки в указанном порядке. И я также хочу интегрировать / сделать пространственное соединение маршрута с сегментами дороги.
заранее спасибо
1 ответ
Следующий ответ основан на
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)
Разделите ребра и выберите главный компонент. Проверьте 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
не поддерживает маршрутизацию «многие ко многим», поэтому нам нужно определить цикл for. Если вам нужно повторить эту операцию для нескольких точек, я думаю, вам следует проверить пакет Rdodgr
.
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
}
Извлечь идентификатор ребер, составляющих все кратчайшие пути
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)
Создано 07 марта 2021 г. пакетом reprex (v0.3.0)