Заполнение пробелов в данных о дорожной сети
У меня есть сеть автомагистралей с точками подсчета, которые можно сопоставить с дорогами. Однако они соответствуют примерно половине ссылок 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)