Заполнение пробелов в данных о дорожной сети

У меня есть сеть автомагистралей с точками подсчета, которые можно сопоставить с дорогами. Однако они соответствуют примерно половине ссылок osm. Сеть является однонаправленной, и должна быть возможность назначать данные от присоединяющихся звеньев к отсутствующим звеньям.

В настоящее время у меня есть довольно уродливое и длинное решение, основанное на цикле WHILE, который последовательно заполняет соединительные ссылки. Тем не менее, я думаю, что возможно более элегантное решение с использованием сети sfnetwork или пространственных линий. Пакеты stplanr, sfnetwork и dodger очень похожи на то, что я хочу сделать, но все они, похоже, сосредоточены на маршрутизации и данных о происхождении и назначении.

Ниже приведен воспроизводимый пример, в котором используется небольшой участок сети автомагистралей Великобритании, удаляется случайная выборка из половины звеньев и генерируются данные о потоках и скорости для оставшейся половины.

Как заполнить недостающие ссылки данными с обоих концов недостающих ссылок?

      library(tidyverse)
library(lubridate)
library(mapview)
library(sf)
library(osmdata)

## define area to import osm data
x_max <- -2.31
x_min <- -2.38
y_max <- 51.48
y_min <- 51.51

##create a data frame to setup a polygon generation
df <- data.frame(X = c(x_min, x_max, x_max, x_min),
                 Y = c(y_max, y_max, y_min, y_min))

##generate a polygon of the area
rd_area <- df %>%
  st_as_sf(coords = c("X", "Y"), crs = 4326) %>%
  dplyr::summarise(geometry = st_combine(geometry)) %>%
  st_cast("POLYGON")

##get osm geometry for motorway links for defined area
x <- opq(bbox = rd_area) %>% 
  add_osm_feature(key = c('highway'), value = c('motorway', 
                                                'motorway_link')) %>% osmdata_sf()

## extract line geometry, generate a unique segment ID and get rid of excess columns
rdz <- x$osm_lines %>% 
  mutate(seg_id = paste0("L", sprintf("%02d", 1:NROW(bicycle)))) %>% 
  select(seg_id)

## pretend we only have traffic counts and speeds for half the links
osm_dat <-  rdz[sample(nrow(rdz), nrow(rdz)/2), ]

## links without data
osm_nodat <- filter(rdz, !seg_id %in% osm_dat$seg_id)

## visualise links with data and without
mapview(osm_dat, color = "green")+mapview(osm_nodat, color = "red")

## make up some data to work with
osm_dat$flow <- sample(200:600, nrow(osm_dat))
osm_dat$speed <- sample(40:80, nrow(osm_dat))

1 ответ

Вот одно быстрое и элегантное решение из проекта Cyipt https://github.com/cyipt/cyipt/blob/master/scripts/prep_data/get_traffic.R .

Он использует код из функции get.aadt.class и использует полигоны Ворони для задания потоков и скоростей ближайших дорог. Однако он не распределяет, т.е. не разделяет потоки, где одно звено встречается с двумя, что иногда приводит к тому, что противоположные направления имеют одинаковые потоки и скорости.

      library(dismo) ## dismo package for voroni polygon generation

  #Make voronoi polygons and convert to SF
  voronoi <- dismo::voronoi(x = st_coordinates(pretend_counts))
  voronoi <- as(voronoi, "sf")
  st_crs(voronoi) <- st_crs(pretend_counts)

  #Find Intersections of roads with vernoi polygons
  inter <- st_intersects(osm_nodat,voronoi)
  #Get aadt and ncycle values
  osm_nodat$aadt <- as.numeric(lapply(1:nrow(osm_nodat),function(x){as.numeric(round(mean(pretend_counts$aadt[inter[[x]]])),0)}))
  osm_nodat$speed <- as.numeric(lapply(1:nrow(osm_nodat),function(x){as.numeric(round(mean(pretend_counts$speed[inter[[x]]])),0)}))

  #Remove Unneded Data
  all_osm <- as.data.frame(rbind(osm_dat, osm_nodat))
  st_geometry(all_osm) <- all_osm$geometry
  flows <- dplyr::select(all_osm, aadt)
  mapview(flows)

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