Создание маршрута из списка точек и наложение маршрута (списка точек) на участок дороги/дорожную сеть в 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)

Другие вопросы по тегам