在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,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,"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以获得更多详细信息。