向 sfnetwork 添加空间显式边
Adding spatially explicit edges to sfnetwork
我在 R 中有一个带有空间隐式边缘的 sfnetwork。我想使用 tmap 绘制它,因此我想通过将它们变成线来使边缘在空间上明确。
我创造了这个怪物来做到这一点
edges <- activate(graph, "edges") %>% as_tibble() %>%
inner_join(activate(graph, "nodes") %>% as_tibble(), by=c("from"="node_id")) %>%
inner_join(activate(graph, "nodes") %>% as_tibble(), by=c("to"="node_id")) %>%
mutate(geometry = purrr::pmap(list(geometry.x, geometry.y), st_union)) %>%
st_as_sf() %>%
st_cast("MULTIPOINT") %>%
st_cast("LINESTRING")
可能需要 MULTIPOINT 转换,因为图表中存在自循环,我认为在 st_union 下它变成了 POINT,而不是 MULTIPOINT,令 LINESTRING 转换感到沮丧。
这看起来真的很尴尬,它创建了一个单独的对象,我无法将其粘回 sfnetwork。
我应该怎么做呢?
我认为以下代码可以创建一个具有空间显式边缘的 sfnetwork
对象,从具有空间隐式边缘的 sfnetwork
对象开始。
首先,加载包
library(sfnetworks)
library(tmap)
创建一些假数据。例子取自?sfnetwork
p1 = sf::st_point(c(7, 51))
p2 = sf::st_point(c(7, 52))
p3 = sf::st_point(c(8, 52))
nodes = sf::st_as_sf(sf::st_sfc(p1, p2, p3, crs = 4326))
e1 = sf::st_cast(sf::st_union(p1,p2), "LINESTRING")
e2 = sf::st_cast(sf::st_union(p1,p3), "LINESTRING")
e3 = sf::st_cast(sf::st_union(p2,p3), "LINESTRING")
edges = sf::st_as_sf(sf::st_sfc(e1, e2, e3, crs = 4326))
edges$from = c(1, 1, 2)
edges$to = c(2, 3, 3)
创建具有空间隐式边的网络
(my_sfnetwork <- sfnetwork(nodes, edges, directed = FALSE, edges_as_lines = FALSE))
#> # An sfnetwork with 3 nodes and 3 edges
#> #
#> # CRS: EPSG:4326
#> #
#> # An undirected simple graph with 1 component with spatially implicit edges
#> #
#> # Node Data: 3 x 1 (active)
#> # Geometry type: POINT
#> # Dimension: XY
#> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52
#> x
#> <POINT [°]>
#> 1 (7 51)
#> 2 (7 52)
#> 3 (8 52)
#> #
#> # Edge Data: 3 x 2
#> from to
#> <int> <int>
#> 1 1 2
#> 2 1 3
#> 3 2 3
使边缘在空间上明确
(my_sfnetwork <- tidygraph::convert(
my_sfnetwork,
to_spatial_explicit_edges,
.clean = TRUE
))
#> # An sfnetwork with 3 nodes and 3 edges
#> #
#> # CRS: EPSG:4326
#> #
#> # An undirected simple graph with 1 component with spatially explicit edges
#> #
#> # Node Data: 3 x 1 (active)
#> # Geometry type: POINT
#> # Dimension: XY
#> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52
#> x
#> <POINT [°]>
#> 1 (7 51)
#> 2 (7 52)
#> 3 (8 52)
#> #
#> # Edge Data: 3 x 3
#> # Geometry type: LINESTRING
#> # Dimension: XY
#> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52
#> from to x
#> <int> <int> <LINESTRING [°]>
#> 1 1 2 (7 51, 7 52)
#> 2 1 3 (7 51, 8 52)
#> 3 2 3 (7 52, 8 52)
由 reprex package (v0.3.0)
于 2020-10-27 创建
查看 here、?tidygraph::convert
和 ?to_spatial_explicit_edges
了解更多详情。
我在 R 中有一个带有空间隐式边缘的 sfnetwork。我想使用 tmap 绘制它,因此我想通过将它们变成线来使边缘在空间上明确。
我创造了这个怪物来做到这一点
edges <- activate(graph, "edges") %>% as_tibble() %>%
inner_join(activate(graph, "nodes") %>% as_tibble(), by=c("from"="node_id")) %>%
inner_join(activate(graph, "nodes") %>% as_tibble(), by=c("to"="node_id")) %>%
mutate(geometry = purrr::pmap(list(geometry.x, geometry.y), st_union)) %>%
st_as_sf() %>%
st_cast("MULTIPOINT") %>%
st_cast("LINESTRING")
可能需要 MULTIPOINT 转换,因为图表中存在自循环,我认为在 st_union 下它变成了 POINT,而不是 MULTIPOINT,令 LINESTRING 转换感到沮丧。
这看起来真的很尴尬,它创建了一个单独的对象,我无法将其粘回 sfnetwork。
我应该怎么做呢?
我认为以下代码可以创建一个具有空间显式边缘的 sfnetwork
对象,从具有空间隐式边缘的 sfnetwork
对象开始。
首先,加载包
library(sfnetworks)
library(tmap)
创建一些假数据。例子取自?sfnetwork
p1 = sf::st_point(c(7, 51))
p2 = sf::st_point(c(7, 52))
p3 = sf::st_point(c(8, 52))
nodes = sf::st_as_sf(sf::st_sfc(p1, p2, p3, crs = 4326))
e1 = sf::st_cast(sf::st_union(p1,p2), "LINESTRING")
e2 = sf::st_cast(sf::st_union(p1,p3), "LINESTRING")
e3 = sf::st_cast(sf::st_union(p2,p3), "LINESTRING")
edges = sf::st_as_sf(sf::st_sfc(e1, e2, e3, crs = 4326))
edges$from = c(1, 1, 2)
edges$to = c(2, 3, 3)
创建具有空间隐式边的网络
(my_sfnetwork <- sfnetwork(nodes, edges, directed = FALSE, edges_as_lines = FALSE))
#> # An sfnetwork with 3 nodes and 3 edges
#> #
#> # CRS: EPSG:4326
#> #
#> # An undirected simple graph with 1 component with spatially implicit edges
#> #
#> # Node Data: 3 x 1 (active)
#> # Geometry type: POINT
#> # Dimension: XY
#> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52
#> x
#> <POINT [°]>
#> 1 (7 51)
#> 2 (7 52)
#> 3 (8 52)
#> #
#> # Edge Data: 3 x 2
#> from to
#> <int> <int>
#> 1 1 2
#> 2 1 3
#> 3 2 3
使边缘在空间上明确
(my_sfnetwork <- tidygraph::convert(
my_sfnetwork,
to_spatial_explicit_edges,
.clean = TRUE
))
#> # An sfnetwork with 3 nodes and 3 edges
#> #
#> # CRS: EPSG:4326
#> #
#> # An undirected simple graph with 1 component with spatially explicit edges
#> #
#> # Node Data: 3 x 1 (active)
#> # Geometry type: POINT
#> # Dimension: XY
#> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52
#> x
#> <POINT [°]>
#> 1 (7 51)
#> 2 (7 52)
#> 3 (8 52)
#> #
#> # Edge Data: 3 x 3
#> # Geometry type: LINESTRING
#> # Dimension: XY
#> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52
#> from to x
#> <int> <int> <LINESTRING [°]>
#> 1 1 2 (7 51, 7 52)
#> 2 1 3 (7 51, 8 52)
#> 3 2 3 (7 52, 8 52)
由 reprex package (v0.3.0)
于 2020-10-27 创建查看 here、?tidygraph::convert
和 ?to_spatial_explicit_edges
了解更多详情。