2

如何将新节点添加到 a SpatialLinesNetwork

我的问题的背景:我有一个公交车路线的 shapefile 和另一个公交车站的 shapefile。我想计算巴士路线沿线站点之间的距离。理想情况下,每个站点都是一个节点,我会用它stplanr::sum_network_routes()来计算它们之间的距离。问题是,当我将公交路线转换为SpatialLinesNetwork网络时,网络中只有几个节点彼此相距很远,并且与公交车站的位置无关。

可重现的数据集:

# load library and data
  library(stplanr)
  library(sf)

# get road data
  data(routes_fast)
  rnet <- overline(routes_fast, attrib = "length")

# convert to sf obj
  rnet <- st_as_sf(rnet)

# convert SpatialLinesDataFrame into  SpatialLinesNetwork
  sln <- SpatialLinesNetwork(rnet)

# identify nodes
 sln_nodes = sln2points(sln)

# Here is a bus stop which should be added as a node
 new_point_coordinates = c(-1.535, 53.809)
 p = sf::st_sf(geometry = sf::st_sfc(sf::st_point(new_point_coordinates)), crs = st_crs(rnet))


# plot
plot(sln, col = "gray")                 # network
plot(sln_nodes, col="red", add = TRUE)  # nodes
plot(p, add=T, col="blue")      # stop to be added as a new node

在此处输入图像描述

4

2 回答 2

3

这并不能在一开始就回答您的问题,但我相信它确实通过显示如何计算您所需的网络距离来解决您的“上下文”。这可以使用dodgr(最新dev版本)来完成,如下所示:

library (dodgr)
library (stplanr)
library (sf)
library (sp)
dat <- st_as_sf (routes_fast)
net <- weight_streetnet (dat, wt_profile = 1)

net对象是一个简单data.frame的包含网络的所有边和顶点的对象。然后调整上面的代码以将路由点作为简单矩阵

rnet rnet <- overline(routes_fast, attrib = "length")
SLN <- SpatialLinesNetwork(rnet)
sln_nodes = sln2points(SLN)
xy <- coordinates (sln_nodes)
colnames (xy) <- c ("x", "y")

sln2points仅返回“节点”(术语stplanr)的节点,它们是连接点。您可以替换为公交车站的坐标,或者简单地将它们添加到此矩阵中。以下三行将这些坐标转换为dodgr net对象的唯一(最近)顶点 ID:

v <- dodgr_vertices (net)
pts <- match_pts_to_graph (v, xy)
pts <- v$id [pts]

要计算网络上的距离pts,只需

d <- dodgr_dists (net, from = pts, to = pts)
于 2018-01-17T16:22:43.030 回答
1

感谢这个问题,感谢这个问题以及随后与 Andrea Gilardi 的合作,我很高兴地宣布现在可以使用新功能向 sfNetwork 对象添加新节点,sln_add_node().

请参见下文,请尝试测试可重现的代码以演示其工作原理:

devtools::install_github("ropensci/stplanr")
#> Skipping install of 'stplanr' from a github remote, the SHA1 (33158a5b) has not changed since last install.
#>   Use `force = TRUE` to force installation
library(stplanr)
#> Registered S3 method overwritten by 'R.oo':
#>   method        from       
#>   throw.default R.methodsS3
#> Warning in fun(libname, pkgname): rgeos: versions of GEOS runtime 3.7.1-CAPI-1.11.1
#> and GEOS at installation 3.7.0-CAPI-1.11.0differ

sample_routes <- routes_fast_sf[2:6, NULL]
sample_routes$value <- rep(1:3, length.out = 5)
rnet <- overline2(sample_routes, attrib = "value")
#> 2019-09-26 16:06:18 constructing segments
#> 2019-09-26 16:06:18 building geometry
#> 2019-09-26 16:06:18 simplifying geometry
#> 2019-09-26 16:06:18 aggregating flows
#> 2019-09-26 16:06:18 rejoining segments into linestrings
plot(sample_routes["value"], lwd = sample_routes$value, main = "Routes")

plot(rnet["value"], lwd = rnet$value, main = "Route network")

sln <- SpatialLinesNetwork(rnet)
#> Linking to GEOS 3.7.1, GDAL 2.4.0, PROJ 5.2.0

new_point_coordinates <- c(-1.540, 53.826)
crs <- sf::st_crs(rnet)
p <- sf::st_sf(geometry = sf::st_sfc(sf::st_point(new_point_coordinates)), crs = crs)
p_dest <- sln2points(sln)[9, ]

# We can identify the nearest point on the network at this point
# and use that to split the associated linestring:

sln_new <- sln_add_node(sln = sln, p = p)
#> although coordinates are longitude/latitude, st_nearest_feature assumes that they are planar
route_new <- route_local(sln = sln_new, from = p, to = p_dest)
plot(sln_new)
plot(p, add = TRUE)
plot(route_new, lwd = 5, add = TRUE)
#> Warning in plot.sf(route_new, lwd = 5, add = TRUE): ignoring all but the
#> first attribute

reprex 包(v0.3.0)于 2019 年 9 月 26 日创建

如果它有用/感兴趣,请在此处查看支持此新功能的新小函数系列的源代码:https ://github.com/ropensci/stplanr/blob/master/R/node-funs.R

于 2019-09-26T15:12:24.173 回答