在 stplanr 中向 SpatialLinesNetwork 添加新节点
Add new node to SpatialLinesNetwork in stplanr
如何向 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
这并没有从一开始就回答您的问题,但我相信它通过显示如何计算您所需的网络距离确实解决了您的问题 "Context"。这可以通过 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
只是 returns "nodes"(在 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)
感谢您提出问题,感谢这个问题以及随后与 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 package (v0.3.0)
于 2019-09-26 创建
如果是 use/interest,请在此处查看支持此新功能的新小型函数系列的源代码:https://github.com/ropensci/stplanr/blob/master/R/node-funs.R
如何向 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
这并没有从一开始就回答您的问题,但我相信它通过显示如何计算您所需的网络距离确实解决了您的问题 "Context"。这可以通过 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
只是 returns "nodes"(在 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)
感谢您提出问题,感谢这个问题以及随后与 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 package (v0.3.0)
于 2019-09-26 创建如果是 use/interest,请在此处查看支持此新功能的新小型函数系列的源代码:https://github.com/ropensci/stplanr/blob/master/R/node-funs.R