R 中的 sf 和网络:从不同的线串和点 sf 对象创建边缘列表
sf and networks in R : create an edgelist from distinct linestrings and points sf objects
我有一个 sf 节点对象(站点)和另一个线串对象(路线)。
# toy example
## nodes
p1 = st_point(c(7, 51))
p2 = st_point(c(7, 52))
p3 = st_point(c(7, 53))
p4 = st_point(c(8, 52))
nodes = st_as_sf(st_sfc(p1, p2, p3,p4, crs = 4326))
## routes
e1 = st_cast(st_union(p1,p3), "LINESTRING")
e2 = st_cast(st_union(p1,p4), "LINESTRING")
e3 = st_cast(st_union(p3,p4), "LINESTRING")
lines = st_as_sf(st_sfc(e1, e2, e3, crs = 4326))
如何获取直接连接两个节点的路段边列表?
#Desired output
from | to
p1 | p2
p2 | p3
p1 | p4
p3 | p4
这里p1和p3之间有一条线但是p2在中间所以p1-p2和p2-p3之间有两条边
我知道 sfnetwork 包可以用线串或点构造网络,但是如何用线和点的交点创建空间网络?
不确定你在找什么,但我再试一次作为你评论的后续行动!!因此,请在下方找到使用 sf
、sfnetworks
和 dplyr
库进行完全编辑的 reprex。
Reprex
- 第 1 步:使用您的 points/nodes p1、p3 和 p4
创建网络
library(sf)
library(sfnetworks)
library(dplyr)
# toy example
p1 = st_point(c(7, 51))
p3 = st_point(c(7, 53))
p4 = st_point(c(8, 52))
nodes = st_as_sf(st_sfc(p1, p3, p4, crs = 4326))
nodes$names <- c("p1", "p3", "p4") # add the name of nodes
## routes
e1 = st_cast(st_union(p1,p3), "LINESTRING")
e2 = st_cast(st_union(p1,p4), "LINESTRING")
e3 = st_cast(st_union(p3,p4), "LINESTRING")
lines = st_as_sf(st_sfc(e1, e2, e3, crs = 4326))
lines$from <- c("p1", "p1", "p3")
lines$to <- c("p3", "p4", "p4")
# Create the network
network <- sfnetwork(nodes, lines, node_key = "names")
#> Checking if spatial network structure is valid...
#> Spatial network structure is valid
# What the network looks like:
network
#> # A sfnetwork with 3 nodes and 3 edges
#> #
#> # CRS: EPSG:4326
#> #
#> # A directed acyclic simple graph with 1 component with spatially explicit edges
#> #
#> # Node Data: 3 x 2 (active)
#> # Geometry type: POINT
#> # Dimension: XY
#> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 53
#> x names
#> <POINT [°]> <chr>
#> 1 (7 51) p1
#> 2 (7 53) p3
#> 3 (8 52) p4
#> #
#> # Edge Data: 3 x 3
#> # Geometry type: LINESTRING
#> # Dimension: XY
#> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 53
#> from to x
#> <int> <int> <LINESTRING [°]>
#> 1 1 2 (7 51, 7 53)
#> 2 1 3 (7 51, 8 52)
#> 3 2 3 (7 53, 8 52)
- 第 2 步:向 'network' 对象添加一个补充节点(即 p2)
# Create a 'sf' object for point 2 'p2'
p2 = st_point(c(7, 52))
p2_sf <- st_as_sf(st_sfc(p2, crs = 4326))
p2_sf$names <- "p2"
# Add 'p2' to the network and get the 'new_network' object
new_network <- st_network_blend(network, p2_sf)
# Cleaning the 'new_network' object
new_network %>%
activate("nodes") %>%
mutate(names = coalesce(names.x, names.y)) %>%
arrange(., names) %>%
select(names,x) -> new_network
- 第 3 步:创建具有所需结果的
sf
对象
new_network %>%
activate("edges") %>%
st_as_sf() %>%
mutate(from = paste0("p", from), to = paste0("p", to))
#> Simple feature collection with 4 features and 2 fields
#> Geometry type: LINESTRING
#> Dimension: XY
#> Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 53
#> Geodetic CRS: WGS 84
#> # A tibble: 4 x 3
#> from to x
#> * <chr> <chr> <LINESTRING [°]>
#> 1 p1 p2 (7 51, 7 52)
#> 2 p2 p3 (7 52, 7 53)
#> 3 p1 p4 (7 51, 8 52)
#> 4 p3 p4 (7 53, 8 52)
由 reprex package (v2.0.1)
于 2021-12-05 创建
我有一个 sf 节点对象(站点)和另一个线串对象(路线)。
# toy example
## nodes
p1 = st_point(c(7, 51))
p2 = st_point(c(7, 52))
p3 = st_point(c(7, 53))
p4 = st_point(c(8, 52))
nodes = st_as_sf(st_sfc(p1, p2, p3,p4, crs = 4326))
## routes
e1 = st_cast(st_union(p1,p3), "LINESTRING")
e2 = st_cast(st_union(p1,p4), "LINESTRING")
e3 = st_cast(st_union(p3,p4), "LINESTRING")
lines = st_as_sf(st_sfc(e1, e2, e3, crs = 4326))
如何获取直接连接两个节点的路段边列表?
#Desired output
from | to
p1 | p2
p2 | p3
p1 | p4
p3 | p4
这里p1和p3之间有一条线但是p2在中间所以p1-p2和p2-p3之间有两条边
我知道 sfnetwork 包可以用线串或点构造网络,但是如何用线和点的交点创建空间网络?
不确定你在找什么,但我再试一次作为你评论的后续行动!!因此,请在下方找到使用 sf
、sfnetworks
和 dplyr
库进行完全编辑的 reprex。
Reprex
- 第 1 步:使用您的 points/nodes p1、p3 和 p4 创建网络
library(sf)
library(sfnetworks)
library(dplyr)
# toy example
p1 = st_point(c(7, 51))
p3 = st_point(c(7, 53))
p4 = st_point(c(8, 52))
nodes = st_as_sf(st_sfc(p1, p3, p4, crs = 4326))
nodes$names <- c("p1", "p3", "p4") # add the name of nodes
## routes
e1 = st_cast(st_union(p1,p3), "LINESTRING")
e2 = st_cast(st_union(p1,p4), "LINESTRING")
e3 = st_cast(st_union(p3,p4), "LINESTRING")
lines = st_as_sf(st_sfc(e1, e2, e3, crs = 4326))
lines$from <- c("p1", "p1", "p3")
lines$to <- c("p3", "p4", "p4")
# Create the network
network <- sfnetwork(nodes, lines, node_key = "names")
#> Checking if spatial network structure is valid...
#> Spatial network structure is valid
# What the network looks like:
network
#> # A sfnetwork with 3 nodes and 3 edges
#> #
#> # CRS: EPSG:4326
#> #
#> # A directed acyclic simple graph with 1 component with spatially explicit edges
#> #
#> # Node Data: 3 x 2 (active)
#> # Geometry type: POINT
#> # Dimension: XY
#> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 53
#> x names
#> <POINT [°]> <chr>
#> 1 (7 51) p1
#> 2 (7 53) p3
#> 3 (8 52) p4
#> #
#> # Edge Data: 3 x 3
#> # Geometry type: LINESTRING
#> # Dimension: XY
#> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 53
#> from to x
#> <int> <int> <LINESTRING [°]>
#> 1 1 2 (7 51, 7 53)
#> 2 1 3 (7 51, 8 52)
#> 3 2 3 (7 53, 8 52)
- 第 2 步:向 'network' 对象添加一个补充节点(即 p2)
# Create a 'sf' object for point 2 'p2'
p2 = st_point(c(7, 52))
p2_sf <- st_as_sf(st_sfc(p2, crs = 4326))
p2_sf$names <- "p2"
# Add 'p2' to the network and get the 'new_network' object
new_network <- st_network_blend(network, p2_sf)
# Cleaning the 'new_network' object
new_network %>%
activate("nodes") %>%
mutate(names = coalesce(names.x, names.y)) %>%
arrange(., names) %>%
select(names,x) -> new_network
- 第 3 步:创建具有所需结果的
sf
对象
new_network %>%
activate("edges") %>%
st_as_sf() %>%
mutate(from = paste0("p", from), to = paste0("p", to))
#> Simple feature collection with 4 features and 2 fields
#> Geometry type: LINESTRING
#> Dimension: XY
#> Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 53
#> Geodetic CRS: WGS 84
#> # A tibble: 4 x 3
#> from to x
#> * <chr> <chr> <LINESTRING [°]>
#> 1 p1 p2 (7 51, 7 52)
#> 2 p2 p3 (7 52, 7 53)
#> 3 p1 p4 (7 51, 8 52)
#> 4 p3 p4 (7 53, 8 52)
由 reprex package (v2.0.1)
于 2021-12-05 创建