1

我有一个高速公路网络,其计数点可以与道路连接相匹配。然而,它们只匹配大约一半的 osm 链接。网络是单向的,应该可以将来自加入链接的数据分配给丢失的链接。

我目前有一个基于 WHILE 循环的相当丑陋且冗长的解决方案,该循环依次填充连接链接。但是,我认为使用 sfnetwork 或空间线网络可能会获得更优雅的解决方案。stplanr、sfnetwork 和 dodger 包与我想要做的非常匹配,但似乎都专注于路由和原始目的地数据。

下面是一个可重现的示例,它使用英国高速公路网络的一小块区域,并删除一半链接的随机样本,并为剩余的一半生成流量和速度数据。

如何用缺失链接两端的数据填充缺失的链接?

library(tidyverse)
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[c(3,4,5,7,11,14,15),]

## 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
pretend_counts <- st_centroid(osm_dat)

## assign some random annual average daily flow and speed averages
pretend_counts$aadt <- sample(200:600, nrow(pretend_counts))
pretend_counts$speed <- sample(40:80, nrow(pretend_counts))

4

1 回答 1

0

这是 Cyipt 项目https://github.com/cyipt/cyipt/blob/master/scripts/prep_data/get_traffic.R的一个快速而优雅的解决方案

它使用 get.aadt.class 函数中的代码并使用 Voroni 多边形为最近的道路提供流量和速度。但是,它不会分配,即在一个链接与两个链接相遇的地方拆分流量,并且有时会导致相反的方向具有相同的流量和速度。

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)

于 2022-01-22T21:51:46.147 回答