diff --git a/articles/sfn01_intro.html b/articles/sfn01_intro.html index 724591a..89fe283 100644 --- a/articles/sfn01_intro.html +++ b/articles/sfn01_intro.html @@ -216,24 +216,24 @@ select(name, label) |> activate(edges) |> filter(sample(c(TRUE, FALSE), n(), replace = TRUE)) -
#> # A sfnetwork: 17 nodes and 13 edges
+
#> # A sfnetwork: 17 nodes and 9 edges
 #> #
-#> # An unrooted forest with 4 trees and spatially explicit edges
+#> # An unrooted forest with 8 trees and spatially explicit edges
 #> #
 #> # Dimension: XY
 #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537
 #> # Projected CRS: ETRS89-extended / LAEA Europe
 #> #
-#> # Edge data: 13 × 3 (active)
+#> # Edge data: 9 × 3 (active)
 #>    from    to                           geometry
 #>   <int> <int>                   <LINESTRING [m]>
-#> 1     1     4 (4549504 2747309, 4549387 2747514)
-#> 2     3     5 (4549589 2747507, 4549491 2747551)
+#> 1     1     3 (4549504 2747309, 4549589 2747507)
+#> 2     2     7 (4549003 2747376, 4549064 2747619)
 #> 3     4     5 (4549387 2747514, 4549491 2747551)
-#> 4     4     9 (4549387 2747514, 4549120 2747654)
-#> 5     6    10 (4549473 2747624, 4549418 2747723)
-#> 6     7     9 (4549064 2747619, 4549120 2747654)
-#> # ℹ 7 more rows
+#> 4     8    12 (4548994 2747632, 4548664 2747868)
+#> 5     9    10 (4549120 2747654, 4549418 2747723)
+#> 6    10    11 (4549418 2747723, 4549119 2747790)
+#> # ℹ 3 more rows
 #> #
 #> # Node data: 17 × 3
 #>   name                  label          geometry
@@ -901,41 +901,41 @@
 new_net = delete_edges(net, drop)
 
 new_net
-#> IGRAPH f481e4e UN-B 17 12 -- 
+#> IGRAPH 66e2aa1 UN-B 17 14 -- 
 #> + attr: name (v/c), type (v/c), website (v/c), geometry (v/x), label
 #> | (v/c), geometry (e/x), length (e/n)
-#> + edges from f481e4e (vertex names):
-#>  [1] Mozartkino             --Mozartsteg/Rudolfskai  
-#>  [2] Haus für Mozart        --Café Mozart            
-#>  [3] Mozart Denkmal         --Mozartsteg/Rudolfskai  
-#>  [4] Mozarts Geburtshaus    --Café Mozart            
-#>  [5] Mozartkugel            --Mozartsteg/Imbergstraße
-#>  [6] Mozartkugel            --Spirit of Mozart       
-#>  [7] Mozartsteg/Imbergstraße--Spirit of Mozart       
+#> + edges from 66e2aa1 (vertex names):
+#>  [1] Mozartkino             --Mozartsteg/Rudolfskai
+#>  [2] Haus für Mozart        --Mozart Denkmal       
+#>  [3] Haus für Mozart        --Mozarts Geburtshaus  
+#>  [4] Mozartsteg/Rudolfskai  --Mozartsteg/Rudolfskai
+#>  [5] Mozart Denkmal         --Mozartsteg/Rudolfskai
+#>  [6] Mozart Denkmal         --Mozartkugel          
+#>  [7] Mozarts Geburtshaus    --Café Mozart          
 #> + ... omitted several edges

As you can see, this returns a igraph object instead of a sfnetwork object. To preserve the class, you can use the wrap_igraph() function of sfnetworks for each igraph function that accepts a network as first input and returns another network. This function will check if the returned network is still spatial.

 wrap_igraph(net, delete_edges, drop)
-
#> # A sfnetwork: 17 nodes and 12 edges
+
#> # A sfnetwork: 17 nodes and 14 edges
 #> #
-#> # A bipartite simple graph with 6 components and spatially explicit edges
+#> # An unrooted forest with 3 trees and spatially explicit edges
 #> #
 #> # Dimension: XY
 #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537
 #> # Projected CRS: ETRS89-extended / LAEA Europe
 #> #
-#> # Edge data: 12 × 4 (active)
+#> # Edge data: 14 × 4 (active)
 #>    from    to                           geometry length
 #>   <int> <int>                   <LINESTRING [m]>    [m]
-#> 1     1     3 (4549504 2747309, 4549589 2747507)  216.
-#> 2     2     8 (4549003 2747376, 4548994 2747632)  256.
-#> 3     4     5 (4549387 2747514, 4549491 2747551)  110.
-#> 4     7     8 (4549064 2747619, 4548994 2747632)   71.1
-#> 5     9    10 (4549120 2747654, 4549418 2747723)  305.
-#> 6     9    11 (4549120 2747654, 4549119 2747790)  136.
-#> # ℹ 6 more rows
+#> 1     1     3 (4549504 2747309, 4549589 2747507)   216.
+#> 2     2     4 (4549003 2747376, 4549387 2747514)   409.
+#> 3     2     7 (4549003 2747376, 4549064 2747619)   250.
+#> 4     3     5 (4549589 2747507, 4549491 2747551)   107.
+#> 5     4     5 (4549387 2747514, 4549491 2747551)   110.
+#> 6     4     9 (4549387 2747514, 4549120 2747654)   301.
+#> # ℹ 8 more rows
 #> #
 #> # Node data: 17 × 5
 #>   name                  type     website                  geometry label
diff --git a/articles/sfn01_intro_files/figure-html/unnamed-chunk-32-4.png b/articles/sfn01_intro_files/figure-html/unnamed-chunk-32-4.png
index 6fc9f3d..a3ee4f9 100644
Binary files a/articles/sfn01_intro_files/figure-html/unnamed-chunk-32-4.png and b/articles/sfn01_intro_files/figure-html/unnamed-chunk-32-4.png differ
diff --git a/articles/sfn02_create_represent.html b/articles/sfn02_create_represent.html
index ec67a85..897f507 100644
--- a/articles/sfn02_create_represent.html
+++ b/articles/sfn02_create_represent.html
@@ -83,7 +83,7 @@
     
-

The sfnetworks contains the sfnetwork class to represent spatial networks in R. There are several ways in which you can create instances of this class. This vignette describes these ways, and provides more detail on the ins and outs of the data structure.

+

The sfnetworks package contains the sfnetwork class to represent spatial networks in R. There are several ways in which you can create instances of this class. This vignette describes these ways, and provides more detail on the ins and outs of the data structure.

 library(sfnetworks)
@@ -273,8 +273,8 @@
 
#> # A tibble: 2 × 2
 #>   oneway     n
 #>   <lgl>  <int>
-#> 1 FALSE    240
-#> 2 TRUE     975
+#> 1 FALSE 236 +#> 2 TRUE 979
 # Create a directed network.
 dnet = as_sfnetwork(streets)
@@ -294,7 +294,7 @@
 # This equals the number of oneway streets ...
 # ... plus twice the number of twoway streets.
 n_edges(mnet)
-#> [1] 1455
+#> [1] 1451

Geometries

@@ -978,39 +978,38 @@ # igraph object. inet = igraph::sample_grg(5, 0.5, coords = TRUE) inet -#> IGRAPH c92c8b1 U--- 5 3 -- Geometric random graph +#> IGRAPH 037109b U--- 5 2 -- Geometric random graph #> + attr: name (g/c), radius (g/n), torus (g/l), x (v/n), y (v/n) -#> + edges from c92c8b1: -#> [1] 2--3 2--4 3--4
+#> + edges from 037109b: +#> [1] 2--3 4--5
 # sfnetwork object.
 net = as_sfnetwork(inet, coords = c("x", "y"))
 net
-
#> # A sfnetwork: 5 nodes and 3 edges
+
#> # A sfnetwork: 5 nodes and 2 edges
 #> #
-#> # An undirected simple graph with 3 components and spatially implicit edges
+#> # An unrooted forest with 3 trees and spatially implicit edges
 #> #
 #> # Dimension: XY
-#> # Bounding box: xmin: 0.261492 ymin: 0.1013638 xmax: 0.9185794 ymax: 0.97436
+#> # Bounding box: xmin: 0.111582 ymin: 0.3144644 xmax: 0.9832471 ymax: 0.9943113
 #> # CRS: NA
 #> #
 #> # Node data: 5 × 1 (active)
 #>                geometry
 #>                 <POINT>
-#> 1  (0.261492 0.1091643)
-#> 2  (0.592074 0.5755864)
-#> 3  (0.7117123 0.877187)
-#> 4   (0.7776058 0.97436)
-#> 5 (0.9185794 0.1013638)
+#> 1   (0.111582 0.968579)
+#> 2 (0.3840216 0.4292271)
+#> 3 (0.8146119 0.3144644)
+#> 4 (0.8447424 0.9943113)
+#> 5 (0.9832471 0.9893714)
 #> #
-#> # Edge data: 3 × 2
+#> # Edge data: 2 × 2
 #>    from    to
 #>   <int> <int>
 #> 1     2     3
-#> 2     2     4
-#> 3     3     4
+#> 2 4 5

From files

diff --git a/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-11-1.png b/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-11-1.png index 6062989..1356eda 100644 Binary files a/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-11-1.png and b/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-11-1.png differ diff --git a/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-11-2.png b/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-11-2.png index ffa5884..2acaeba 100644 Binary files a/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-11-2.png and b/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-11-2.png differ diff --git a/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-45-1.png b/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-45-1.png index 8337482..c69b01f 100644 Binary files a/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-45-1.png and b/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-45-1.png differ diff --git a/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-45-2.png b/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-45-2.png index c9e8ab4..47a0a5d 100644 Binary files a/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-45-2.png and b/articles/sfn02_create_represent_files/figure-html/unnamed-chunk-45-2.png differ diff --git a/articles/sfn03_cleaning.html b/articles/sfn03_cleaning.html index 54b47c2..98083ec 100644 --- a/articles/sfn03_cleaning.html +++ b/articles/sfn03_cleaning.html @@ -331,20 +331,20 @@ #> # Edge data: 16 × 7 (active) #> from to id foo bar .tidygraph_edge_index geometry #> <int> <int> <dbl> <list> <dbl> <list> <LINESTRING> -#> 1 17 2 2 <chr> 10 <int [1]> (3 1, 4 1) -#> 2 2 7 8 <chr> 8 <int [1]> (4 1, 5.8 1) -#> 3 3 17 3 <chr> 10 <int [1]> (3 2, 3 1) -#> 4 17 4 3 <chr> 10 <int [1]> (3 1, 3 0) -#> 5 2 6 5 <chr> 5 <int [1]> (4 1, 4 0) -#> 6 7 10 11 <chr> 6 <int [1]> (5.8 1, 6 0.8) +#> 1 17 2 2 <chr> 7 <int [1]> (3 1, 4 1) +#> 2 2 7 8 <chr> 10 <int [1]> (4 1, 5.8 1) +#> 3 3 17 3 <chr> 6 <int [1]> (3 2, 3 1) +#> 4 17 4 3 <chr> 6 <int [1]> (3 1, 3 0) +#> 5 2 6 5 <chr> 10 <int [1]> (4 1, 4 0) +#> 6 7 10 11 <chr> 7 <int [1]> (5.8 1, 6 0.8) #> # ℹ 10 more rows #> # #> # Node data: 17 × 4 #> geometry foo bar .tidygraph_node_index #> <POINT> <chr> <int> <int> -#> 1 (0 1) g 6 1 -#> 2 (4 1) n 1 3 -#> 3 (3 2) r 2 4 +#> 1 (0 1) b 3 1 +#> 2 (4 1) n 7 3 +#> 3 (3 2) x 9 4 #> # ℹ 14 more rows diff --git a/articles/sfn04_join_filter.html b/articles/sfn04_join_filter.html index 5b6e17f..b9c2f72 100644 --- a/articles/sfn04_join_filter.html +++ b/articles/sfn04_join_filter.html @@ -83,7 +83,7 @@ -

The integration with sf and addition of several spatial network specific functions in sfnetworks allow to easily filter information from a network based on spatial relationships, and to join new information into a network based on spatial relationships. This vignette presents several ways to do that.

+

The integration with sf and addition of several spatial network specific functions in sfnetworks allow to easily filter information from a network based on spatial relationships, and to join new information into a network based on spatial relationships. This vignette presents several ways to do that.

Both spatial filters and spatial joins use spatial predicate functions to examine spatial relationships. Spatial predicates are mathematically defined binary spatial relations between two simple feature geometries. Often used examples include the predicate equals (geometry x is equal to geometry y) and the predicate intersects (geometry x has at least one point in common with geometry y). For an overview of all available spatial predicate functions in sf and links to detailed explanations of the underlying algorithms, see here.

diff --git a/articles/sfn05_routing.html b/articles/sfn05_routing.html
index 30c1c8d..65e348e 100644
--- a/articles/sfn05_routing.html
+++ b/articles/sfn05_routing.html
@@ -293,7 +293,7 @@
 

Choosing a routing backend

-

As mentioned, {sfnetwork} does not implement the routing algorithms themselves. For that, it relies on other packages, which we call “routing backends” or “routers” for short. The default routing backend is igraph. The st_network_paths() function wraps, depending on argument settings, igraph::shortest_paths(), igraph::all_shortest_paths() and igraph::k_shortest_paths(). The st_network_cost() function wraps igraph::distances(). The benefits of this routing backend are: 1) it can compute all shortest paths, if there exists more than one; 2) it can compute the kk shortest paths with Yen’s algorithm; 3) no internal conversion between data structures is needed. However, routing is only supported from a single origin. Hence, many-to-many routing is not possible.

+

As mentioned, sfnetworks does not implement the routing algorithms themselves. For that, it relies on other packages, which we call “routing backends” or “routers” for short. The default routing backend is igraph. The st_network_paths() function wraps, depending on argument settings, igraph::shortest_paths(), igraph::all_shortest_paths() and igraph::k_shortest_paths(). The st_network_cost() function wraps igraph::distances(). The benefits of this routing backend are: 1) it can compute all shortest paths, if there exists more than one; 2) it can compute the kk shortest paths with Yen’s algorithm; 3) no internal conversion between data structures is needed. However, routing is only supported from a single origin. Hence, many-to-many routing is not possible.

The second routing backend that is currently supported is dodgr. This package implements a very fast routing algorithm in C++. This is exposed in sfnetworks by wrapping dodgr::dodgr_paths() in st_network_paths() and dodgr::dodgr_dists() in st_network_cost(). The benefits of this routing backend are: 1) it can route from multiple origins to multiple destinations, i.e. many-to-many routing; 2) it supports dual-weighted routing (see here); 3) it is very fast also on large networks. However, there is currently no support for kk shortest paths routing, and some internal conversions are needed to bridge between the different data structures.

You can specify which routing backend to use through the router argument. If you want to change the default routing backend, update the global options: options(sfn_default_router = "dodgr").

Specifying origins and destinations @@ -561,10 +561,10 @@ #> # A tibble: 4 × 7 #> from to node_path edge_path path_found cost geometry #> * <dbl> <dbl> <list> <list> <lgl> [m] <MULTILINESTRING [m]> -#> 1 633 1003 <dbl [28]> <dbl [27]> TRUE 1074. ((4151039 3206662, 4151063… -#> 2 1003 869 <dbl [12]> <dbl [11]> TRUE 602. ((4151793 3207244, 4151805… -#> 3 869 999 <dbl [39]> <dbl [38]> TRUE 1178. ((4151073 3207744, 4151097… -#> 4 999 633 <dbl [24]> <dbl [23]> TRUE 1385. ((4151138 3207734, 4151160… +#> 1 869 1003 <dbl [12]> <dbl [11]> TRUE 602. ((4151793 3207244, 4151805… +#> 2 1003 633 <dbl [28]> <dbl [27]> TRUE 1074. ((4151039 3206662, 4151063… +#> 3 633 1001 <dbl [22]> <dbl [21]> TRUE 1385. ((4151138 3207734, 4151160… +#> 4 1001 869 <dbl [39]> <dbl [38]> TRUE 1178. ((4151073 3207744, 4151097…
@@ -598,7 +598,7 @@
 #> Simple feature collection with 4 features and 1 field
 #> Geometry type: POLYGON
 #> Dimension:     XY
-#> Bounding box:  xmin: 4150754 ymin: 3206653 xmax: 4152337 ymax: 3208212
+#> Bounding box:  xmin: 4150754 ymin: 3206653 xmax: 4152274 ymax: 3208212
 #> Projected CRS: ETRS89-extended / LAEA Europe
 #>       cost                       geometry
 #> 1 1000 [m] POLYGON ((4151598 3206653, ...
@@ -747,10 +747,10 @@
   router = "dodgr"
 ) |> round()
 #>        1  151  301  451  601  751  901
-#> 1      0 2953  374 1644 1445  863 5485
+#> 1      0 2953  374 1599 1445  863 5485
 #> 151 2953    0 2579 3721 2371 3816 7772
 #> 301  374 2579    0 1244 1071 1237 5567
-#> 451 1971 3721 1244    0 2213 1349 5310
+#> 451 1599 3721 1244    0 2213 1349 5971
 #> 601 1445 2371 1071 2213    0 2308 6437
 #> 751  863 3816 1237 1349 2308    0 4811
 #> 901 5485 8385 5806 5559 6876 4811    0
diff --git a/articles/sfn05_routing_files/figure-html/unnamed-chunk-25-1.png b/articles/sfn05_routing_files/figure-html/unnamed-chunk-25-1.png index b20ef7b..f7aa5bf 100644 Binary files a/articles/sfn05_routing_files/figure-html/unnamed-chunk-25-1.png and b/articles/sfn05_routing_files/figure-html/unnamed-chunk-25-1.png differ diff --git a/articles/sfn05_routing_files/figure-html/unnamed-chunk-27-1.png b/articles/sfn05_routing_files/figure-html/unnamed-chunk-27-1.png index 21649ef..b1919a4 100644 Binary files a/articles/sfn05_routing_files/figure-html/unnamed-chunk-27-1.png and b/articles/sfn05_routing_files/figure-html/unnamed-chunk-27-1.png differ diff --git a/articles/sfn05_routing_files/figure-html/unnamed-chunk-29-1.png b/articles/sfn05_routing_files/figure-html/unnamed-chunk-29-1.png index 777b429..34dff45 100644 Binary files a/articles/sfn05_routing_files/figure-html/unnamed-chunk-29-1.png and b/articles/sfn05_routing_files/figure-html/unnamed-chunk-29-1.png differ diff --git a/articles/sfn05_routing_files/figure-html/unnamed-chunk-31-1.png b/articles/sfn05_routing_files/figure-html/unnamed-chunk-31-1.png index b317985..474b4f6 100644 Binary files a/articles/sfn05_routing_files/figure-html/unnamed-chunk-31-1.png and b/articles/sfn05_routing_files/figure-html/unnamed-chunk-31-1.png differ diff --git a/articles/sfn05_routing_files/figure-html/unnamed-chunk-33-1.png b/articles/sfn05_routing_files/figure-html/unnamed-chunk-33-1.png index 6f65d87..77b1fde 100644 Binary files a/articles/sfn05_routing_files/figure-html/unnamed-chunk-33-1.png and b/articles/sfn05_routing_files/figure-html/unnamed-chunk-33-1.png differ diff --git a/articles/sfn05_routing_files/figure-html/unnamed-chunk-36-1.png b/articles/sfn05_routing_files/figure-html/unnamed-chunk-36-1.png index bb90a78..f536ccd 100644 Binary files a/articles/sfn05_routing_files/figure-html/unnamed-chunk-36-1.png and b/articles/sfn05_routing_files/figure-html/unnamed-chunk-36-1.png differ diff --git a/articles/sfn05_routing_files/figure-html/unnamed-chunk-36-2.png b/articles/sfn05_routing_files/figure-html/unnamed-chunk-36-2.png index aebc8e4..41a2071 100644 Binary files a/articles/sfn05_routing_files/figure-html/unnamed-chunk-36-2.png and b/articles/sfn05_routing_files/figure-html/unnamed-chunk-36-2.png differ diff --git a/index.html b/index.html index 8e0fcc7..dbc465f 100644 --- a/index.html +++ b/index.html @@ -79,7 +79,7 @@

Backgroundsf} for spatial data science and {tidygraph} for standard graph analysis. The core of the package is a dedicated data structure for geospatial networks, that can be provided as input to both the graph analytical functions of {tidygraph} as well as the spatial analytical functions of {sf}, without the need for conversion. Additionally, we implemented a set of geospatial network specific functions, such as routines for shortest path calculation, network cleaning and topology modification. {sfnetworks} is designed as a general-purpose package suitable for usage across different application domains, and can be seamlessly integrated in tidyverse workflows.

-

sfnetworks dependencies and building blocks.

+

sfnetworks dependencies and building blocks.

Installation diff --git a/pkgdown.yml b/pkgdown.yml index ba4cc37..714fda6 100644 --- a/pkgdown.yml +++ b/pkgdown.yml @@ -7,7 +7,7 @@ articles: sfn03_cleaning: sfn03_cleaning.html sfn04_join_filter: sfn04_join_filter.html sfn05_routing: sfn05_routing.html -last_built: 2024-11-17T20:26Z +last_built: 2024-11-17T20:49Z urls: reference: https://luukvdmeer.github.io/sfnetworks/reference article: https://luukvdmeer.github.io/sfnetworks/articles diff --git a/search.json b/search.json index 335af2a..ca6115a 100644 --- a/search.json +++ b/search.json @@ -1 +1 @@ -[{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"our-pledge","dir":"","previous_headings":"","what":"Our Pledge","title":"Contributor Covenant Code of Conduct","text":"members, contributors, leaders pledge make participation community harassment-free experience everyone, regardless age, body size, visible invisible disability, ethnicity, sex characteristics, gender identity expression, level experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, sexual identity orientation. pledge act interact ways contribute open, welcoming, diverse, inclusive, healthy community.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"our-standards","dir":"","previous_headings":"","what":"Our Standards","title":"Contributor Covenant Code of Conduct","text":"Examples behavior contributes positive environment community include: Demonstrating empathy kindness toward people respectful differing opinions, viewpoints, experiences Giving gracefully accepting constructive feedback Accepting responsibility apologizing affected mistakes, learning experience Focusing best just us individuals, overall community Examples unacceptable behavior include: use sexualized language imagery, sexual attention advances kind Trolling, insulting derogatory comments, personal political attacks Public private harassment Publishing others’ private information, physical email address, without explicit permission conduct reasonably considered inappropriate professional setting","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"enforcement-responsibilities","dir":"","previous_headings":"","what":"Enforcement Responsibilities","title":"Contributor Covenant Code of Conduct","text":"Community leaders responsible clarifying enforcing standards acceptable behavior take appropriate fair corrective action response behavior deem inappropriate, threatening, offensive, harmful. Community leaders right responsibility remove, edit, reject comments, commits, code, wiki edits, issues, contributions aligned Code Conduct, communicate reasons moderation decisions appropriate.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"scope","dir":"","previous_headings":"","what":"Scope","title":"Contributor Covenant Code of Conduct","text":"Code Conduct applies within community spaces, also applies individual officially representing community public spaces. Examples representing community include using official e-mail address, posting via official social media account, acting appointed representative online offline event.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"enforcement","dir":"","previous_headings":"","what":"Enforcement","title":"Contributor Covenant Code of Conduct","text":"Instances abusive, harassing, otherwise unacceptable behavior may reported community leaders responsible enforcement lucas.vandermeer@sbg.ac.. complaints reviewed investigated promptly fairly. community leaders obligated respect privacy security reporter incident.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"enforcement-guidelines","dir":"","previous_headings":"","what":"Enforcement Guidelines","title":"Contributor Covenant Code of Conduct","text":"Community leaders follow Community Impact Guidelines determining consequences action deem violation Code Conduct:","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"id_1-correction","dir":"","previous_headings":"Enforcement Guidelines","what":"1. Correction","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Use inappropriate language behavior deemed unprofessional unwelcome community. Consequence: private, written warning community leaders, providing clarity around nature violation explanation behavior inappropriate. public apology may requested.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"id_2-warning","dir":"","previous_headings":"Enforcement Guidelines","what":"2. Warning","title":"Contributor Covenant Code of Conduct","text":"Community Impact: violation single incident series actions. Consequence: warning consequences continued behavior. interaction people involved, including unsolicited interaction enforcing Code Conduct, specified period time. includes avoiding interactions community spaces well external channels like social media. Violating terms may lead temporary permanent ban.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"id_3-temporary-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"3. Temporary Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: serious violation community standards, including sustained inappropriate behavior. Consequence: temporary ban sort interaction public communication community specified period time. public private interaction people involved, including unsolicited interaction enforcing Code Conduct, allowed period. Violating terms may lead permanent ban.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"id_4-permanent-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"4. Permanent Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Demonstrating pattern violation community standards, including sustained inappropriate behavior, harassment individual, aggression toward disparagement classes individuals. Consequence: permanent ban sort public interaction within community.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"attribution","dir":"","previous_headings":"","what":"Attribution","title":"Contributor Covenant Code of Conduct","text":"Code Conduct adapted Contributor Covenant, version 2.1, available https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. Community Impact Guidelines inspired Mozilla’s code conduct enforcement ladder. answers common questions code conduct, see FAQ https://www.contributor-covenant.org/faq. Translations available https://www.contributor-covenant.org/translations.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CONTRIBUTING.html","id":null,"dir":"","previous_headings":"","what":"How to contribute?","title":"How to contribute?","text":"look much forward contributions package. can done several ways: Create pull request specific feature implementation bug fix. Please direct develop branch. Open issue issue tracker request specific feature report bug. Please use respective issue templates . Share general ideas package starting new discussion discussion room, using ideas category. Share experiences using package work starting new discussion discussion room, using show tell category. Sharing help package developers see package used improve things accordingly, users learn package get inspiration work! Ask questions starting new discussion discussion room, using Q&category, StackOverflow sfnetwork tag. Asking questions openly helps users struggle problems!","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CONTRIBUTING.html","id":"code-style","dir":"","previous_headings":"","what":"Code style","title":"How to contribute?","text":"strive follow tidyverse styleguide source code package. exception assignment operator: use = instead <- (see reasons ).","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CONTRIBUTING.html","id":"structured-commit-messages","dir":"","previous_headings":"","what":"Structured commit messages","title":"How to contribute?","text":"commiting changes git commit try use structured commit messages, adapted https://www.conventionalcommits.org/. first line commit message following format: summary short (preferably < 50 characters), starting upper case, written present tense. commit references specific issue, include Refs # summary. issue bug report, may also use Fix # issue gets closed automatically. type one defined types listed . feel artistic, can end commit message emoji belonging type 😎. feat: Implementation new feature. :gift: 🎁 fix: bug fix. :wrench: 🔧 style: Changes code formatting. change program logic. :art: 🎨 refactor: Changes existing functionality change behaviour. :construction: 🚧 breaking: Changes existing functionality backwards compatible. :warning: ⚠️ docs: Adding, removing updating user documentation. :books: 📚 logs: Adding, removing updating log messages. :sound: 🔉 test: Adding, removing updating tests. changes user code. :test_tube: 🧪 cicd: Adding, removing updating CI/CD workflows. changes user code. :robot: 🤖 deps: Adding, removing updating dependencies. :couple: 👫 release: Preparing release, e.g. updating version numbers. :bookmark: 🔖 repo: Changes repository involve code/documentation, e.g. adding templates community files. :package: 📦 Example commit messages :","code":": git commit -m 'feat: Add bar parameter to foo(). Refs #10 :gift:' git commit -m 'fix: Include type checking in foo(). Fix #12 :wrench:'"},{"path":"https://luukvdmeer.github.io/sfnetworks/CONTRIBUTING.html","id":"code-of-conduct","dir":"","previous_headings":"","what":"Code of conduct","title":"How to contribute?","text":"project released Contributor Code Conduct. participating project agree abide terms.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":null,"dir":"","previous_headings":"","what":"Apache License","title":"Apache License","text":"Version 2.0, January 2004 ","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_1-definitions","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"1. Definitions","title":"Apache License","text":"“License” shall mean terms conditions use, reproduction, distribution defined Sections 1 9 document. “Licensor” shall mean copyright owner entity authorized copyright owner granting License. “Legal Entity” shall mean union acting entity entities control, controlled , common control entity. purposes definition, “control” means () power, direct indirect, cause direction management entity, whether contract otherwise, (ii) ownership fifty percent (50%) outstanding shares, (iii) beneficial ownership entity. “” (“”) shall mean individual Legal Entity exercising permissions granted License. “Source” form shall mean preferred form making modifications, including limited software source code, documentation source, configuration files. “Object” form shall mean form resulting mechanical transformation translation Source form, including limited compiled object code, generated documentation, conversions media types. “Work” shall mean work authorship, whether Source Object form, made available License, indicated copyright notice included attached work (example provided Appendix ). “Derivative Works” shall mean work, whether Source Object form, based (derived ) Work editorial revisions, annotations, elaborations, modifications represent, whole, original work authorship. purposes License, Derivative Works shall include works remain separable , merely link (bind name) interfaces , Work Derivative Works thereof. “Contribution” shall mean work authorship, including original version Work modifications additions Work Derivative Works thereof, intentionally submitted Licensor inclusion Work copyright owner individual Legal Entity authorized submit behalf copyright owner. purposes definition, “submitted” means form electronic, verbal, written communication sent Licensor representatives, including limited communication electronic mailing lists, source code control systems, issue tracking systems managed , behalf , Licensor purpose discussing improving Work, excluding communication conspicuously marked otherwise designated writing copyright owner “Contribution.” “Contributor” shall mean Licensor individual Legal Entity behalf Contribution received Licensor subsequently incorporated within Work.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_2-grant-of-copyright-license","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"2. Grant of Copyright License","title":"Apache License","text":"Subject terms conditions License, Contributor hereby grants perpetual, worldwide, non-exclusive, -charge, royalty-free, irrevocable copyright license reproduce, prepare Derivative Works , publicly display, publicly perform, sublicense, distribute Work Derivative Works Source Object form.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_3-grant-of-patent-license","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"3. Grant of Patent License","title":"Apache License","text":"Subject terms conditions License, Contributor hereby grants perpetual, worldwide, non-exclusive, -charge, royalty-free, irrevocable (except stated section) patent license make, made, use, offer sell, sell, import, otherwise transfer Work, license applies patent claims licensable Contributor necessarily infringed Contribution(s) alone combination Contribution(s) Work Contribution(s) submitted. institute patent litigation entity (including cross-claim counterclaim lawsuit) alleging Work Contribution incorporated within Work constitutes direct contributory patent infringement, patent licenses granted License Work shall terminate date litigation filed.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_4-redistribution","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"4. Redistribution","title":"Apache License","text":"may reproduce distribute copies Work Derivative Works thereof medium, without modifications, Source Object form, provided meet following conditions: () must give recipients Work Derivative Works copy License; (b) must cause modified files carry prominent notices stating changed files; (c) must retain, Source form Derivative Works distribute, copyright, patent, trademark, attribution notices Source form Work, excluding notices pertain part Derivative Works; (d) Work includes “NOTICE” text file part distribution, Derivative Works distribute must include readable copy attribution notices contained within NOTICE file, excluding notices pertain part Derivative Works, least one following places: within NOTICE text file distributed part Derivative Works; within Source form documentation, provided along Derivative Works; , within display generated Derivative Works, wherever third-party notices normally appear. contents NOTICE file informational purposes modify License. may add attribution notices within Derivative Works distribute, alongside addendum NOTICE text Work, provided additional attribution notices construed modifying License. may add copyright statement modifications may provide additional different license terms conditions use, reproduction, distribution modifications, Derivative Works whole, provided use, reproduction, distribution Work otherwise complies conditions stated License.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_5-submission-of-contributions","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"5. Submission of Contributions","title":"Apache License","text":"Unless explicitly state otherwise, Contribution intentionally submitted inclusion Work Licensor shall terms conditions License, without additional terms conditions. Notwithstanding , nothing herein shall supersede modify terms separate license agreement may executed Licensor regarding Contributions.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_6-trademarks","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"6. Trademarks","title":"Apache License","text":"License grant permission use trade names, trademarks, service marks, product names Licensor, except required reasonable customary use describing origin Work reproducing content NOTICE file.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_7-disclaimer-of-warranty","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"7. Disclaimer of Warranty","title":"Apache License","text":"Unless required applicable law agreed writing, Licensor provides Work (Contributor provides Contributions) “” BASIS, WITHOUT WARRANTIES CONDITIONS KIND, either express implied, including, without limitation, warranties conditions TITLE, NON-INFRINGEMENT, MERCHANTABILITY, FITNESS PARTICULAR PURPOSE. solely responsible determining appropriateness using redistributing Work assume risks associated exercise permissions License.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_8-limitation-of-liability","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"8. Limitation of Liability","title":"Apache License","text":"event legal theory, whether tort (including negligence), contract, otherwise, unless required applicable law (deliberate grossly negligent acts) agreed writing, shall Contributor liable damages, including direct, indirect, special, incidental, consequential damages character arising result License use inability use Work (including limited damages loss goodwill, work stoppage, computer failure malfunction, commercial damages losses), even Contributor advised possibility damages.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_9-accepting-warranty-or-additional-liability","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"9. Accepting Warranty or Additional Liability","title":"Apache License","text":"redistributing Work Derivative Works thereof, may choose offer, charge fee , acceptance support, warranty, indemnity, liability obligations /rights consistent License. However, accepting obligations, may act behalf sole responsibility, behalf Contributor, agree indemnify, defend, hold Contributor harmless liability incurred , claims asserted , Contributor reason accepting warranty additional liability. END TERMS CONDITIONS","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"appendix-how-to-apply-the-apache-license-to-your-work","dir":"","previous_headings":"","what":"APPENDIX: How to apply the Apache License to your work","title":"Apache License","text":"apply Apache License work, attach following boilerplate notice, fields enclosed brackets [] replaced identifying information. (Don’t include brackets!) text enclosed appropriate comment syntax file format. also recommend file class name description purpose included “printed page” copyright notice easier identification within third-party archives.","code":"Copyright 2020 sfnetworks authors Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License."},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"rationale","dir":"Articles","previous_headings":"","what":"Rationale","title":"Introduction to sfnetworks","text":"R good packages respectively geospatial analysis standard network analysis: sf package brings simple features standard R provides interface low-level geospatial system libraries GDAL, GEOS, s2, allowing represent analyze spatial vector data points, lines polygons. tidygraph package provides tidy interface large network analysis library igraph, written C also R API. packages great purposes. However, sf know networks, tidygraph know space. combining forces, sfnetworks enables integrated workflows connecting network analysis spatial analysis. addition, offers functions specific spatial network analysis, found either two “parent packages”. , often utilizes additional building blocks within R world.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"representing-spatial-networks","dir":"Articles","previous_headings":"","what":"Representing spatial networks","title":"Introduction to sfnetworks","text":"Spatial networks sfnetworks represented objects class sfnetwork. objects inherit tbl_graph class tidygraph, turn inherit igraph class igraph. means core designed store graph structures. However, thanks design tidygraph, look like collection two flat tables: one nodes, one edges. tidygraph tables can treated tibbles, sfnetworks sf data frames list column containing geometry feature. sfnetworks, edges can either directed (default) undirected. Mixed networks contain types edges, e.g. road networks oneway streets, can represented duplicating reversing edges can traveled ways. nodes spatial networks need explicitly store geometries, edges always required. edges straight lines, spatial embedding can also inferred spatial locations nodes connect. sfnetworks refer two approaches spatially explicit edges spatially implicit edges, respectively. details representation spatial networks sfnetwork class can found vignette Creating representing spatial networks. many different ways create sfnetwork object, explained detail vignette Creating representing spatial networks. commonly start set spatial features, stored object class sf. features linestrings, considered edges network, nodes created endpoints. multiple linestrings share endpoint, becomes single node network, hence, edges adjacent. features points, considered nodes network, connected edges according given adjacency matrix. adjacency matrix can also created internally according specified method.","code":"net = as_sfnetwork(roxel) net #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows plot(net) net = as_sfnetwork(mozart, connections = \"gabriel\", directed = FALSE) net #> # A sfnetwork: 17 nodes and 25 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 4 (active) #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> 4 Mozart Denkmal artwork NA (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) #> 6 Mozartsteg bridge NA (4549473 2747624) #> # ℹ 11 more rows #> # #> # Edge data: 25 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 1 4 (4549504 2747309, 4549387 2747514) #> 3 2 4 (4549003 2747376, 4549387 2747514) #> # ℹ 22 more rows plot(net)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"analyzing-spatial-networks","dir":"Articles","previous_headings":"","what":"Analyzing spatial networks","title":"Introduction to sfnetworks","text":"Thanks design sf tidygraph, spatial network analysis sfnetworks can fitted seamlessly tidy data analysis workflows using tidyverse family packages. Since sfnetwork object can treated collection two tables, rather one, just need specify want apply function. , tidygraph invented activate() verb, allowing set either nodes edges target analysis. done , can apply favorite tidyverse verb just ’re used . can see activation network element also changes order printed. Obviously network just list two distinct elements. Nodes edges related . Therefore, operations applied nodes may also affect edges, vice versa. good example filtering. Whenever nodes removed network, edges terminating nodes removed . behavior symmetric: removing edges, endpoints edges remain, even endpoint edge. definition edges can never exist without nodes ends, nodes can peacefully exist isolation. Another consequence working relational data operations defined single tables applicable networks. example, common groupby-apply-combine workflows supported, since break relational structure. cases, however, can always extract active element network either sf object tibble, proceed analysis single table. allow performing common network analysis tasks, sfnetworks builds upon tidygraph. Since sfnetwork objects inherit tbl_graph class, analytical functions tidygraph can directly used. lot functions available, tidy wrappers around functions igraph library. complete overview, check tidygraph documentation. important note case spatial networks often makes sense use geographic length edge weight. Since tidygraph know space, never set automatically, explicitly specify every time call function can consider edge weights. Read specifying edge weights vignette Routing spatial networks. large set functions tidygraph dedicated computation quantitative measures nodes, edges, network whole. known centrality measures, define importance node network. names implemented centrality measure functions formatted centrality_*. implemented measure functions names formatted node_* (node measures) edge_* (edge measures) graph_* (network measures). special group measure functions logical measures, return either TRUE FALSE, indicating node, edge network specified type. None functions meant called directly, used inside tidyverse-verbs dplyr::mutate() dplyr::filter(), analyzed network know thus needed input function. tidygraph::with_graph() can used evaluate measure context specific network, outside tidyverse framework. Another set functions tidygraph deals community detection networks. functions group nodes edges based clustering algorithm. names formatted group_*, always return vector group indices, one feature. implemented algorithms try create groups nodes number edges within groups relatively high compared number edges groups, example . note algorithms generally designed account spatial factors, may limited use working spatial networks. Finally, tidygraph introduced new set network analysis functions call morphers. Morphers change structure input graph, example subsetting splitting , combining multiple features one, converting nodes edges vice versa. different struture needed computations, can set temporarily providing morphers subsequently tidygraph::morph() tidygraph::unmorph() verbs. different structure meant last, morpher can provided tidygraph::convert() verb instead. example convert network minimum spanning tree, contains minimum set edges need nodes still connected like . writing methods many spatial analytical functions sf package, sfnetworks allows functions called directly sfnetwork objects, without need conversion. See overview sf functions method sfnetwork objects. complete overview functionalities sf, check sf documentation. One many tasks sf covers specification coordinate reference systems, CRS short, transformation spatial coordinates systems. sfnetwork object nodes edges always CRS, matter elements active retrieve CRS, transform coordinates different CRS. sf also multiple functions implement evaluation spatial predicate. spatial predicate describes spatial relation two geometries. example, point may located within polygon B. example show evaluate node spatial network located within one two given polygons. using spatial predicates, sf offers ability perform spatial joins spatial filters. Spatial joins join information spatial feature features specified spatial relation . Spatial filters keep features specified spatial relation, removes . details spatial joins filters spatial networks, see vignette Spatial joins filters. Finally, sf contains group functions known geometric unary operations. functions change structure individual geometries. usage context spatial networks limited, since many break network structure endpoints edges spatially equal respective nodes. Hence, geometric unary operations change type, shape, position geometries method sfnetwork objects. include sf::st_reverse() reverse edge geometries, sf::st_segmentize() add interior points edge geometries. However, just unsupported tidyverse-verbs, can still apply unsupported geometric unary operations first extracting active element sf object, proceed analysis single table. mentioned, sfnetworks extends functionalities tidygraph sf offering functions specific spatial network analysis, well functions allow smoother integration sf design tidygraph workflows. contradiction tidygraph, functions sfnetworks consider edge weights always use geographic edge length default weight. first family functions sfnetworks names formatted st_network_*, adopting naming conventions sf. functions take spatial network first input implement analysis task involves network set regular spatial simple features (points, lines, polygons). returned object can either set spatial simple features computed network, network spatial features merged , another object (e.g., matrix) result computation relating network spatial features. covers large range use-cases. Examples include drawing isochrone isodistance polygons around nodes, finding geographic shortest paths pairs nodes, computing cost matrices travel nodes, extracting faces network, adding external point data new nodes network. vignettes find details functions. also functions sfnetworks start st_*, end *_network. contradiction st_network_* functions, functions take set spatial features first input, network additional argument. example st_project_on_network, projects points onto network. Shortest path Isodistance polygon Network faces Blended points extension measure functions tidygraph, several spatial measure functions nodes edges found sfnetworks. Just tidygraph, functions named style node_* edge_*, centrality measure, centrality_*. Edge measures can computed include example geographic length edge, azimuth, circuity (.e. ratio geographic length shortest euclidean distance source target node). nodes, example possible compute straightness centrality (.e. average ratio euclidean distance network distance node nodes network). better integrate spatial predicate functions sf design tidygraph, applicable predicates also implemented node edge measure function. functions return TRUE node edge specified spatial relation least one given spatial features, FALSE otherwise. makes easy use predicates directly inside functions dplyr::filter() dplyr::mutate(). extension community detection functions tidygraph, sfnetworks contains group_spatial_dbscan() function find spatial clusters nodes. idea offer multiple spatial clustering algorithms choose , currently one implemented DBSCAN algorithm (require dbscan package installed). algorithm executed network distance matrix nodes, euclidean distance matrix. extension morpher functions tidygraph, many different spatial morpher functions implemented sfnetworks. Just tidygraph, function change structure input network, example subsetting splitting , combining multiple features one, splitting single features. Common examples include subdividing network interior points edge geometries, smoothing pseudo nodes degree 2, contracting multiple nodes one preserving network connectivity. vignettes find details functions. Many morphers used network cleaning operations, described detail vignette Cleaning spatial networks. Smooth network Subdivision smooth network Contracted groups nodes single path Finally, sfnetworks exports kind utility functions make working spatial networks less cumbersome. example finding nearest node nearest edge given spatial feature. overview exported functions package, see function reference. Nearest node Nearest edge Also fan tidyverse style data analysis, sfnetworks can . Since sfnetwork objects inherit igraph class, can apply functions large igraph package . means, example, instead using dplyr::mutate() dplyr::filter(), proceed follows (note igraph, term vertex used instead node). can see, returns igraph object instead sfnetwork object. preserve class, can use wrap_igraph() function sfnetworks igraph function accepts network first input returns another network. function check returned network still spatial. spatial measure functions can evaluated outside tidygraph framework using with_graph(), works similar base R’s () function. spatial morpher functions implement larger workflow internal workers exported, meaning can called directly outside tidygraph::morph() tidygraph::convert() verbs. morphers easy replicate using sf sfnetworks functions directly.","code":"net |> activate(nodes) |> mutate(label = letters[1:n()]) |> select(name, label) |> activate(edges) |> filter(sample(c(TRUE, FALSE), n(), replace = TRUE)) #> # A sfnetwork: 17 nodes and 13 edges #> # #> # An unrooted forest with 4 trees and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 13 × 3 (active) #> from to geometry #> #> 1 1 4 (4549504 2747309, 4549387 2747514) #> 2 3 5 (4549589 2747507, 4549491 2747551) #> 3 4 5 (4549387 2747514, 4549491 2747551) #> 4 4 9 (4549387 2747514, 4549120 2747654) #> 5 6 10 (4549473 2747624, 4549418 2747723) #> 6 7 9 (4549064 2747619, 4549120 2747654) #> # ℹ 7 more rows #> # #> # Node data: 17 × 3 #> name label geometry #> #> 1 Mozartkino a (4549504 2747309) #> 2 Haus für Mozart b (4549003 2747376) #> 3 Mozartsteg/Rudolfskai c (4549589 2747507) #> # ℹ 14 more rows # Filtering nodes also reduces the number of edges. net |> activate(nodes) |> filter(type == \"artwork\") #> # A sfnetwork: 3 nodes and 0 edges #> # #> # An unrooted forest with 3 trees and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747514 xmax: 4549387 ymax: 2747868 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 3 × 4 (active) #> name type website geometry #> #> 1 Mozart Denkmal artwork NA (4549387 2747514) #> 2 Spirit of Mozart artwork https://salzburgfoundat… (4549119 2747790) #> 3 Mozart-Eine Hommage artwork https://salzburgfoundat… (4548664 2747868) #> # #> # Edge data: 0 × 3 #> # ℹ 3 variables: from , to , geometry net |> activate(nodes) |> st_as_sf() |> group_by(type) |> summarize(n = n()) #> Simple feature collection with 13 features and 2 fields #> Geometry type: GEOMETRY #> Dimension: XY #> Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 13 × 3 #> type n geometry #> #> 1 apartments 1 POINT (4549073 2747916) #> 2 artwork 3 MULTIPOINT ((4548664 2747868), (4549119 2747790), (45493… #> 3 bridge 1 POINT (4549473 2747624) #> 4 bus_stop 3 MULTIPOINT ((4549418 2747723), (4549491 2747551), (45495… #> 5 cafe 1 POINT (4548994 2747632) #> 6 cinema 1 POINT (4549504 2747309) #> 7 concert_hall 1 POINT (4548897 2748037) #> 8 confectionery 1 POINT (4549120 2747654) #> 9 dormitory 1 POINT (4548984 2748537) #> 10 hotel 1 POINT (4549378 2748391) #> 11 museum 1 POINT (4549064 2747619) #> 12 theatre 1 POINT (4549003 2747376) #> 13 university 1 POINT (4549059 2748042) net = net |> activate(edges) |> mutate(length = edge_length()) net #> # A sfnetwork: 17 nodes and 25 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 25 × 4 (active) #> from to geometry length #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. #> 4 2 7 (4549003 2747376, 4549064 2747619) 250. #> 5 2 8 (4549003 2747376, 4548994 2747632) 256. #> 6 3 5 (4549589 2747507, 4549491 2747551) 107. #> # ℹ 19 more rows #> # #> # Node data: 17 × 4 #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> # ℹ 14 more rows new_net = net |> activate(edges) |> filter(!edge_is_incident(13)) |> activate(nodes) |> mutate(bc = centrality_betweenness(weights = length)) new_net #> # A sfnetwork: 17 nodes and 23 edges #> # #> # A bipartite simple graph with 2 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 5 (active) #> name type website geometry bc #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) 0 #> 2 Haus für Mozart theatre NA (4549003 2747376) 0 #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 5 #> 4 Mozart Denkmal artwork NA (4549387 2747514) 21 #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 22 #> 6 Mozartsteg bridge NA (4549473 2747624) 16 #> # ℹ 11 more rows #> # #> # Edge data: 23 × 4 #> from to geometry length #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. #> # ℹ 20 more rows ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(size = bc)) + theme_void() with_graph(net, centrality_degree()) |> setNames(NULL) #> [1] 2 3 2 4 3 2 3 3 4 4 3 2 2 4 3 3 3 new_net = net |> activate(nodes) |> mutate(group = group_optimal()) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(group)), size = 4) + scale_colour_discrete(\"group\") + theme_void() new_net = net |> convert(to_minimum_spanning_tree, weights = length) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() st_crs(net)$epsg #> [1] 3035 st_transform(net, 4326) #> # A sfnetwork: 17 nodes and 25 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 13.03835 ymin: 47.79698 xmax: 13.05049 ymax: 47.80822 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 25 × 4 (active) #> from to geometry length #> [m] #> 1 1 3 (13.04925 47.79698, 13.05049 47.79874) 216. #> 2 1 4 (13.04925 47.79698, 13.04781 47.79887) 236. #> 3 2 4 (13.0426 47.79778, 13.04781 47.79887) 409. #> 4 2 7 (13.0426 47.79778, 13.04355 47.79993) 250. #> 5 2 8 (13.0426 47.79778, 13.04263 47.80008) 256. #> 6 3 5 (13.05049 47.79874, 13.04921 47.79917) 107. #> # ℹ 19 more rows #> # #> # Node data: 17 × 4 #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (13.04925 47.79698) #> 2 Haus für Mozart theatre NA (13.0426 47.79778) #> 3 Mozartsteg/Rudolfskai bus_stop NA (13.05049 47.79874) #> # ℹ 14 more rows polys = mozart |> slice(4, 15) |> st_buffer(325) |> mutate(label = c(\"A\", \"B\")) |> select(label) ggraph(net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() net |> activate(nodes) |> st_within(polys) #> Sparse geometry binary predicate list of length 17, where the predicate #> was `within' #> first 10 elements: #> 1: 1 #> 2: (empty) #> 3: 1 #> 4: 1 #> 5: 1 #> 6: 1 #> 7: (empty) #> 8: (empty) #> 9: 1 #> 10: 1 new_net = net |> activate(nodes) |> st_join(polys, join = st_within) ggraph(new_net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(label)), size = 4) + scale_colour_discrete(\"label\") + theme_void() new_net = net |> activate(nodes) |> st_filter(polys, .predicate = st_within) ggraph(new_net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() net |> activate(nodes) |> st_as_sf() |> st_buffer(250) #> Simple feature collection with 17 features and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POLYGON #> Dimension: XY #> Bounding box: xmin: 4548414 ymin: 2747059 xmax: 4549839 ymax: 2748787 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 17 × 4 #> name type website geometry #> * #> 1 Mozartkino cinema https://www.… ((4549754 2747309, 45497… #> 2 Haus für Mozart theatre NA ((4549253 2747376, 45492… #> 3 Mozartsteg/Rudolfskai bus_stop NA ((4549839 2747507, 45498… #> 4 Mozart Denkmal artwork NA ((4549637 2747514, 45496… #> 5 Mozartsteg/Rudolfskai bus_stop NA ((4549741 2747551, 45497… #> 6 Mozartsteg bridge NA ((4549723 2747624, 45497… #> 7 Mozarts Geburtshaus museum http://www.m… ((4549314 2747619, 45493… #> 8 Café Mozart cafe https://www.… ((4549244 2747632, 45492… #> 9 Mozartkugel confectionery NA ((4549370 2747654, 45493… #> 10 Mozartsteg/Imbergstraße bus_stop NA ((4549668 2747723, 45496… #> 11 Spirit of Mozart artwork https://salz… ((4549369 2747790, 45493… #> 12 Mozart-Eine Hommage artwork https://salz… ((4548914 2747868, 45489… #> 13 Mozarts Wohnhaus apartments NA ((4549323 2747916, 45493… #> 14 Universität Mozarteum university NA ((4549309 2748042, 45493… #> 15 Stiftung Mozarteum concert_hall NA ((4549147 2748037, 45491… #> 16 Hotel Mozart hotel http://www.h… ((4549628 2748391, 45496… #> 17 Mozart Studentenheim dormitory NA ((4549234 2748537, 45492… # Find shortest path between node 1 and node 17. path = st_network_paths(net, 1, 17) # Draw an isodistance polygon with 500m threshold around node 13. iso = st_network_iso(net, 13, 500) # Extract the faces of the network. faces = st_network_faces(net) # Blend external points as new nodes into the network. feats = st_sample(st_bbox(mozart), 10) blend = st_network_blend(net, feats) ggraph(net, \"sf\") + geom_edge_sf() + geom_sf(data = path, color = \"orange\", linewidth = 2) + geom_node_sf(size = 4) + geom_sf(data = st_geometry(net, \"nodes\")[c(1, 17)], size = 6) + theme_void() ggraph(net, \"sf\") + geom_sf(data = iso, fill = \"orange\", alpha = 0.7) + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = st_geometry(net, \"nodes\")[13], size = 6) + theme_void() faces_sf = st_sf(id = c(1:length(faces)), geometry = faces) ggraph(net, \"sf\") + geom_sf(data = faces_sf, aes(fill = as.factor(id)), show.legend = FALSE) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(blend, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = feats, color = \"orange\", size = 4) + geom_sf( data = st_nearest_points(feats, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + theme_void() new_net = net |> activate(edges) |> filter(edge_intersects(polys)) |> mutate(circuity = edge_circuity()) |> activate(nodes) |> mutate( sc = centrality_straightness(), in_poly = node_is_within(polys) ) new_net #> # A sfnetwork: 17 nodes and 21 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 6 (active) #> name type website geometry sc in_poly #> #> 1 Mozartkino cinema https:… (4549504 2747309) 0.847 TRUE #> 2 Haus für Mozart theatre NA (4549003 2747376) 0.648 FALSE #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 0.878 TRUE #> 4 Mozart Denkmal artwork NA (4549387 2747514) 0.850 TRUE #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 0.874 TRUE #> 6 Mozartsteg bridge NA (4549473 2747624) 0.843 TRUE #> # ℹ 11 more rows #> # #> # Edge data: 21 × 5 #> from to geometry length circuity #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. 1 #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. 1 #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. 1 #> # ℹ 18 more rows new_net = net |> activate(nodes) |> mutate(group = group_spatial_dbscan(300)) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(group)), size = 4) + scale_colour_discrete(\"group\") + theme_void() # Smooth nodes of degree 2. smooth = convert(net, to_spatial_smooth) # Subdivide edges at each interior point in the smoothed network. # In this case this is the opposite of smoothing, it adds back the degree 2 nodes. division = convert(smooth, to_spatial_subdivision, all = TRUE) # Contract nodes that are in the same spatial cluster. contraction = net |> activate(nodes) |> mutate(group = group_spatial_dbscan(300)) |> convert(to_spatial_contracted, group) # Subset the graph to only those edges in a shortest path. path = convert(net, to_spatial_shortest_paths, 1, 17) ggraph(smooth, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(division, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(contraction, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(path, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() p = st_centroid(st_combine(mozart)) nn = nearest_nodes(net, p) nn #> Simple feature collection with 1 feature and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 4549119 ymin: 2747790 xmax: 4549119 ymax: 2747790 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 4 #> name type website geometry #> #> 1 Spirit of Mozart artwork https://salzburgfoundation… (4549119 2747790) ne = nearest_edges(net, p) ne #> Simple feature collection with 1 feature and 3 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4549119 ymin: 2747723 xmax: 4549418 ymax: 2747790 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 4 #> from to geometry length #> [m] #> 1 10 11 (4549418 2747723, 4549119 2747790) 306. ggraph(net, \"sf\") + geom_sf(data = p, size = 6, pch = 8) + geom_edge_sf(color = \"grey\") + geom_node_sf(color = \"grey\", size = 4) + geom_sf(data = nn, color = \"orange\", size = 6) + theme_void() ggraph(net, \"sf\") + geom_sf(data = p, size = 6, pch = 8) + geom_edge_sf(color = \"grey\") + geom_sf(data = ne, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"grey\", size = 4) + theme_void() # Mutate. vertex_attr(net, \"label\") = letters[1:vcount(net)] # Filter. drop = which(!sample(c(TRUE, FALSE), ecount(net), replace = TRUE)) new_net = delete_edges(net, drop) new_net #> IGRAPH f481e4e UN-B 17 12 -- #> + attr: name (v/c), type (v/c), website (v/c), geometry (v/x), label #> | (v/c), geometry (e/x), length (e/n) #> + edges from f481e4e (vertex names): #> [1] Mozartkino --Mozartsteg/Rudolfskai #> [2] Haus für Mozart --Café Mozart #> [3] Mozart Denkmal --Mozartsteg/Rudolfskai #> [4] Mozarts Geburtshaus --Café Mozart #> [5] Mozartkugel --Mozartsteg/Imbergstraße #> [6] Mozartkugel --Spirit of Mozart #> [7] Mozartsteg/Imbergstraße--Spirit of Mozart #> + ... omitted several edges wrap_igraph(net, delete_edges, drop) #> # A sfnetwork: 17 nodes and 12 edges #> # #> # A bipartite simple graph with 6 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 12 × 4 (active) #> from to geometry length #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. #> 2 2 8 (4549003 2747376, 4548994 2747632) 256. #> 3 4 5 (4549387 2747514, 4549491 2747551) 110. #> 4 7 8 (4549064 2747619, 4548994 2747632) 71.1 #> 5 9 10 (4549120 2747654, 4549418 2747723) 305. #> 6 9 11 (4549120 2747654, 4549119 2747790) 136. #> # ℹ 6 more rows #> # #> # Node data: 17 × 5 #> name type website geometry label #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) a #> 2 Haus für Mozart theatre NA (4549003 2747376) b #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) c #> # ℹ 14 more rows mst = wrap_igraph(net, mst, weights = edge_attr(net, \"length\")) ggraph(mst, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() with_graph(net, edge_circuity()) #> [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"network-analysis-with-tidygraph","dir":"Articles","previous_headings":"","what":"Network analysis with tidygraph","title":"Introduction to sfnetworks","text":"allow performing common network analysis tasks, sfnetworks builds upon tidygraph. Since sfnetwork objects inherit tbl_graph class, analytical functions tidygraph can directly used. lot functions available, tidy wrappers around functions igraph library. complete overview, check tidygraph documentation. important note case spatial networks often makes sense use geographic length edge weight. Since tidygraph know space, never set automatically, explicitly specify every time call function can consider edge weights. Read specifying edge weights vignette Routing spatial networks. large set functions tidygraph dedicated computation quantitative measures nodes, edges, network whole. known centrality measures, define importance node network. names implemented centrality measure functions formatted centrality_*. implemented measure functions names formatted node_* (node measures) edge_* (edge measures) graph_* (network measures). special group measure functions logical measures, return either TRUE FALSE, indicating node, edge network specified type. None functions meant called directly, used inside tidyverse-verbs dplyr::mutate() dplyr::filter(), analyzed network know thus needed input function. tidygraph::with_graph() can used evaluate measure context specific network, outside tidyverse framework. Another set functions tidygraph deals community detection networks. functions group nodes edges based clustering algorithm. names formatted group_*, always return vector group indices, one feature. implemented algorithms try create groups nodes number edges within groups relatively high compared number edges groups, example . note algorithms generally designed account spatial factors, may limited use working spatial networks. Finally, tidygraph introduced new set network analysis functions call morphers. Morphers change structure input graph, example subsetting splitting , combining multiple features one, converting nodes edges vice versa. different struture needed computations, can set temporarily providing morphers subsequently tidygraph::morph() tidygraph::unmorph() verbs. different structure meant last, morpher can provided tidygraph::convert() verb instead. example convert network minimum spanning tree, contains minimum set edges need nodes still connected like .","code":"net = net |> activate(edges) |> mutate(length = edge_length()) net #> # A sfnetwork: 17 nodes and 25 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 25 × 4 (active) #> from to geometry length #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. #> 4 2 7 (4549003 2747376, 4549064 2747619) 250. #> 5 2 8 (4549003 2747376, 4548994 2747632) 256. #> 6 3 5 (4549589 2747507, 4549491 2747551) 107. #> # ℹ 19 more rows #> # #> # Node data: 17 × 4 #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> # ℹ 14 more rows new_net = net |> activate(edges) |> filter(!edge_is_incident(13)) |> activate(nodes) |> mutate(bc = centrality_betweenness(weights = length)) new_net #> # A sfnetwork: 17 nodes and 23 edges #> # #> # A bipartite simple graph with 2 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 5 (active) #> name type website geometry bc #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) 0 #> 2 Haus für Mozart theatre NA (4549003 2747376) 0 #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 5 #> 4 Mozart Denkmal artwork NA (4549387 2747514) 21 #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 22 #> 6 Mozartsteg bridge NA (4549473 2747624) 16 #> # ℹ 11 more rows #> # #> # Edge data: 23 × 4 #> from to geometry length #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. #> # ℹ 20 more rows ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(size = bc)) + theme_void() with_graph(net, centrality_degree()) |> setNames(NULL) #> [1] 2 3 2 4 3 2 3 3 4 4 3 2 2 4 3 3 3 new_net = net |> activate(nodes) |> mutate(group = group_optimal()) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(group)), size = 4) + scale_colour_discrete(\"group\") + theme_void() new_net = net |> convert(to_minimum_spanning_tree, weights = length) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"measures","dir":"Articles","previous_headings":"","what":"Measures","title":"Introduction to sfnetworks","text":"large set functions tidygraph dedicated computation quantitative measures nodes, edges, network whole. known centrality measures, define importance node network. names implemented centrality measure functions formatted centrality_*. implemented measure functions names formatted node_* (node measures) edge_* (edge measures) graph_* (network measures). special group measure functions logical measures, return either TRUE FALSE, indicating node, edge network specified type. None functions meant called directly, used inside tidyverse-verbs dplyr::mutate() dplyr::filter(), analyzed network know thus needed input function. tidygraph::with_graph() can used evaluate measure context specific network, outside tidyverse framework.","code":"new_net = net |> activate(edges) |> filter(!edge_is_incident(13)) |> activate(nodes) |> mutate(bc = centrality_betweenness(weights = length)) new_net #> # A sfnetwork: 17 nodes and 23 edges #> # #> # A bipartite simple graph with 2 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 5 (active) #> name type website geometry bc #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) 0 #> 2 Haus für Mozart theatre NA (4549003 2747376) 0 #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 5 #> 4 Mozart Denkmal artwork NA (4549387 2747514) 21 #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 22 #> 6 Mozartsteg bridge NA (4549473 2747624) 16 #> # ℹ 11 more rows #> # #> # Edge data: 23 × 4 #> from to geometry length #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. #> # ℹ 20 more rows ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(size = bc)) + theme_void() with_graph(net, centrality_degree()) |> setNames(NULL) #> [1] 2 3 2 4 3 2 3 3 4 4 3 2 2 4 3 3 3"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"community-detection","dir":"Articles","previous_headings":"","what":"Community detection","title":"Introduction to sfnetworks","text":"Another set functions tidygraph deals community detection networks. functions group nodes edges based clustering algorithm. names formatted group_*, always return vector group indices, one feature. implemented algorithms try create groups nodes number edges within groups relatively high compared number edges groups, example . note algorithms generally designed account spatial factors, may limited use working spatial networks.","code":"new_net = net |> activate(nodes) |> mutate(group = group_optimal()) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(group)), size = 4) + scale_colour_discrete(\"group\") + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"morphers","dir":"Articles","previous_headings":"","what":"Morphers","title":"Introduction to sfnetworks","text":"Finally, tidygraph introduced new set network analysis functions call morphers. Morphers change structure input graph, example subsetting splitting , combining multiple features one, converting nodes edges vice versa. different struture needed computations, can set temporarily providing morphers subsequently tidygraph::morph() tidygraph::unmorph() verbs. different structure meant last, morpher can provided tidygraph::convert() verb instead. example convert network minimum spanning tree, contains minimum set edges need nodes still connected like .","code":"new_net = net |> convert(to_minimum_spanning_tree, weights = length) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"spatial-analysis-with-sf","dir":"Articles","previous_headings":"","what":"Spatial analysis with sf","title":"Introduction to sfnetworks","text":"writing methods many spatial analytical functions sf package, sfnetworks allows functions called directly sfnetwork objects, without need conversion. See overview sf functions method sfnetwork objects. complete overview functionalities sf, check sf documentation. One many tasks sf covers specification coordinate reference systems, CRS short, transformation spatial coordinates systems. sfnetwork object nodes edges always CRS, matter elements active retrieve CRS, transform coordinates different CRS. sf also multiple functions implement evaluation spatial predicate. spatial predicate describes spatial relation two geometries. example, point may located within polygon B. example show evaluate node spatial network located within one two given polygons. using spatial predicates, sf offers ability perform spatial joins spatial filters. Spatial joins join information spatial feature features specified spatial relation . Spatial filters keep features specified spatial relation, removes . details spatial joins filters spatial networks, see vignette Spatial joins filters. Finally, sf contains group functions known geometric unary operations. functions change structure individual geometries. usage context spatial networks limited, since many break network structure endpoints edges spatially equal respective nodes. Hence, geometric unary operations change type, shape, position geometries method sfnetwork objects. include sf::st_reverse() reverse edge geometries, sf::st_segmentize() add interior points edge geometries. However, just unsupported tidyverse-verbs, can still apply unsupported geometric unary operations first extracting active element sf object, proceed analysis single table.","code":"st_crs(net)$epsg #> [1] 3035 st_transform(net, 4326) #> # A sfnetwork: 17 nodes and 25 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 13.03835 ymin: 47.79698 xmax: 13.05049 ymax: 47.80822 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 25 × 4 (active) #> from to geometry length #> [m] #> 1 1 3 (13.04925 47.79698, 13.05049 47.79874) 216. #> 2 1 4 (13.04925 47.79698, 13.04781 47.79887) 236. #> 3 2 4 (13.0426 47.79778, 13.04781 47.79887) 409. #> 4 2 7 (13.0426 47.79778, 13.04355 47.79993) 250. #> 5 2 8 (13.0426 47.79778, 13.04263 47.80008) 256. #> 6 3 5 (13.05049 47.79874, 13.04921 47.79917) 107. #> # ℹ 19 more rows #> # #> # Node data: 17 × 4 #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (13.04925 47.79698) #> 2 Haus für Mozart theatre NA (13.0426 47.79778) #> 3 Mozartsteg/Rudolfskai bus_stop NA (13.05049 47.79874) #> # ℹ 14 more rows polys = mozart |> slice(4, 15) |> st_buffer(325) |> mutate(label = c(\"A\", \"B\")) |> select(label) ggraph(net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() net |> activate(nodes) |> st_within(polys) #> Sparse geometry binary predicate list of length 17, where the predicate #> was `within' #> first 10 elements: #> 1: 1 #> 2: (empty) #> 3: 1 #> 4: 1 #> 5: 1 #> 6: 1 #> 7: (empty) #> 8: (empty) #> 9: 1 #> 10: 1 new_net = net |> activate(nodes) |> st_join(polys, join = st_within) ggraph(new_net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(label)), size = 4) + scale_colour_discrete(\"label\") + theme_void() new_net = net |> activate(nodes) |> st_filter(polys, .predicate = st_within) ggraph(new_net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() net |> activate(nodes) |> st_as_sf() |> st_buffer(250) #> Simple feature collection with 17 features and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POLYGON #> Dimension: XY #> Bounding box: xmin: 4548414 ymin: 2747059 xmax: 4549839 ymax: 2748787 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 17 × 4 #> name type website geometry #> * #> 1 Mozartkino cinema https://www.… ((4549754 2747309, 45497… #> 2 Haus für Mozart theatre NA ((4549253 2747376, 45492… #> 3 Mozartsteg/Rudolfskai bus_stop NA ((4549839 2747507, 45498… #> 4 Mozart Denkmal artwork NA ((4549637 2747514, 45496… #> 5 Mozartsteg/Rudolfskai bus_stop NA ((4549741 2747551, 45497… #> 6 Mozartsteg bridge NA ((4549723 2747624, 45497… #> 7 Mozarts Geburtshaus museum http://www.m… ((4549314 2747619, 45493… #> 8 Café Mozart cafe https://www.… ((4549244 2747632, 45492… #> 9 Mozartkugel confectionery NA ((4549370 2747654, 45493… #> 10 Mozartsteg/Imbergstraße bus_stop NA ((4549668 2747723, 45496… #> 11 Spirit of Mozart artwork https://salz… ((4549369 2747790, 45493… #> 12 Mozart-Eine Hommage artwork https://salz… ((4548914 2747868, 45489… #> 13 Mozarts Wohnhaus apartments NA ((4549323 2747916, 45493… #> 14 Universität Mozarteum university NA ((4549309 2748042, 45493… #> 15 Stiftung Mozarteum concert_hall NA ((4549147 2748037, 45491… #> 16 Hotel Mozart hotel http://www.h… ((4549628 2748391, 45496… #> 17 Mozart Studentenheim dormitory NA ((4549234 2748537, 45492…"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"coordinate-reference-systems","dir":"Articles","previous_headings":"","what":"Coordinate reference systems","title":"Introduction to sfnetworks","text":"One many tasks sf covers specification coordinate reference systems, CRS short, transformation spatial coordinates systems. sfnetwork object nodes edges always CRS, matter elements active retrieve CRS, transform coordinates different CRS.","code":"st_crs(net)$epsg #> [1] 3035 st_transform(net, 4326) #> # A sfnetwork: 17 nodes and 25 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 13.03835 ymin: 47.79698 xmax: 13.05049 ymax: 47.80822 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 25 × 4 (active) #> from to geometry length #> [m] #> 1 1 3 (13.04925 47.79698, 13.05049 47.79874) 216. #> 2 1 4 (13.04925 47.79698, 13.04781 47.79887) 236. #> 3 2 4 (13.0426 47.79778, 13.04781 47.79887) 409. #> 4 2 7 (13.0426 47.79778, 13.04355 47.79993) 250. #> 5 2 8 (13.0426 47.79778, 13.04263 47.80008) 256. #> 6 3 5 (13.05049 47.79874, 13.04921 47.79917) 107. #> # ℹ 19 more rows #> # #> # Node data: 17 × 4 #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (13.04925 47.79698) #> 2 Haus für Mozart theatre NA (13.0426 47.79778) #> 3 Mozartsteg/Rudolfskai bus_stop NA (13.05049 47.79874) #> # ℹ 14 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"spatial-predicates","dir":"Articles","previous_headings":"","what":"Spatial predicates","title":"Introduction to sfnetworks","text":"sf also multiple functions implement evaluation spatial predicate. spatial predicate describes spatial relation two geometries. example, point may located within polygon B. example show evaluate node spatial network located within one two given polygons.","code":"polys = mozart |> slice(4, 15) |> st_buffer(325) |> mutate(label = c(\"A\", \"B\")) |> select(label) ggraph(net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() net |> activate(nodes) |> st_within(polys) #> Sparse geometry binary predicate list of length 17, where the predicate #> was `within' #> first 10 elements: #> 1: 1 #> 2: (empty) #> 3: 1 #> 4: 1 #> 5: 1 #> 6: 1 #> 7: (empty) #> 8: (empty) #> 9: 1 #> 10: 1"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"spatial-joins-and-filters","dir":"Articles","previous_headings":"","what":"Spatial joins and filters","title":"Introduction to sfnetworks","text":"using spatial predicates, sf offers ability perform spatial joins spatial filters. Spatial joins join information spatial feature features specified spatial relation . Spatial filters keep features specified spatial relation, removes . details spatial joins filters spatial networks, see vignette Spatial joins filters.","code":"new_net = net |> activate(nodes) |> st_join(polys, join = st_within) ggraph(new_net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(label)), size = 4) + scale_colour_discrete(\"label\") + theme_void() new_net = net |> activate(nodes) |> st_filter(polys, .predicate = st_within) ggraph(new_net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"geometric-unary-operations","dir":"Articles","previous_headings":"","what":"Geometric unary operations","title":"Introduction to sfnetworks","text":"Finally, sf contains group functions known geometric unary operations. functions change structure individual geometries. usage context spatial networks limited, since many break network structure endpoints edges spatially equal respective nodes. Hence, geometric unary operations change type, shape, position geometries method sfnetwork objects. include sf::st_reverse() reverse edge geometries, sf::st_segmentize() add interior points edge geometries. However, just unsupported tidyverse-verbs, can still apply unsupported geometric unary operations first extracting active element sf object, proceed analysis single table.","code":"net |> activate(nodes) |> st_as_sf() |> st_buffer(250) #> Simple feature collection with 17 features and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POLYGON #> Dimension: XY #> Bounding box: xmin: 4548414 ymin: 2747059 xmax: 4549839 ymax: 2748787 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 17 × 4 #> name type website geometry #> * #> 1 Mozartkino cinema https://www.… ((4549754 2747309, 45497… #> 2 Haus für Mozart theatre NA ((4549253 2747376, 45492… #> 3 Mozartsteg/Rudolfskai bus_stop NA ((4549839 2747507, 45498… #> 4 Mozart Denkmal artwork NA ((4549637 2747514, 45496… #> 5 Mozartsteg/Rudolfskai bus_stop NA ((4549741 2747551, 45497… #> 6 Mozartsteg bridge NA ((4549723 2747624, 45497… #> 7 Mozarts Geburtshaus museum http://www.m… ((4549314 2747619, 45493… #> 8 Café Mozart cafe https://www.… ((4549244 2747632, 45492… #> 9 Mozartkugel confectionery NA ((4549370 2747654, 45493… #> 10 Mozartsteg/Imbergstraße bus_stop NA ((4549668 2747723, 45496… #> 11 Spirit of Mozart artwork https://salz… ((4549369 2747790, 45493… #> 12 Mozart-Eine Hommage artwork https://salz… ((4548914 2747868, 45489… #> 13 Mozarts Wohnhaus apartments NA ((4549323 2747916, 45493… #> 14 Universität Mozarteum university NA ((4549309 2748042, 45493… #> 15 Stiftung Mozarteum concert_hall NA ((4549147 2748037, 45491… #> 16 Hotel Mozart hotel http://www.h… ((4549628 2748391, 45496… #> 17 Mozart Studentenheim dormitory NA ((4549234 2748537, 45492…"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"spatial-network-specific-additions","dir":"Articles","previous_headings":"","what":"Spatial network specific additions","title":"Introduction to sfnetworks","text":"mentioned, sfnetworks extends functionalities tidygraph sf offering functions specific spatial network analysis, well functions allow smoother integration sf design tidygraph workflows. contradiction tidygraph, functions sfnetworks consider edge weights always use geographic edge length default weight. first family functions sfnetworks names formatted st_network_*, adopting naming conventions sf. functions take spatial network first input implement analysis task involves network set regular spatial simple features (points, lines, polygons). returned object can either set spatial simple features computed network, network spatial features merged , another object (e.g., matrix) result computation relating network spatial features. covers large range use-cases. Examples include drawing isochrone isodistance polygons around nodes, finding geographic shortest paths pairs nodes, computing cost matrices travel nodes, extracting faces network, adding external point data new nodes network. vignettes find details functions. also functions sfnetworks start st_*, end *_network. contradiction st_network_* functions, functions take set spatial features first input, network additional argument. example st_project_on_network, projects points onto network. Shortest path Isodistance polygon Network faces Blended points extension measure functions tidygraph, several spatial measure functions nodes edges found sfnetworks. Just tidygraph, functions named style node_* edge_*, centrality measure, centrality_*. Edge measures can computed include example geographic length edge, azimuth, circuity (.e. ratio geographic length shortest euclidean distance source target node). nodes, example possible compute straightness centrality (.e. average ratio euclidean distance network distance node nodes network). better integrate spatial predicate functions sf design tidygraph, applicable predicates also implemented node edge measure function. functions return TRUE node edge specified spatial relation least one given spatial features, FALSE otherwise. makes easy use predicates directly inside functions dplyr::filter() dplyr::mutate(). extension community detection functions tidygraph, sfnetworks contains group_spatial_dbscan() function find spatial clusters nodes. idea offer multiple spatial clustering algorithms choose , currently one implemented DBSCAN algorithm (require dbscan package installed). algorithm executed network distance matrix nodes, euclidean distance matrix. extension morpher functions tidygraph, many different spatial morpher functions implemented sfnetworks. Just tidygraph, function change structure input network, example subsetting splitting , combining multiple features one, splitting single features. Common examples include subdividing network interior points edge geometries, smoothing pseudo nodes degree 2, contracting multiple nodes one preserving network connectivity. vignettes find details functions. Many morphers used network cleaning operations, described detail vignette Cleaning spatial networks. Smooth network Subdivision smooth network Contracted groups nodes single path Finally, sfnetworks exports kind utility functions make working spatial networks less cumbersome. example finding nearest node nearest edge given spatial feature. overview exported functions package, see function reference. Nearest node Nearest edge","code":"# Find shortest path between node 1 and node 17. path = st_network_paths(net, 1, 17) # Draw an isodistance polygon with 500m threshold around node 13. iso = st_network_iso(net, 13, 500) # Extract the faces of the network. faces = st_network_faces(net) # Blend external points as new nodes into the network. feats = st_sample(st_bbox(mozart), 10) blend = st_network_blend(net, feats) ggraph(net, \"sf\") + geom_edge_sf() + geom_sf(data = path, color = \"orange\", linewidth = 2) + geom_node_sf(size = 4) + geom_sf(data = st_geometry(net, \"nodes\")[c(1, 17)], size = 6) + theme_void() ggraph(net, \"sf\") + geom_sf(data = iso, fill = \"orange\", alpha = 0.7) + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = st_geometry(net, \"nodes\")[13], size = 6) + theme_void() faces_sf = st_sf(id = c(1:length(faces)), geometry = faces) ggraph(net, \"sf\") + geom_sf(data = faces_sf, aes(fill = as.factor(id)), show.legend = FALSE) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(blend, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = feats, color = \"orange\", size = 4) + geom_sf( data = st_nearest_points(feats, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + theme_void() new_net = net |> activate(edges) |> filter(edge_intersects(polys)) |> mutate(circuity = edge_circuity()) |> activate(nodes) |> mutate( sc = centrality_straightness(), in_poly = node_is_within(polys) ) new_net #> # A sfnetwork: 17 nodes and 21 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 6 (active) #> name type website geometry sc in_poly #> #> 1 Mozartkino cinema https:… (4549504 2747309) 0.847 TRUE #> 2 Haus für Mozart theatre NA (4549003 2747376) 0.648 FALSE #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 0.878 TRUE #> 4 Mozart Denkmal artwork NA (4549387 2747514) 0.850 TRUE #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 0.874 TRUE #> 6 Mozartsteg bridge NA (4549473 2747624) 0.843 TRUE #> # ℹ 11 more rows #> # #> # Edge data: 21 × 5 #> from to geometry length circuity #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. 1 #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. 1 #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. 1 #> # ℹ 18 more rows new_net = net |> activate(nodes) |> mutate(group = group_spatial_dbscan(300)) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(group)), size = 4) + scale_colour_discrete(\"group\") + theme_void() # Smooth nodes of degree 2. smooth = convert(net, to_spatial_smooth) # Subdivide edges at each interior point in the smoothed network. # In this case this is the opposite of smoothing, it adds back the degree 2 nodes. division = convert(smooth, to_spatial_subdivision, all = TRUE) # Contract nodes that are in the same spatial cluster. contraction = net |> activate(nodes) |> mutate(group = group_spatial_dbscan(300)) |> convert(to_spatial_contracted, group) # Subset the graph to only those edges in a shortest path. path = convert(net, to_spatial_shortest_paths, 1, 17) ggraph(smooth, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(division, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(contraction, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(path, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() p = st_centroid(st_combine(mozart)) nn = nearest_nodes(net, p) nn #> Simple feature collection with 1 feature and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 4549119 ymin: 2747790 xmax: 4549119 ymax: 2747790 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 4 #> name type website geometry #> #> 1 Spirit of Mozart artwork https://salzburgfoundation… (4549119 2747790) ne = nearest_edges(net, p) ne #> Simple feature collection with 1 feature and 3 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4549119 ymin: 2747723 xmax: 4549418 ymax: 2747790 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 4 #> from to geometry length #> [m] #> 1 10 11 (4549418 2747723, 4549119 2747790) 306. ggraph(net, \"sf\") + geom_sf(data = p, size = 6, pch = 8) + geom_edge_sf(color = \"grey\") + geom_node_sf(color = \"grey\", size = 4) + geom_sf(data = nn, color = \"orange\", size = 6) + theme_void() ggraph(net, \"sf\") + geom_sf(data = p, size = 6, pch = 8) + geom_edge_sf(color = \"grey\") + geom_sf(data = ne, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"grey\", size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"relating-networks-and-spatial-simple-features","dir":"Articles","previous_headings":"","what":"Relating networks and spatial simple features","title":"Introduction to sfnetworks","text":"first family functions sfnetworks names formatted st_network_*, adopting naming conventions sf. functions take spatial network first input implement analysis task involves network set regular spatial simple features (points, lines, polygons). returned object can either set spatial simple features computed network, network spatial features merged , another object (e.g., matrix) result computation relating network spatial features. covers large range use-cases. Examples include drawing isochrone isodistance polygons around nodes, finding geographic shortest paths pairs nodes, computing cost matrices travel nodes, extracting faces network, adding external point data new nodes network. vignettes find details functions. also functions sfnetworks start st_*, end *_network. contradiction st_network_* functions, functions take set spatial features first input, network additional argument. example st_project_on_network, projects points onto network. Shortest path Isodistance polygon Network faces Blended points","code":"# Find shortest path between node 1 and node 17. path = st_network_paths(net, 1, 17) # Draw an isodistance polygon with 500m threshold around node 13. iso = st_network_iso(net, 13, 500) # Extract the faces of the network. faces = st_network_faces(net) # Blend external points as new nodes into the network. feats = st_sample(st_bbox(mozart), 10) blend = st_network_blend(net, feats) ggraph(net, \"sf\") + geom_edge_sf() + geom_sf(data = path, color = \"orange\", linewidth = 2) + geom_node_sf(size = 4) + geom_sf(data = st_geometry(net, \"nodes\")[c(1, 17)], size = 6) + theme_void() ggraph(net, \"sf\") + geom_sf(data = iso, fill = \"orange\", alpha = 0.7) + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = st_geometry(net, \"nodes\")[13], size = 6) + theme_void() faces_sf = st_sf(id = c(1:length(faces)), geometry = faces) ggraph(net, \"sf\") + geom_sf(data = faces_sf, aes(fill = as.factor(id)), show.legend = FALSE) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(blend, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = feats, color = \"orange\", size = 4) + geom_sf( data = st_nearest_points(feats, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"spatial-measures","dir":"Articles","previous_headings":"","what":"Spatial measures","title":"Introduction to sfnetworks","text":"extension measure functions tidygraph, several spatial measure functions nodes edges found sfnetworks. Just tidygraph, functions named style node_* edge_*, centrality measure, centrality_*. Edge measures can computed include example geographic length edge, azimuth, circuity (.e. ratio geographic length shortest euclidean distance source target node). nodes, example possible compute straightness centrality (.e. average ratio euclidean distance network distance node nodes network). better integrate spatial predicate functions sf design tidygraph, applicable predicates also implemented node edge measure function. functions return TRUE node edge specified spatial relation least one given spatial features, FALSE otherwise. makes easy use predicates directly inside functions dplyr::filter() dplyr::mutate().","code":"new_net = net |> activate(edges) |> filter(edge_intersects(polys)) |> mutate(circuity = edge_circuity()) |> activate(nodes) |> mutate( sc = centrality_straightness(), in_poly = node_is_within(polys) ) new_net #> # A sfnetwork: 17 nodes and 21 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 6 (active) #> name type website geometry sc in_poly #> #> 1 Mozartkino cinema https:… (4549504 2747309) 0.847 TRUE #> 2 Haus für Mozart theatre NA (4549003 2747376) 0.648 FALSE #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 0.878 TRUE #> 4 Mozart Denkmal artwork NA (4549387 2747514) 0.850 TRUE #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 0.874 TRUE #> 6 Mozartsteg bridge NA (4549473 2747624) 0.843 TRUE #> # ℹ 11 more rows #> # #> # Edge data: 21 × 5 #> from to geometry length circuity #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. 1 #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. 1 #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. 1 #> # ℹ 18 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"spatial-clustering","dir":"Articles","previous_headings":"","what":"Spatial clustering","title":"Introduction to sfnetworks","text":"extension community detection functions tidygraph, sfnetworks contains group_spatial_dbscan() function find spatial clusters nodes. idea offer multiple spatial clustering algorithms choose , currently one implemented DBSCAN algorithm (require dbscan package installed). algorithm executed network distance matrix nodes, euclidean distance matrix.","code":"new_net = net |> activate(nodes) |> mutate(group = group_spatial_dbscan(300)) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(group)), size = 4) + scale_colour_discrete(\"group\") + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"spatial-morphers","dir":"Articles","previous_headings":"","what":"Spatial morphers","title":"Introduction to sfnetworks","text":"extension morpher functions tidygraph, many different spatial morpher functions implemented sfnetworks. Just tidygraph, function change structure input network, example subsetting splitting , combining multiple features one, splitting single features. Common examples include subdividing network interior points edge geometries, smoothing pseudo nodes degree 2, contracting multiple nodes one preserving network connectivity. vignettes find details functions. Many morphers used network cleaning operations, described detail vignette Cleaning spatial networks. Smooth network Subdivision smooth network Contracted groups nodes single path","code":"# Smooth nodes of degree 2. smooth = convert(net, to_spatial_smooth) # Subdivide edges at each interior point in the smoothed network. # In this case this is the opposite of smoothing, it adds back the degree 2 nodes. division = convert(smooth, to_spatial_subdivision, all = TRUE) # Contract nodes that are in the same spatial cluster. contraction = net |> activate(nodes) |> mutate(group = group_spatial_dbscan(300)) |> convert(to_spatial_contracted, group) # Subset the graph to only those edges in a shortest path. path = convert(net, to_spatial_shortest_paths, 1, 17) ggraph(smooth, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(division, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(contraction, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(path, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"utilities","dir":"Articles","previous_headings":"","what":"Utilities","title":"Introduction to sfnetworks","text":"Finally, sfnetworks exports kind utility functions make working spatial networks less cumbersome. example finding nearest node nearest edge given spatial feature. overview exported functions package, see function reference. Nearest node Nearest edge","code":"p = st_centroid(st_combine(mozart)) nn = nearest_nodes(net, p) nn #> Simple feature collection with 1 feature and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 4549119 ymin: 2747790 xmax: 4549119 ymax: 2747790 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 4 #> name type website geometry #> #> 1 Spirit of Mozart artwork https://salzburgfoundation… (4549119 2747790) ne = nearest_edges(net, p) ne #> Simple feature collection with 1 feature and 3 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4549119 ymin: 2747723 xmax: 4549418 ymax: 2747790 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 4 #> from to geometry length #> [m] #> 1 10 11 (4549418 2747723, 4549119 2747790) 306. ggraph(net, \"sf\") + geom_sf(data = p, size = 6, pch = 8) + geom_edge_sf(color = \"grey\") + geom_node_sf(color = \"grey\", size = 4) + geom_sf(data = nn, color = \"orange\", size = 6) + theme_void() ggraph(net, \"sf\") + geom_sf(data = p, size = 6, pch = 8) + geom_edge_sf(color = \"grey\") + geom_sf(data = ne, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"grey\", size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"non-tidyverse-workflows","dir":"Articles","previous_headings":"","what":"Non-tidyverse workflows","title":"Introduction to sfnetworks","text":"Also fan tidyverse style data analysis, sfnetworks can . Since sfnetwork objects inherit igraph class, can apply functions large igraph package . means, example, instead using dplyr::mutate() dplyr::filter(), proceed follows (note igraph, term vertex used instead node). can see, returns igraph object instead sfnetwork object. preserve class, can use wrap_igraph() function sfnetworks igraph function accepts network first input returns another network. function check returned network still spatial. spatial measure functions can evaluated outside tidygraph framework using with_graph(), works similar base R’s () function. spatial morpher functions implement larger workflow internal workers exported, meaning can called directly outside tidygraph::morph() tidygraph::convert() verbs. morphers easy replicate using sf sfnetworks functions directly.","code":"# Mutate. vertex_attr(net, \"label\") = letters[1:vcount(net)] # Filter. drop = which(!sample(c(TRUE, FALSE), ecount(net), replace = TRUE)) new_net = delete_edges(net, drop) new_net #> IGRAPH f481e4e UN-B 17 12 -- #> + attr: name (v/c), type (v/c), website (v/c), geometry (v/x), label #> | (v/c), geometry (e/x), length (e/n) #> + edges from f481e4e (vertex names): #> [1] Mozartkino --Mozartsteg/Rudolfskai #> [2] Haus für Mozart --Café Mozart #> [3] Mozart Denkmal --Mozartsteg/Rudolfskai #> [4] Mozarts Geburtshaus --Café Mozart #> [5] Mozartkugel --Mozartsteg/Imbergstraße #> [6] Mozartkugel --Spirit of Mozart #> [7] Mozartsteg/Imbergstraße--Spirit of Mozart #> + ... omitted several edges wrap_igraph(net, delete_edges, drop) #> # A sfnetwork: 17 nodes and 12 edges #> # #> # A bipartite simple graph with 6 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 12 × 4 (active) #> from to geometry length #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. #> 2 2 8 (4549003 2747376, 4548994 2747632) 256. #> 3 4 5 (4549387 2747514, 4549491 2747551) 110. #> 4 7 8 (4549064 2747619, 4548994 2747632) 71.1 #> 5 9 10 (4549120 2747654, 4549418 2747723) 305. #> 6 9 11 (4549120 2747654, 4549119 2747790) 136. #> # ℹ 6 more rows #> # #> # Node data: 17 × 5 #> name type website geometry label #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) a #> 2 Haus für Mozart theatre NA (4549003 2747376) b #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) c #> # ℹ 14 more rows mst = wrap_igraph(net, mst, weights = edge_attr(net, \"length\")) ggraph(mst, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() with_graph(net, edge_circuity()) #> [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"visualizing-spatial-networks","dir":"Articles","previous_headings":"","what":"Visualizing spatial networks","title":"Introduction to sfnetworks","text":"quickly visualize network can use plot() method sfnetwork objects. use sf plot geometries nodes edges one view. Using regular arguments plot(), can change style plot whole. Arguments node_args edge_args added can also provide style settings nodes edges separately, list-format. Default settings Custom settings Custom settings advanced visualizations, recommend use ggraph. extension {ggplot} network data works seamlessly tbl_graph data structures. fact, tidygraph initially developed idea provide suitable data structure ggraph visualizations. now also native support sfnetworks sf layout ggraph::geom_node_sf() ggraph::geom_edge_sf() geoms aware spatial nature data. Edges can also plotted without spatial embedding, using one many geoms offerend ggraph. plot additional spatial layers networks, can simply use ggplot::geom_sf(). details, check ggraph documentation. Default settings Custom settings Custom settings Additional layers want create Leaflet-based interactive maps, take look packages mapview tmap. well integrated sf, can extract nodes edges network, plot two separate layers.","code":"plot(mst) plot(mst, col = \"orange\", pch = 8, cex = 4) plot( mst, node_args = list(col = \"orange\", cex = 3), edge_args = list(col = \"grey\", lwd = 2) ) ggraph(mst, \"sf\") + geom_edge_sf() + geom_node_sf() + theme_void() ggraph(mst, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(type)), size = 4) + scale_color_discrete(\"type\") + theme_void() ggraph(mst, \"sf\") + geom_edge_fan(aes(alpha = after_stat(index)), show.legend = FALSE) + geom_node_sf(aes(size = centrality_degree()), color = \"orange\") + theme_void() ggraph(mst, \"sf\") + geom_edge_sf(color = \"grey\") + geom_node_sf(color = \"orange\", size = 4) + geom_sf( data = st_buffer(st_centroid(st_combine(mozart)), 300), fill = \"skyblue\", alpha = 0.5, linewidth = 0.8 ) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"learning-more","dir":"Articles","previous_headings":"","what":"Learning more","title":"Introduction to sfnetworks","text":"vignette provided introduction sfnetworks. documentation contains several vignettes dive detail: Creating representing spatial networks Cleaning spatial networks Spatial joins filters Routing spatial networks","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"the-sfnetwork-class","dir":"Articles","previous_headings":"","what":"The sfnetwork class","title":"Creating and representing spatial networks","text":"Spatial networks sfnetworks represented objects class sfnetwork. objects inherit tbl_graph class tidygraph, turn inherit igraph class igraph. means core designed store graph structures. However, thanks design tidygraph, look like collection two flat tables: one nodes, one edges. documentation tidygraph, design choice explained follows. Relational data meaningful way encoded single tidy data frame. hand, node edge data fits well within tidy concept node edge , sense, single observation. Thus, close approximation tidyness relational data two tidy data frames, one describing node data one describing edge data. Since sfnetwork class inherits tbl_graph class, shares philosophy. However, extends domain geospatial data analysis, observation location geographical space. , brings sf game. object class sf stores geographical coordinates observation standardized format geometry list-column, coordinate reference system (CRS) associated . Thus, sfnetworks, re-formulate last sentence paragraph following. close approximation tidyness relational geospatial data two sf objects, one describing node data one describing edge data. Obviously network just list two distinct elements. Nodes edges related . first two columns edges table always named contain integer indices source target node edge. integer indices correspond rownumbers nodes table. , nodes filtered, order changes, indices updated. geometries nodes edges also match. sfnetworks, following requirements specified valid geospatial network: Nodes geometries type POINT. Edges geometries type LINESTRING. endpoints edge geometries spatially equal corresponding node geometries. Nodes edge geometries coordinate reference system coordinate precision. need make note . geospatial network, nodes always coordinates geographic space, thus, can always described sf object. edges, however, can also described indices nodes ends. still makes geospatial, connect two specific points space, spatial information explicitly attached . representations can useful. geolocated social networks, example, often explicit spatial embedding edges. road networks, however, edges usually straight lines, geometries stored explicitly. sfnetworks variants supported: edges can described sf object geometries, also regular tibble without geometry column. refer spatially explicit edges spatially implicit edges, respectively. documentation, however, focus first type. figure summarizes structure sfnetwork objects. Just like tbl_graph objects, always one element (nodes edges) sfnetwork object active. means element main target analysis. default, nodes active element creating network. active element can changed using activate() verb, also change order elements printed. practice, looks follows. Note create network set spatial lines, creating nodes endpoints. See section Creating sfnetwork objects many examples create spatial network. Spatially explicit edges Spatially implicit edges sfnetwork objects possible represent networks directed edges, undirected edges. also possible mimic mixed representations edge types exist. default instance sfnetwork class initialized directed network. means edge can traveled source node target node, vice versa. case, geometry edge always matches direction, startpoint line location source node, endpoint line location target node. sfnetwork data structure also supports undirected networks. networks edge can traveled directions. Since clear source target, node lowest index referenced column, node highest index column. linestring geometry, however, remains unchanged. , undirected networks specified source node may always correspond startpoint edge geometry, instead endpoint. behavior ordering indices comes igraph might confusing, remember undirected networks terms meaning can thus used interchangeably. computation really need edge geometries match specified node indices, can use utility function make_edges_follow_indices(). function reverse edge geometries needed. sfnetworks native support represent mixed networks, .e. networks edges can traveled ways, others one way. However, type networks quite common applications spatial network analysis. example, road networks streets oneway streets. creating directed network, duplicating reversing edges undirected, can mimic mixed network structure. morpher to_spatial_mixed() exactly . Since network cleaning functions work well duplicated reversed edges, usually good idea first create directed network, clean , mimic mixed representation. makes sfnetwork objects different tbl_graph objects nodes (optionally) edges geometries. geometries stored geometry list-column, following design sf. also means just sf, columns “sticky”, survive column subsetting operations. Like sf, can always extract geometries active network element using sf::st_geometry(). shortcuts st_geometry(x, \"nodes\") st_geometry(net, \"edges\") can used extract geometries network element, regardless active . way around, can also replace geometries using setter function sf::set_set_geometry() (alternatively: st_geometry(x) = new). New node geometries required geometry type POINT, new edge geometries geometry type LINESTRING. preserve valid spatial network structure, following done: replacing node geometries, endpoints edge geometries replaced well match new node geometries. replacing edge geometries, endpoints geometries added new nodes network whenever don’t equal original location. original nodes remain network even now isolated. Original network New network can drop geometries using sf::st_drop_geometry() (alternatively: st_geometry(x) = NULL). already shown previous section, dropping edge geometries still return sfnetwork object, now spatially implicit instead spatially explicit edges. Dropping node geometries, however, return tbl_graph. area geometries occupy bounded bounding box. can use sf::st_bbox() compute bounding box active element sfnetwork object. compute bounding box full network, use st_network_bbox(). cases, network bounding box may different bounding box nodes . Element bounding boxes Network bounding box coordinates geometries always expressed specified coordinate reference system (CRS). sfnetwork object, CRS node edge geometries required equal. can extract CRS using sf::st_crs(). transform coordinates different CRS, use sf::st_transform(), specifying example EPSG code new CRS (ways specifying possible well, see documentation sf). Geometries also coordinate precision associated . precision round coordinate values, applied spatial operations. Just CRS, nodes edges sfnetwork object required precision. can extract precision using sf::st_precision(), set using sf::st_set_precision(). Precision values specified scale factor. example, specify 3 decimal places precision, use scale factor 1000. precision specified, defaults machine precision. However, sfnetworks, functions assess spatial equality nodes use default precision 1e12 (.e. 12 decimal places) speed processing. Thanks sf, also possible explicitly specify attribute-geometry relations. define attribute column attribute constant, aggregate, identity. See information. can get set attribute-geometry relations active network element function sf::st_agr(). setter, can also use pipe-friendly version sf::st_set_agr(). Note columns really attributes edges seen network analysis perspective, included attribute-geometry relation specification ensure smooth interaction sf.","code":"# Spatially explicit edges. net = as_sfnetwork(roxel) net #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows # Make edges spatially implicit. inet = net |> activate(edges) |> st_drop_geometry() inet #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 4 (active) #> from to name type #> #> 1 1 2 Hagemanns Kämpken residential #> 2 3 4 Stiegkamp residential #> 3 5 6 Havixbecker Straße residential #> 4 7 8 Holzschuhmacherweg residential #> 5 9 10 Annette-von-Droste-Hülshoff-Straße secondary #> 6 11 12 NA footway #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf() + theme_void() ggraph(inet, \"sf\") + geom_edge_link(linetype = 2) + geom_node_sf() + theme_void() as_sfnetwork(roxel, directed = FALSE) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # An undirected multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows # First we mark some streets as oneway. streets = roxel |> mutate(oneway = sample(c(TRUE, FALSE), n(), replace = TRUE, prob = c(0.8, 0.2))) # Check the distribution of oneway vs twoway streets. streets |> st_drop_geometry() |> count(oneway) #> # A tibble: 2 × 2 #> oneway n #> #> 1 FALSE 240 #> 2 TRUE 975 # Create a directed network. dnet = as_sfnetwork(streets) # Check the number of edges in the directed network. # This equals the total number of streets. n_edges(dnet) #> [1] 1215 # Convert it into a mixed network. # Oneway streets remain directed. # Twoway streets are duplicated and reversed. mnet = dnet |> convert(to_spatial_mixed, directed = oneway) # Check number of edges in the mixed network. # This equals the number of oneway streets ... # ... plus twice the number of twoway streets. n_edges(mnet) #> [1] 1455 net |> activate(edges) |> st_geometry() #> Geometry set for 1215 features #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> First 5 geometries: #> LINESTRING (7.538109 51.95286, 7.537867 51.95282) #> LINESTRING (7.537815 51.95867, 7.537015 51.95848) #> LINESTRING (7.533441 51.95578, 7.533467 51.9557... #> LINESTRING (7.525977 51.95283, 7.526581 51.95293) #> LINESTRING (7.532301 51.95559, 7.532214 51.9557... orig_net = as_sfnetwork(mozart, \"gabriel\") orig_nodes = st_geometry(orig_net, \"nodes\") new_nodes = st_jitter(orig_nodes, 250) new_net = orig_net |> st_set_geometry(new_nodes) ggraph(orig_net, \"sf\") + geom_sf(data = new_nodes, color = \"orange\") + geom_edge_sf() + geom_node_sf(color = \"darkgrey\", size = 4) + theme_void() ggraph(new_net, \"sf\") + geom_sf(data = orig_nodes, color = \"darkgrey\") + geom_edge_sf() + geom_node_sf(color = \"orange\", size = 4) + theme_void() net |> activate(nodes) |> st_drop_geometry() #> # A tbl_graph: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components #> # #> # Node Data: 987 × 0 (active) #> # #> # Edge Data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows p1 = st_point(c(1, 0)) p2 = st_point(c(0, 0.5)) p3 = st_point(c(1, 1)) p4 = st_point(c(2, 0.5)) nodes = st_sf(geometry = c(st_sfc(p1), st_sfc(p3), st_sfc(p4))) edges = st_sf(geometry = st_sfc(st_linestring(c(p1, p2, p3)))) edges$from = 1 edges$to = 2 G = sfnetwork(nodes, edges) node_bbox = G |> st_bbox() |> st_as_sfc() edge_bbox = G |> activate(edges) |> st_bbox() |> st_as_sfc() net_bbox = G |> st_network_bbox() |> st_as_sfc() ggraph(G, \"sf\") + geom_sf( data = node_bbox, color = \"#F8766D\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_sf( data = edge_bbox, color = \"#619CFF\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(G, \"sf\") + geom_sf( data = net_bbox, color = \"orange\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() st_transform(net, 3035) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150707 ymin: 3206375 xmax: 4152366 ymax: 3208564 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (4151782 3207612) #> 2 (4151765 3207609) #> 3 (4151784 3208259) #> 4 (4151728 3208240) #> 5 (4151472 3207948) #> 6 (4151470 3207929) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (4151782 3207612, 4151765 3207609) #> 2 3 4 Stiegkamp residential (4151784 3208259, 4151728 3208240) #> 3 5 6 Havixbecker Straße residential (4151472 3207948, 4151474 3207941,… #> # ℹ 1,212 more rows # With unspecified precision, no node is equal to another node. any(lengths(st_equals(net)) > 1) #> [1] FALSE # With an extremely low precision, all nodes are equal to each other. all(lengths(st_equals(st_set_precision(net, 1))) == n_nodes(net)) #> [1] TRUE net |> activate(edges) |> st_agr() #> from to name type #> constant constant #> Levels: constant aggregate identity net |> activate(edges) |> st_set_agr(c(type = \"aggregate\")) |> st_agr() #> from to name type #> constant aggregate #> Levels: constant aggregate identity"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"structure","dir":"Articles","previous_headings":"","what":"Structure","title":"Creating and representing spatial networks","text":"Obviously network just list two distinct elements. Nodes edges related . first two columns edges table always named contain integer indices source target node edge. integer indices correspond rownumbers nodes table. , nodes filtered, order changes, indices updated. geometries nodes edges also match. sfnetworks, following requirements specified valid geospatial network: Nodes geometries type POINT. Edges geometries type LINESTRING. endpoints edge geometries spatially equal corresponding node geometries. Nodes edge geometries coordinate reference system coordinate precision. need make note . geospatial network, nodes always coordinates geographic space, thus, can always described sf object. edges, however, can also described indices nodes ends. still makes geospatial, connect two specific points space, spatial information explicitly attached . representations can useful. geolocated social networks, example, often explicit spatial embedding edges. road networks, however, edges usually straight lines, geometries stored explicitly. sfnetworks variants supported: edges can described sf object geometries, also regular tibble without geometry column. refer spatially explicit edges spatially implicit edges, respectively. documentation, however, focus first type. figure summarizes structure sfnetwork objects. Just like tbl_graph objects, always one element (nodes edges) sfnetwork object active. means element main target analysis. default, nodes active element creating network. active element can changed using activate() verb, also change order elements printed. practice, looks follows. Note create network set spatial lines, creating nodes endpoints. See section Creating sfnetwork objects many examples create spatial network. Spatially explicit edges Spatially implicit edges","code":"# Spatially explicit edges. net = as_sfnetwork(roxel) net #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows # Make edges spatially implicit. inet = net |> activate(edges) |> st_drop_geometry() inet #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 4 (active) #> from to name type #> #> 1 1 2 Hagemanns Kämpken residential #> 2 3 4 Stiegkamp residential #> 3 5 6 Havixbecker Straße residential #> 4 7 8 Holzschuhmacherweg residential #> 5 9 10 Annette-von-Droste-Hülshoff-Straße secondary #> 6 11 12 NA footway #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf() + theme_void() ggraph(inet, \"sf\") + geom_edge_link(linetype = 2) + geom_node_sf() + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"directionality","dir":"Articles","previous_headings":"","what":"Directionality","title":"Creating and representing spatial networks","text":"sfnetwork objects possible represent networks directed edges, undirected edges. also possible mimic mixed representations edge types exist. default instance sfnetwork class initialized directed network. means edge can traveled source node target node, vice versa. case, geometry edge always matches direction, startpoint line location source node, endpoint line location target node. sfnetwork data structure also supports undirected networks. networks edge can traveled directions. Since clear source target, node lowest index referenced column, node highest index column. linestring geometry, however, remains unchanged. , undirected networks specified source node may always correspond startpoint edge geometry, instead endpoint. behavior ordering indices comes igraph might confusing, remember undirected networks terms meaning can thus used interchangeably. computation really need edge geometries match specified node indices, can use utility function make_edges_follow_indices(). function reverse edge geometries needed. sfnetworks native support represent mixed networks, .e. networks edges can traveled ways, others one way. However, type networks quite common applications spatial network analysis. example, road networks streets oneway streets. creating directed network, duplicating reversing edges undirected, can mimic mixed network structure. morpher to_spatial_mixed() exactly . Since network cleaning functions work well duplicated reversed edges, usually good idea first create directed network, clean , mimic mixed representation.","code":"as_sfnetwork(roxel, directed = FALSE) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # An undirected multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows # First we mark some streets as oneway. streets = roxel |> mutate(oneway = sample(c(TRUE, FALSE), n(), replace = TRUE, prob = c(0.8, 0.2))) # Check the distribution of oneway vs twoway streets. streets |> st_drop_geometry() |> count(oneway) #> # A tibble: 2 × 2 #> oneway n #> #> 1 FALSE 240 #> 2 TRUE 975 # Create a directed network. dnet = as_sfnetwork(streets) # Check the number of edges in the directed network. # This equals the total number of streets. n_edges(dnet) #> [1] 1215 # Convert it into a mixed network. # Oneway streets remain directed. # Twoway streets are duplicated and reversed. mnet = dnet |> convert(to_spatial_mixed, directed = oneway) # Check number of edges in the mixed network. # This equals the number of oneway streets ... # ... plus twice the number of twoway streets. n_edges(mnet) #> [1] 1455"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"directed-networks","dir":"Articles","previous_headings":"","what":"Directed networks","title":"Creating and representing spatial networks","text":"default instance sfnetwork class initialized directed network. means edge can traveled source node target node, vice versa. case, geometry edge always matches direction, startpoint line location source node, endpoint line location target node.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"undirected-networks","dir":"Articles","previous_headings":"","what":"Undirected networks","title":"Creating and representing spatial networks","text":"sfnetwork data structure also supports undirected networks. networks edge can traveled directions. Since clear source target, node lowest index referenced column, node highest index column. linestring geometry, however, remains unchanged. , undirected networks specified source node may always correspond startpoint edge geometry, instead endpoint. behavior ordering indices comes igraph might confusing, remember undirected networks terms meaning can thus used interchangeably. computation really need edge geometries match specified node indices, can use utility function make_edges_follow_indices(). function reverse edge geometries needed.","code":"as_sfnetwork(roxel, directed = FALSE) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # An undirected multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"mixed-networks","dir":"Articles","previous_headings":"","what":"Mixed networks","title":"Creating and representing spatial networks","text":"sfnetworks native support represent mixed networks, .e. networks edges can traveled ways, others one way. However, type networks quite common applications spatial network analysis. example, road networks streets oneway streets. creating directed network, duplicating reversing edges undirected, can mimic mixed network structure. morpher to_spatial_mixed() exactly . Since network cleaning functions work well duplicated reversed edges, usually good idea first create directed network, clean , mimic mixed representation.","code":"# First we mark some streets as oneway. streets = roxel |> mutate(oneway = sample(c(TRUE, FALSE), n(), replace = TRUE, prob = c(0.8, 0.2))) # Check the distribution of oneway vs twoway streets. streets |> st_drop_geometry() |> count(oneway) #> # A tibble: 2 × 2 #> oneway n #> #> 1 FALSE 240 #> 2 TRUE 975 # Create a directed network. dnet = as_sfnetwork(streets) # Check the number of edges in the directed network. # This equals the total number of streets. n_edges(dnet) #> [1] 1215 # Convert it into a mixed network. # Oneway streets remain directed. # Twoway streets are duplicated and reversed. mnet = dnet |> convert(to_spatial_mixed, directed = oneway) # Check number of edges in the mixed network. # This equals the number of oneway streets ... # ... plus twice the number of twoway streets. n_edges(mnet) #> [1] 1455"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"geometries","dir":"Articles","previous_headings":"","what":"Geometries","title":"Creating and representing spatial networks","text":"makes sfnetwork objects different tbl_graph objects nodes (optionally) edges geometries. geometries stored geometry list-column, following design sf. also means just sf, columns “sticky”, survive column subsetting operations. Like sf, can always extract geometries active network element using sf::st_geometry(). shortcuts st_geometry(x, \"nodes\") st_geometry(net, \"edges\") can used extract geometries network element, regardless active . way around, can also replace geometries using setter function sf::set_set_geometry() (alternatively: st_geometry(x) = new). New node geometries required geometry type POINT, new edge geometries geometry type LINESTRING. preserve valid spatial network structure, following done: replacing node geometries, endpoints edge geometries replaced well match new node geometries. replacing edge geometries, endpoints geometries added new nodes network whenever don’t equal original location. original nodes remain network even now isolated. Original network New network can drop geometries using sf::st_drop_geometry() (alternatively: st_geometry(x) = NULL). already shown previous section, dropping edge geometries still return sfnetwork object, now spatially implicit instead spatially explicit edges. Dropping node geometries, however, return tbl_graph. area geometries occupy bounded bounding box. can use sf::st_bbox() compute bounding box active element sfnetwork object. compute bounding box full network, use st_network_bbox(). cases, network bounding box may different bounding box nodes . Element bounding boxes Network bounding box coordinates geometries always expressed specified coordinate reference system (CRS). sfnetwork object, CRS node edge geometries required equal. can extract CRS using sf::st_crs(). transform coordinates different CRS, use sf::st_transform(), specifying example EPSG code new CRS (ways specifying possible well, see documentation sf). Geometries also coordinate precision associated . precision round coordinate values, applied spatial operations. Just CRS, nodes edges sfnetwork object required precision. can extract precision using sf::st_precision(), set using sf::st_set_precision(). Precision values specified scale factor. example, specify 3 decimal places precision, use scale factor 1000. precision specified, defaults machine precision. However, sfnetworks, functions assess spatial equality nodes use default precision 1e12 (.e. 12 decimal places) speed processing. Thanks sf, also possible explicitly specify attribute-geometry relations. define attribute column attribute constant, aggregate, identity. See information. can get set attribute-geometry relations active network element function sf::st_agr(). setter, can also use pipe-friendly version sf::st_set_agr(). Note columns really attributes edges seen network analysis perspective, included attribute-geometry relation specification ensure smooth interaction sf.","code":"net |> activate(edges) |> st_geometry() #> Geometry set for 1215 features #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> First 5 geometries: #> LINESTRING (7.538109 51.95286, 7.537867 51.95282) #> LINESTRING (7.537815 51.95867, 7.537015 51.95848) #> LINESTRING (7.533441 51.95578, 7.533467 51.9557... #> LINESTRING (7.525977 51.95283, 7.526581 51.95293) #> LINESTRING (7.532301 51.95559, 7.532214 51.9557... orig_net = as_sfnetwork(mozart, \"gabriel\") orig_nodes = st_geometry(orig_net, \"nodes\") new_nodes = st_jitter(orig_nodes, 250) new_net = orig_net |> st_set_geometry(new_nodes) ggraph(orig_net, \"sf\") + geom_sf(data = new_nodes, color = \"orange\") + geom_edge_sf() + geom_node_sf(color = \"darkgrey\", size = 4) + theme_void() ggraph(new_net, \"sf\") + geom_sf(data = orig_nodes, color = \"darkgrey\") + geom_edge_sf() + geom_node_sf(color = \"orange\", size = 4) + theme_void() net |> activate(nodes) |> st_drop_geometry() #> # A tbl_graph: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components #> # #> # Node Data: 987 × 0 (active) #> # #> # Edge Data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows p1 = st_point(c(1, 0)) p2 = st_point(c(0, 0.5)) p3 = st_point(c(1, 1)) p4 = st_point(c(2, 0.5)) nodes = st_sf(geometry = c(st_sfc(p1), st_sfc(p3), st_sfc(p4))) edges = st_sf(geometry = st_sfc(st_linestring(c(p1, p2, p3)))) edges$from = 1 edges$to = 2 G = sfnetwork(nodes, edges) node_bbox = G |> st_bbox() |> st_as_sfc() edge_bbox = G |> activate(edges) |> st_bbox() |> st_as_sfc() net_bbox = G |> st_network_bbox() |> st_as_sfc() ggraph(G, \"sf\") + geom_sf( data = node_bbox, color = \"#F8766D\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_sf( data = edge_bbox, color = \"#619CFF\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(G, \"sf\") + geom_sf( data = net_bbox, color = \"orange\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() st_transform(net, 3035) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150707 ymin: 3206375 xmax: 4152366 ymax: 3208564 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (4151782 3207612) #> 2 (4151765 3207609) #> 3 (4151784 3208259) #> 4 (4151728 3208240) #> 5 (4151472 3207948) #> 6 (4151470 3207929) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (4151782 3207612, 4151765 3207609) #> 2 3 4 Stiegkamp residential (4151784 3208259, 4151728 3208240) #> 3 5 6 Havixbecker Straße residential (4151472 3207948, 4151474 3207941,… #> # ℹ 1,212 more rows # With unspecified precision, no node is equal to another node. any(lengths(st_equals(net)) > 1) #> [1] FALSE # With an extremely low precision, all nodes are equal to each other. all(lengths(st_equals(st_set_precision(net, 1))) == n_nodes(net)) #> [1] TRUE net |> activate(edges) |> st_agr() #> from to name type #> constant constant #> Levels: constant aggregate identity net |> activate(edges) |> st_set_agr(c(type = \"aggregate\")) |> st_agr() #> from to name type #> constant aggregate #> Levels: constant aggregate identity"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"extract-geometries","dir":"Articles","previous_headings":"","what":"Extract geometries","title":"Creating and representing spatial networks","text":"Like sf, can always extract geometries active network element using sf::st_geometry(). shortcuts st_geometry(x, \"nodes\") st_geometry(net, \"edges\") can used extract geometries network element, regardless active .","code":"net |> activate(edges) |> st_geometry() #> Geometry set for 1215 features #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> First 5 geometries: #> LINESTRING (7.538109 51.95286, 7.537867 51.95282) #> LINESTRING (7.537815 51.95867, 7.537015 51.95848) #> LINESTRING (7.533441 51.95578, 7.533467 51.9557... #> LINESTRING (7.525977 51.95283, 7.526581 51.95293) #> LINESTRING (7.532301 51.95559, 7.532214 51.9557..."},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"replace-geometries","dir":"Articles","previous_headings":"","what":"Replace geometries","title":"Creating and representing spatial networks","text":"way around, can also replace geometries using setter function sf::set_set_geometry() (alternatively: st_geometry(x) = new). New node geometries required geometry type POINT, new edge geometries geometry type LINESTRING. preserve valid spatial network structure, following done: replacing node geometries, endpoints edge geometries replaced well match new node geometries. replacing edge geometries, endpoints geometries added new nodes network whenever don’t equal original location. original nodes remain network even now isolated. Original network New network","code":"orig_net = as_sfnetwork(mozart, \"gabriel\") orig_nodes = st_geometry(orig_net, \"nodes\") new_nodes = st_jitter(orig_nodes, 250) new_net = orig_net |> st_set_geometry(new_nodes) ggraph(orig_net, \"sf\") + geom_sf(data = new_nodes, color = \"orange\") + geom_edge_sf() + geom_node_sf(color = \"darkgrey\", size = 4) + theme_void() ggraph(new_net, \"sf\") + geom_sf(data = orig_nodes, color = \"darkgrey\") + geom_edge_sf() + geom_node_sf(color = \"orange\", size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"drop-geometries","dir":"Articles","previous_headings":"","what":"Drop geometries","title":"Creating and representing spatial networks","text":"can drop geometries using sf::st_drop_geometry() (alternatively: st_geometry(x) = NULL). already shown previous section, dropping edge geometries still return sfnetwork object, now spatially implicit instead spatially explicit edges. Dropping node geometries, however, return tbl_graph.","code":"net |> activate(nodes) |> st_drop_geometry() #> # A tbl_graph: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components #> # #> # Node Data: 987 × 0 (active) #> # #> # Edge Data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"bounding-box","dir":"Articles","previous_headings":"","what":"Bounding box","title":"Creating and representing spatial networks","text":"area geometries occupy bounded bounding box. can use sf::st_bbox() compute bounding box active element sfnetwork object. compute bounding box full network, use st_network_bbox(). cases, network bounding box may different bounding box nodes . Element bounding boxes Network bounding box","code":"p1 = st_point(c(1, 0)) p2 = st_point(c(0, 0.5)) p3 = st_point(c(1, 1)) p4 = st_point(c(2, 0.5)) nodes = st_sf(geometry = c(st_sfc(p1), st_sfc(p3), st_sfc(p4))) edges = st_sf(geometry = st_sfc(st_linestring(c(p1, p2, p3)))) edges$from = 1 edges$to = 2 G = sfnetwork(nodes, edges) node_bbox = G |> st_bbox() |> st_as_sfc() edge_bbox = G |> activate(edges) |> st_bbox() |> st_as_sfc() net_bbox = G |> st_network_bbox() |> st_as_sfc() ggraph(G, \"sf\") + geom_sf( data = node_bbox, color = \"#F8766D\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_sf( data = edge_bbox, color = \"#619CFF\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(G, \"sf\") + geom_sf( data = net_bbox, color = \"orange\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"coordinate-reference-system","dir":"Articles","previous_headings":"","what":"Coordinate reference system","title":"Creating and representing spatial networks","text":"coordinates geometries always expressed specified coordinate reference system (CRS). sfnetwork object, CRS node edge geometries required equal. can extract CRS using sf::st_crs(). transform coordinates different CRS, use sf::st_transform(), specifying example EPSG code new CRS (ways specifying possible well, see documentation sf).","code":"st_transform(net, 3035) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150707 ymin: 3206375 xmax: 4152366 ymax: 3208564 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (4151782 3207612) #> 2 (4151765 3207609) #> 3 (4151784 3208259) #> 4 (4151728 3208240) #> 5 (4151472 3207948) #> 6 (4151470 3207929) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (4151782 3207612, 4151765 3207609) #> 2 3 4 Stiegkamp residential (4151784 3208259, 4151728 3208240) #> 3 5 6 Havixbecker Straße residential (4151472 3207948, 4151474 3207941,… #> # ℹ 1,212 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"coordinate-precision","dir":"Articles","previous_headings":"","what":"Coordinate precision","title":"Creating and representing spatial networks","text":"Geometries also coordinate precision associated . precision round coordinate values, applied spatial operations. Just CRS, nodes edges sfnetwork object required precision. can extract precision using sf::st_precision(), set using sf::st_set_precision(). Precision values specified scale factor. example, specify 3 decimal places precision, use scale factor 1000. precision specified, defaults machine precision. However, sfnetworks, functions assess spatial equality nodes use default precision 1e12 (.e. 12 decimal places) speed processing.","code":"# With unspecified precision, no node is equal to another node. any(lengths(st_equals(net)) > 1) #> [1] FALSE # With an extremely low precision, all nodes are equal to each other. all(lengths(st_equals(st_set_precision(net, 1))) == n_nodes(net)) #> [1] TRUE"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"attribute-geometry-relations","dir":"Articles","previous_headings":"","what":"Attribute-geometry relations","title":"Creating and representing spatial networks","text":"Thanks sf, also possible explicitly specify attribute-geometry relations. define attribute column attribute constant, aggregate, identity. See information. can get set attribute-geometry relations active network element function sf::st_agr(). setter, can also use pipe-friendly version sf::st_set_agr(). Note columns really attributes edges seen network analysis perspective, included attribute-geometry relation specification ensure smooth interaction sf.","code":"net |> activate(edges) |> st_agr() #> from to name type #> constant constant #> Levels: constant aggregate identity net |> activate(edges) |> st_set_agr(c(type = \"aggregate\")) |> st_agr() #> from to name type #> constant aggregate #> Levels: constant aggregate identity"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"creating-sfnetwork-objects","dir":"Articles","previous_headings":"","what":"Creating sfnetwork objects","title":"Creating and representing spatial networks","text":"several ways create sfnetwork object, discussed detail . basic way create sfnetwork object provide ready--use node edge tables sfnetwork() construction function. Remember nodes sf object POINT geometries, first two columns edges table required named contain rownumbers nodes start end edge. edges spatially explicit, hence, also geometries, type LINESTRING endpoints equal locations source target nodes. construction function check provided input meets criteria. already sure data forms valid spatial network, can set force = TRUE. also possible provide nodes sf object, can converted . example, table two coordinate columns. additional arguments provided sfnetwork() construction function forwarded sf::st_as_sf() convert provided nodes table sf object. Instead integers referring rownumbers nodes table, columns edges table can also contain characters refer values specific node attribute column. name column given argument node_key. default, assumed column named name. Internally, construction function convert character values integer indices referencing rownumbers. edges geometries, can still create network spatially explicit edges setting edges_as_lines = TRUE. create linestring geometries straight lines source target nodes. common way create spatial network start set LINESTRING geometries sf format. assumed edge network. Providing as_sfnetwork() automatically call create_from_spatial_lines(). function creates nodes endpoints lines. Endpoints shared multiple lines, become single node network. determine spatial equality endpoints, sfnetworks default uses 12-digit precision coordinates. can change either setting different precision (see ) effectively rounding coordinate values using utility function st_round(). Lines Network Besides endpoints, linestring geometries may interior points define shape. may multiple linestrings interior points location. Since endpoints, become node network. also want add nodes shared interior points, set subdivide = TRUE, call to_spatial_subdivision() morpher construction. See vignette Spatial morphers details. also possible create network set POINT geometries. assumed nodes network. Providing as_sfnetwork() automatically call create_from_spatial_points(). second input requires adjacency matrix specifies nodes connected . Adjacency matrices networks n×nn \\times n matrices nn number nodes, element AijA_{ij} holding value edge node ii node jj, value otherwise. Points Network adjacency matrix can also provided sparse form, node indices nodes connected listed. allows directly forward output binary spatial predicate. example, using sf::st_is_within_distance(), can connect nodes within given distance . Points Network Finally, sfnetworks can create adjacency matrix internally according specified method. case, just need provide name method. Supported options currently : complete: nodes directly connected . sequence: nodes sequentially connected , meaning first node connected second node, second node connected third node, etc. minimum_spanning_tree: nodes connected spatial minimum spanning tree, .e. set edges minimum total edge length required connect nodes. Can also specified mst. delaunay: nodes connected Delaunay triangulation. Requires spdep package installed, assumes planar coordinates. gabriel: nodes connected Gabriel graph. Requires spdep package installed, assumes planar coordinates. relative_neighborhood: nodes connected relative neighborhood graph. Can also specified rn. Requires spdep package installed, assumes planar coordinates. nearest_neighbors: node connected kk nearest neighbors, kk specified k argument. default, k = 1, meaning nodes connected nearest neighbor graph. Can also specified knn. Requires spdep package installed. Complete Sequential Minimum spanning tree Delaunay triangulation Gabriel Relative neighbors Nearest neighbors K nearest neighbors (k = 3) conversion function as_sfnetwork() can also used convert instances network classes sfnetwork object. includes classes also designed spatial networks, dodgr_streetnet dodgr package routing street networks, linnet spatstat.linnet package statistical point pattern analysis spatial linear networks. However, can also used convert instances non-spatial network formats, long specify way spatial location nodes. example, igraph object x y coordinates stored node attributes. case, additional arguments provided as_sfnetwork() forwarded sf::st_as_sf() convert nodes given network sf object. currently functions sfnetworks reading writing data (ideas). However, can use sf::st_read() spatial file formats read points /lines, construct network using sfnetwork() (described ) as_sfnetwork() (described lines points). network specific file types, can use igraph::read_graph() read data R, convert spatial network format using as_sfnetwork() long required spatial information present (see ). common format latter category GraphML. example file can found , containing power grid Netherlands. reading using igraph, first convert tbl_graph can easily explore data. can see spatial geometries nodes edges stored WKT strings columns named wktsrid4326. Remember additional arguments as_sfnetwork() igraph objects forwarded sf::st_as_sf() convert nodes sf object. makes conversion sfnetwork object easy : However, affect nodes table (since one required geometries). edges explicit geometries yet. Using morpher function to_spatial_explicit(), can “explicitize” edge geometries constructed network. Also , additional arguments forwarded sf::st_as_sf(). common source spatial network data OpenStreetMap.open collaborative geographic database. can used example extract geometries streets rivers anywhere world. R, two main packages allow read OpenStreetMap data: osmdata package provides interface Overpass API OpenStreetMap. osmextract package can read OpenStreetMap data osm.pbf files. small areas repeated calls, Overpass API easiest way get data. However, area interest large, want load data many times, preferred overload API read osm.pbf files instead. Geofabrik one platforms can download files many different regions world. , show small example using osmdata. can read street centerlines Anif, small village Austria, shown . details workflow, check osmdata documentation. Now, can simply create network lines using as_sfnetwork(), shown . However, need aware OpenStreetMap data created primarily network structure mind. means locations two streets connect always endpoints linestring geometries, can interior point geometry well. setting subdivide = TRUE linestring geometries subdivided places interior point shared multiple features. way, node placed locations. function play_geometric() creates random geometric graph. randomly samples nn nodes, connects edge within given distance threshold . default, sampling take place unit square. However, bounds argument can also provide spatial feature sample . use sf::st_sample() internally. Random network Random network B","code":"p1 = st_point(c(6, 52)) p2 = st_point(c(8, 53)) p3 = st_point(c(8, 51)) l1 = st_linestring(c(p1, p2)) l2 = st_linestring(c(p2, p3)) l3 = st_linestring(c(p3, p1)) edges = st_sf(geometry = st_sfc(l1, l2, l3), crs = 4326) nodes = st_sf(geometry = st_sfc(p1, p2, p3), crs = 4326) edges$from = c(1, 2, 3) edges$to = c(2, 3, 1) net = sfnetwork(nodes, edges) net #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 6 ymin: 51 xmax: 8 ymax: 53 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 1 (active) #> geometry #> #> 1 (6 52) #> 2 (8 53) #> 3 (8 51) #> # #> # Edge data: 3 × 3 #> from to geometry #> #> 1 1 2 (6 52, 8 53) #> 2 2 3 (8 53, 8 51) #> 3 3 1 (8 51, 6 52) nodes_tbl = tibble(x = c(6, 8, 8), y = c(52, 53, 51)) net = sfnetwork(nodes_tbl, edges, coords = c(\"x\", \"y\"), crs = 4326) net #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 6 ymin: 51 xmax: 8 ymax: 53 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 1 (active) #> geometry #> #> 1 (6 52) #> 2 (8 53) #> 3 (8 51) #> # #> # Edge data: 3 × 3 #> from to geometry #> #> 1 1 2 (6 52, 8 53) #> 2 2 3 (8 53, 8 51) #> 3 3 1 (8 51, 6 52) nodes$type = c(\"city\", \"village\", \"farm\") edges = st_drop_geometry(edges) edges$from = c(\"city\", \"village\", \"farm\") edges$to = c(\"village\", \"farm\", \"city\") net = sfnetwork(nodes, edges, node_key = \"type\", edges_as_lines = TRUE) net #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 6 ymin: 51 xmax: 8 ymax: 53 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 2 (active) #> geometry type #> #> 1 (6 52) city #> 2 (8 53) village #> 3 (8 51) farm #> # #> # Edge data: 3 × 3 #> from to geometry #> #> 1 1 2 (6 52, 8 53) #> 2 2 3 (8 53, 8 51) #> 3 3 1 (8 51, 6 52) ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(type)), size = 4) + scale_color_discrete(\"type\") + theme_void() # Linestring geometries. roxel #> Simple feature collection with 1215 features and 2 fields #> Attribute-geometry relationships: constant (2) #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 1,215 × 3 #> name type geometry #> #> 1 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 … #> 2 Stiegkamp residential (7.537815 51.95867, 7.537015 … #> 3 Havixbecker Straße residential (7.533441 51.95578, 7.533467 … #> 4 Holzschuhmacherweg residential (7.525977 51.95283, 7.526581 … #> 5 Annette-von-Droste-Hülshoff-Straße secondary (7.532301 51.95559, 7.532214 … #> 6 NA footway (7.543404 51.94779, 7.54358 5… #> 7 Deermannskamp residential (7.537675 51.95689, 7.537904 … #> 8 Lindenstraße residential (7.539105 51.9504, 7.540105 5… #> 9 NA NA (7.534875 51.95795, 7.534819 … #> 10 Annette-von-Droste-Hülshoff-Straße secondary (7.532465 51.95424, 7.532469 … #> # ℹ 1,205 more rows # Network. net = as_sfnetwork(roxel) net #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows ggplot(roxel) + geom_sf() + theme_void() ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf() + theme_void() # Point geometries. mozart #> Simple feature collection with 17 features and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 17 × 4 #> name type website geometry #> * #> 1 Mozartkino cinema https://www.… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> 4 Mozart Denkmal artwork NA (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) #> 6 Mozartsteg bridge NA (4549473 2747624) #> 7 Mozarts Geburtshaus museum http://www.m… (4549064 2747619) #> 8 Café Mozart cafe https://www.… (4548994 2747632) #> 9 Mozartkugel confectionery NA (4549120 2747654) #> 10 Mozartsteg/Imbergstraße bus_stop NA (4549418 2747723) #> 11 Spirit of Mozart artwork https://salz… (4549119 2747790) #> 12 Mozart-Eine Hommage artwork https://salz… (4548664 2747868) #> 13 Mozarts Wohnhaus apartments NA (4549073 2747916) #> 14 Universität Mozarteum university NA (4549059 2748042) #> 15 Stiftung Mozarteum concert_hall NA (4548897 2748037) #> 16 Hotel Mozart hotel http://www.h… (4549378 2748391) #> 17 Mozart Studentenheim dormitory NA (4548984 2748537) # Adjacency matrix. adj = matrix(c(rep(TRUE, 17), rep(rep(FALSE, 17), 16)), nrow = 17) # Network. net = as_sfnetwork(mozart, adj) net #> # A sfnetwork: 17 nodes and 17 edges #> # #> # A bipartite multigraph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 4 (active) #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> 4 Mozart Denkmal artwork NA (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) #> 6 Mozartsteg bridge NA (4549473 2747624) #> # ℹ 11 more rows #> # #> # Edge data: 17 × 3 #> from to geometry #> #> 1 1 1 (4549504 2747309, 4549504 2747309) #> 2 2 1 (4549003 2747376, 4549504 2747309) #> 3 3 1 (4549589 2747507, 4549504 2747309) #> # ℹ 14 more rows ggplot(mozart) + geom_sf(size = 4) + theme_void() ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() adj = st_is_within_distance(mozart, dist = set_units(250, \"m\")) adj #> Sparse geometry binary predicate list of length 17, where the predicate #> was `is_within_distance' #> first 10 elements: #> 1: 1, 3, 4, 5 #> 2: 2 #> 3: 1, 3, 4, 5, 6 #> 4: 1, 3, 4, 5, 6, 10 #> 5: 1, 3, 4, 5, 6, 10 #> 6: 3, 4, 5, 6, 10 #> 7: 7, 8, 9, 11 #> 8: 7, 8, 9, 11 #> 9: 7, 8, 9, 11 #> 10: 4, 5, 6, 10 net = as_sfnetwork(mozart, adj) ggplot(mozart) + geom_sf(size = 4) + theme_void() ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() make_ggraph = function(x) { ggraph(x, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() } make_ggraph(as_sfnetwork(mozart, \"complete\")) make_ggraph(as_sfnetwork(mozart, \"sequence\")) make_ggraph(as_sfnetwork(mozart, \"mst\")) make_ggraph(as_sfnetwork(mozart, \"delaunay\")) make_ggraph(as_sfnetwork(mozart, \"gabriel\")) make_ggraph(as_sfnetwork(mozart, \"rn\")) make_ggraph(as_sfnetwork(mozart, \"knn\")) #> Warning in spdep::knn2nb(spdep::knearneigh(st_geometry(x), k = k), sym = #> FALSE): neighbour object has 4 sub-graphs make_ggraph(as_sfnetwork(mozart, \"knn\", k = 3)) #> Warning in spdep::knn2nb(spdep::knearneigh(st_geometry(x), k = k), sym = #> FALSE): neighbour object has 2 sub-graphs # igraph object. inet = igraph::sample_grg(5, 0.5, coords = TRUE) inet #> IGRAPH c92c8b1 U--- 5 3 -- Geometric random graph #> + attr: name (g/c), radius (g/n), torus (g/l), x (v/n), y (v/n) #> + edges from c92c8b1: #> [1] 2--3 2--4 3--4 # sfnetwork object. net = as_sfnetwork(inet, coords = c(\"x\", \"y\")) net #> # A sfnetwork: 5 nodes and 3 edges #> # #> # An undirected simple graph with 3 components and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0.261492 ymin: 0.1013638 xmax: 0.9185794 ymax: 0.97436 #> # CRS: NA #> # #> # Node data: 5 × 1 (active) #> geometry #> #> 1 (0.261492 0.1091643) #> 2 (0.592074 0.5755864) #> 3 (0.7117123 0.877187) #> 4 (0.7776058 0.97436) #> 5 (0.9185794 0.1013638) #> # #> # Edge data: 3 × 2 #> from to #> #> 1 2 3 #> 2 2 4 #> 3 3 4 url = \"https://raw.githubusercontent.com/ComplexNetTSP/Power_grids/v1.0.0/Countries/Netherlands/graphml/Netherlands_highvoltage.graphml\" igraph::read_graph(url, format = \"graphml\") |> as_tbl_graph() #> # A tbl_graph: 91 nodes and 101 edges #> # #> # An undirected simple graph with 2 components #> # #> # Node Data: 91 × 14 (active) #> netcapacity typ wktsrid4326 lat voltage frequency ngen operator lon #> #> 1 \"\" substat… SRID=4326;… 52.3… 110000 \"\" \"\" \"TenneT\" 6.67… #> 2 \"\" substat… SRID=4326;… 52.2… 110000 \"\" \"\" \"\" 6.83… #> 3 \"\" substat… SRID=4326;… 53.4… 220000 \"\" \"\" \"TenneT\" 6.86… #> 4 \"\" joint SRID=4326;… 53.2… 220000… \"50;50;5… \"\" \"TenneT\" 6.47… #> 5 \"\" joint SRID=4326;… 51.4… 150000… \"50;50;5… \"\" \"TenneT\" 5.62… #> 6 \"\" joint SRID=4326;… 52.4… 150000… \"50;50;5… \"\" \"TenneT\" 4.87… #> 7 \"\" joint SRID=4326;… 52.4… 380000… \"50;50;5… \"\" \"TenneT\" 4.87… #> 8 \"\" substat… SRID=4326;… 52.4… 380000… \"\" \"\" \"TenneT\" 4.87… #> 9 \"\" substat… SRID=4326;… 51.8… 380000 \"\" \"\" \"TenneT\" 4.26… #> 10 \"\" substat… SRID=4326;… 51.6… 380000… \"\" \"\" \"TenneT\" 5.91… #> # ℹ 81 more rows #> # ℹ 5 more variables: ref , source , name , capacity , #> # id #> # #> # Edge Data: 101 × 18 #> from to rohmkm cables wktsrid4326 operator type lengthm voltage frequency #> #> 1 1 52 \"\" 6;3;3… SRID=4326;… \"\" line 49125.… 380000… 50 #> 2 1 21 \"\" 3;3;3… SRID=4326;… \"TenneT\" line 7653.0… 110000… 50;50 #> 3 2 23 \"\" 6;6 SRID=4326;… \"TenneT\" line 6135.3… 380000… 50 #> # ℹ 98 more rows #> # ℹ 8 more variables: cnfkm , fromrelation , ref , name , #> # xohmkm , wires , ithmaxa , lid net = igraph::read_graph(url, format = \"graphml\") |> as_sfnetwork(wkt = \"wktsrid4326\", crs = 4326) |> rename(geometry = wktsrid4326) net #> # A sfnetwork: 91 nodes and 101 edges #> # #> # An undirected simple graph with 2 components and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 3.692428 ymin: 51.14805 xmax: 7.041048 ymax: 53.44424 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 91 × 14 (active) #> netcapacity typ geometry lat voltage frequency ngen #> #> 1 \"\" substation (6.679331 52.32104) 52.3210417… 110000 \"\" \"\" #> 2 \"\" substation (6.830673 52.2139) 52.2139014… 110000 \"\" \"\" #> 3 \"\" substation (6.869683 53.42999) 53.4299869… 220000 \"\" \"\" #> 4 \"\" joint (6.474364 53.21321) 53.2132104… 220000… \"50;50;5… \"\" #> 5 \"\" joint (5.621211 51.45516) 51.4551594… 150000… \"50;50;5… \"\" #> 6 \"\" joint (4.873691 52.42842) 52.4284153… 150000… \"50;50;5… \"\" #> # ℹ 85 more rows #> # ℹ 7 more variables: operator , lon , ref , source , #> # name , capacity , id #> # #> # Edge data: 101 × 18 #> from to rohmkm cables wktsrid4326 operator type lengthm voltage frequency #> #> 1 1 52 \"\" 6;3;3… SRID=4326;… \"\" line 49125.… 380000… 50 #> 2 1 21 \"\" 3;3;3… SRID=4326;… \"TenneT\" line 7653.0… 110000… 50;50 #> 3 2 23 \"\" 6;6 SRID=4326;… \"TenneT\" line 6135.3… 380000… 50 #> # ℹ 98 more rows #> # ℹ 8 more variables: cnfkm , fromrelation , ref , name , #> # xohmkm , wires , ithmaxa , lid net = net |> convert(to_spatial_explicit, wkt = \"wktsrid4326\", crs = 4326, .clean = TRUE) |> activate(edges) |> rename(geometry = wktsrid4326) net #> # A sfnetwork: 91 nodes and 101 edges #> # #> # An undirected simple graph with 2 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 3.692428 ymin: 51.14805 xmax: 7.041048 ymax: 53.44424 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 101 × 18 (active) #> from to rohmkm cables geometry operator type lengthm #> #> 1 1 52 \"\" 6;3;3;3;3 (6.188921 52.53048, 6.67… \"\" line 49125.… #> 2 1 21 \"\" 3;3;3;3;6… (6.768035 52.27755, 6.67… \"TenneT\" line 7653.0… #> 3 2 23 \"\" 6;6 (6.830673 52.2139, 6.760… \"TenneT\" line 6135.3… #> 4 2 13 \"\" 6;6 (6.830673 52.2139, 6.888… \"\" line 4296.2… #> 5 3 53 \"\" 6 (6.869683 53.42999, 6.87… \"\" line 388.82… #> 6 3 70 \"\" 6 (6.869683 53.42999, 6.85… \"\" line 359.61… #> # ℹ 95 more rows #> # ℹ 10 more variables: voltage , frequency , cnfkm , #> # fromrelation , ref , name , xohmkm , wires , #> # ithmaxa , lid #> # #> # Node data: 91 × 14 #> netcapacity typ geometry lat voltage frequency ngen #> #> 1 \"\" substation (6.679331 52.32104) 52.3210417… 110000 \"\" \"\" #> 2 \"\" substation (6.830673 52.2139) 52.2139014… 110000 \"\" \"\" #> 3 \"\" substation (6.869683 53.42999) 53.4299869… 220000 \"\" \"\" #> # ℹ 88 more rows #> # ℹ 7 more variables: operator , lon , ref , source , #> # name , capacity , id ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() library(osmdata) #> Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright # Call the Overpass API to extract streets in Anif. data = opq(\"Anif, Austria\") |> add_osm_feature(key = \"highway\") |> osmdata_sf() |> osm_poly2line() # Extract only the linestring geometries from the response. streets = data$osm_lines |> select(name, \"type\" = highway, surface) streets #> Simple feature collection with 1781 features and 3 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 13.03806 ymin: 47.71134 xmax: 13.08752 ymax: 47.76715 #> Geodetic CRS: WGS 84 #> First 10 features: #> name type surface #> 5205037 Sankt-Leonhard-Straße secondary asphalt #> 13868047 Christophorusstraße residential #> 13868111 Überfuhrstraße unclassified asphalt #> 16300987 motorway_link asphalt #> 16628000 Berchtesgadener Straße primary asphalt #> 20812716 Ursteinsteg cycleway asphalt #> 20812718 Tauernradweg path fine_gravel #> 22767760 motorway_link asphalt #> 22767761 motorway_link asphalt #> 22767763 motorway_link asphalt #> geometry #> 5205037 LINESTRING (13.05769 47.724... #> 13868047 LINESTRING (13.08263 47.746... #> 13868111 LINESTRING (13.08397 47.746... #> 16300987 LINESTRING (13.0515 47.7375... #> 16628000 LINESTRING (13.05344 47.739... #> 20812716 LINESTRING (13.08375 47.725... #> 20812718 LINESTRING (13.08152 47.731... #> 22767760 LINESTRING (13.04707 47.741... #> 22767761 LINESTRING (13.05249 47.738... #> 22767763 LINESTRING (13.05394 47.740... net = as_sfnetwork(streets, directed = FALSE) net #> # A sfnetwork: 2519 nodes and 1781 edges #> # #> # An undirected multigraph with 837 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 13.03806 ymin: 47.71134 xmax: 13.08752 ymax: 47.76715 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 2,519 × 1 (active) #> geometry #> #> 1 (13.05769 47.72452) #> 2 (13.05883 47.72453) #> 3 (13.08263 47.74633) #> 4 (13.08086 47.75767) #> 5 (13.08397 47.74621) #> 6 (13.0515 47.73759) #> # ℹ 2,513 more rows #> # #> # Edge data: 1,781 × 6 #> from to name type surface geometry #> #> 1 1 2 Sankt-Leonhard-Straße secondary asphalt (13.05769 47.72452, 13.0… #> 2 3 4 Christophorusstraße residenti… NA (13.08263 47.74633, 13.0… #> 3 3 5 Überfuhrstraße unclassif… asphalt (13.08397 47.74621, 13.0… #> # ℹ 1,778 more rows # The create network without subdivision has many disconnected components. with_graph(net, graph_component_count()) #> [1] 837 # Creating the network with subdivsion reduces this number drastically. net = as_sfnetwork(streets, subdivide = TRUE) with_graph(net, graph_component_count()) #> [1] 21 ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf() + theme_void() # Sample on a unit square. neta = play_geometric(10, 0.3) # Sample on a spatial feature. netb = play_geometric(20, set_units(250, \"m\"), bounds = st_bbox(mozart)) ggraph(neta, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(netb, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"from-node-and-edge-tables","dir":"Articles","previous_headings":"","what":"From node and edge tables","title":"Creating and representing spatial networks","text":"basic way create sfnetwork object provide ready--use node edge tables sfnetwork() construction function. Remember nodes sf object POINT geometries, first two columns edges table required named contain rownumbers nodes start end edge. edges spatially explicit, hence, also geometries, type LINESTRING endpoints equal locations source target nodes. construction function check provided input meets criteria. already sure data forms valid spatial network, can set force = TRUE. also possible provide nodes sf object, can converted . example, table two coordinate columns. additional arguments provided sfnetwork() construction function forwarded sf::st_as_sf() convert provided nodes table sf object. Instead integers referring rownumbers nodes table, columns edges table can also contain characters refer values specific node attribute column. name column given argument node_key. default, assumed column named name. Internally, construction function convert character values integer indices referencing rownumbers. edges geometries, can still create network spatially explicit edges setting edges_as_lines = TRUE. create linestring geometries straight lines source target nodes.","code":"p1 = st_point(c(6, 52)) p2 = st_point(c(8, 53)) p3 = st_point(c(8, 51)) l1 = st_linestring(c(p1, p2)) l2 = st_linestring(c(p2, p3)) l3 = st_linestring(c(p3, p1)) edges = st_sf(geometry = st_sfc(l1, l2, l3), crs = 4326) nodes = st_sf(geometry = st_sfc(p1, p2, p3), crs = 4326) edges$from = c(1, 2, 3) edges$to = c(2, 3, 1) net = sfnetwork(nodes, edges) net #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 6 ymin: 51 xmax: 8 ymax: 53 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 1 (active) #> geometry #> #> 1 (6 52) #> 2 (8 53) #> 3 (8 51) #> # #> # Edge data: 3 × 3 #> from to geometry #> #> 1 1 2 (6 52, 8 53) #> 2 2 3 (8 53, 8 51) #> 3 3 1 (8 51, 6 52) nodes_tbl = tibble(x = c(6, 8, 8), y = c(52, 53, 51)) net = sfnetwork(nodes_tbl, edges, coords = c(\"x\", \"y\"), crs = 4326) net #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 6 ymin: 51 xmax: 8 ymax: 53 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 1 (active) #> geometry #> #> 1 (6 52) #> 2 (8 53) #> 3 (8 51) #> # #> # Edge data: 3 × 3 #> from to geometry #> #> 1 1 2 (6 52, 8 53) #> 2 2 3 (8 53, 8 51) #> 3 3 1 (8 51, 6 52) nodes$type = c(\"city\", \"village\", \"farm\") edges = st_drop_geometry(edges) edges$from = c(\"city\", \"village\", \"farm\") edges$to = c(\"village\", \"farm\", \"city\") net = sfnetwork(nodes, edges, node_key = \"type\", edges_as_lines = TRUE) net #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 6 ymin: 51 xmax: 8 ymax: 53 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 2 (active) #> geometry type #> #> 1 (6 52) city #> 2 (8 53) village #> 3 (8 51) farm #> # #> # Edge data: 3 × 3 #> from to geometry #> #> 1 1 2 (6 52, 8 53) #> 2 2 3 (8 53, 8 51) #> 3 3 1 (8 51, 6 52) ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(type)), size = 4) + scale_color_discrete(\"type\") + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"from-spatial-lines","dir":"Articles","previous_headings":"","what":"From spatial lines","title":"Creating and representing spatial networks","text":"common way create spatial network start set LINESTRING geometries sf format. assumed edge network. Providing as_sfnetwork() automatically call create_from_spatial_lines(). function creates nodes endpoints lines. Endpoints shared multiple lines, become single node network. determine spatial equality endpoints, sfnetworks default uses 12-digit precision coordinates. can change either setting different precision (see ) effectively rounding coordinate values using utility function st_round(). Lines Network Besides endpoints, linestring geometries may interior points define shape. may multiple linestrings interior points location. Since endpoints, become node network. also want add nodes shared interior points, set subdivide = TRUE, call to_spatial_subdivision() morpher construction. See vignette Spatial morphers details.","code":"# Linestring geometries. roxel #> Simple feature collection with 1215 features and 2 fields #> Attribute-geometry relationships: constant (2) #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 1,215 × 3 #> name type geometry #> #> 1 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 … #> 2 Stiegkamp residential (7.537815 51.95867, 7.537015 … #> 3 Havixbecker Straße residential (7.533441 51.95578, 7.533467 … #> 4 Holzschuhmacherweg residential (7.525977 51.95283, 7.526581 … #> 5 Annette-von-Droste-Hülshoff-Straße secondary (7.532301 51.95559, 7.532214 … #> 6 NA footway (7.543404 51.94779, 7.54358 5… #> 7 Deermannskamp residential (7.537675 51.95689, 7.537904 … #> 8 Lindenstraße residential (7.539105 51.9504, 7.540105 5… #> 9 NA NA (7.534875 51.95795, 7.534819 … #> 10 Annette-von-Droste-Hülshoff-Straße secondary (7.532465 51.95424, 7.532469 … #> # ℹ 1,205 more rows # Network. net = as_sfnetwork(roxel) net #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows ggplot(roxel) + geom_sf() + theme_void() ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf() + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"from-spatial-points","dir":"Articles","previous_headings":"","what":"From spatial points","title":"Creating and representing spatial networks","text":"also possible create network set POINT geometries. assumed nodes network. Providing as_sfnetwork() automatically call create_from_spatial_points(). second input requires adjacency matrix specifies nodes connected . Adjacency matrices networks n×nn \\times n matrices nn number nodes, element AijA_{ij} holding value edge node ii node jj, value otherwise. Points Network adjacency matrix can also provided sparse form, node indices nodes connected listed. allows directly forward output binary spatial predicate. example, using sf::st_is_within_distance(), can connect nodes within given distance . Points Network Finally, sfnetworks can create adjacency matrix internally according specified method. case, just need provide name method. Supported options currently : complete: nodes directly connected . sequence: nodes sequentially connected , meaning first node connected second node, second node connected third node, etc. minimum_spanning_tree: nodes connected spatial minimum spanning tree, .e. set edges minimum total edge length required connect nodes. Can also specified mst. delaunay: nodes connected Delaunay triangulation. Requires spdep package installed, assumes planar coordinates. gabriel: nodes connected Gabriel graph. Requires spdep package installed, assumes planar coordinates. relative_neighborhood: nodes connected relative neighborhood graph. Can also specified rn. Requires spdep package installed, assumes planar coordinates. nearest_neighbors: node connected kk nearest neighbors, kk specified k argument. default, k = 1, meaning nodes connected nearest neighbor graph. Can also specified knn. Requires spdep package installed. Complete Sequential Minimum spanning tree Delaunay triangulation Gabriel Relative neighbors Nearest neighbors K nearest neighbors (k = 3)","code":"# Point geometries. mozart #> Simple feature collection with 17 features and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 17 × 4 #> name type website geometry #> * #> 1 Mozartkino cinema https://www.… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> 4 Mozart Denkmal artwork NA (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) #> 6 Mozartsteg bridge NA (4549473 2747624) #> 7 Mozarts Geburtshaus museum http://www.m… (4549064 2747619) #> 8 Café Mozart cafe https://www.… (4548994 2747632) #> 9 Mozartkugel confectionery NA (4549120 2747654) #> 10 Mozartsteg/Imbergstraße bus_stop NA (4549418 2747723) #> 11 Spirit of Mozart artwork https://salz… (4549119 2747790) #> 12 Mozart-Eine Hommage artwork https://salz… (4548664 2747868) #> 13 Mozarts Wohnhaus apartments NA (4549073 2747916) #> 14 Universität Mozarteum university NA (4549059 2748042) #> 15 Stiftung Mozarteum concert_hall NA (4548897 2748037) #> 16 Hotel Mozart hotel http://www.h… (4549378 2748391) #> 17 Mozart Studentenheim dormitory NA (4548984 2748537) # Adjacency matrix. adj = matrix(c(rep(TRUE, 17), rep(rep(FALSE, 17), 16)), nrow = 17) # Network. net = as_sfnetwork(mozart, adj) net #> # A sfnetwork: 17 nodes and 17 edges #> # #> # A bipartite multigraph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 4 (active) #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> 4 Mozart Denkmal artwork NA (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) #> 6 Mozartsteg bridge NA (4549473 2747624) #> # ℹ 11 more rows #> # #> # Edge data: 17 × 3 #> from to geometry #> #> 1 1 1 (4549504 2747309, 4549504 2747309) #> 2 2 1 (4549003 2747376, 4549504 2747309) #> 3 3 1 (4549589 2747507, 4549504 2747309) #> # ℹ 14 more rows ggplot(mozart) + geom_sf(size = 4) + theme_void() ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() adj = st_is_within_distance(mozart, dist = set_units(250, \"m\")) adj #> Sparse geometry binary predicate list of length 17, where the predicate #> was `is_within_distance' #> first 10 elements: #> 1: 1, 3, 4, 5 #> 2: 2 #> 3: 1, 3, 4, 5, 6 #> 4: 1, 3, 4, 5, 6, 10 #> 5: 1, 3, 4, 5, 6, 10 #> 6: 3, 4, 5, 6, 10 #> 7: 7, 8, 9, 11 #> 8: 7, 8, 9, 11 #> 9: 7, 8, 9, 11 #> 10: 4, 5, 6, 10 net = as_sfnetwork(mozart, adj) ggplot(mozart) + geom_sf(size = 4) + theme_void() ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() make_ggraph = function(x) { ggraph(x, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() } make_ggraph(as_sfnetwork(mozart, \"complete\")) make_ggraph(as_sfnetwork(mozart, \"sequence\")) make_ggraph(as_sfnetwork(mozart, \"mst\")) make_ggraph(as_sfnetwork(mozart, \"delaunay\")) make_ggraph(as_sfnetwork(mozart, \"gabriel\")) make_ggraph(as_sfnetwork(mozart, \"rn\")) make_ggraph(as_sfnetwork(mozart, \"knn\")) #> Warning in spdep::knn2nb(spdep::knearneigh(st_geometry(x), k = k), sym = #> FALSE): neighbour object has 4 sub-graphs make_ggraph(as_sfnetwork(mozart, \"knn\", k = 3)) #> Warning in spdep::knn2nb(spdep::knearneigh(st_geometry(x), k = k), sym = #> FALSE): neighbour object has 2 sub-graphs"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"from-other-network-representations","dir":"Articles","previous_headings":"","what":"From other network representations","title":"Creating and representing spatial networks","text":"conversion function as_sfnetwork() can also used convert instances network classes sfnetwork object. includes classes also designed spatial networks, dodgr_streetnet dodgr package routing street networks, linnet spatstat.linnet package statistical point pattern analysis spatial linear networks. However, can also used convert instances non-spatial network formats, long specify way spatial location nodes. example, igraph object x y coordinates stored node attributes. case, additional arguments provided as_sfnetwork() forwarded sf::st_as_sf() convert nodes given network sf object.","code":"# igraph object. inet = igraph::sample_grg(5, 0.5, coords = TRUE) inet #> IGRAPH c92c8b1 U--- 5 3 -- Geometric random graph #> + attr: name (g/c), radius (g/n), torus (g/l), x (v/n), y (v/n) #> + edges from c92c8b1: #> [1] 2--3 2--4 3--4 # sfnetwork object. net = as_sfnetwork(inet, coords = c(\"x\", \"y\")) net #> # A sfnetwork: 5 nodes and 3 edges #> # #> # An undirected simple graph with 3 components and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0.261492 ymin: 0.1013638 xmax: 0.9185794 ymax: 0.97436 #> # CRS: NA #> # #> # Node data: 5 × 1 (active) #> geometry #> #> 1 (0.261492 0.1091643) #> 2 (0.592074 0.5755864) #> 3 (0.7117123 0.877187) #> 4 (0.7776058 0.97436) #> 5 (0.9185794 0.1013638) #> # #> # Edge data: 3 × 2 #> from to #> #> 1 2 3 #> 2 2 4 #> 3 3 4"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"from-files","dir":"Articles","previous_headings":"","what":"From files","title":"Creating and representing spatial networks","text":"currently functions sfnetworks reading writing data (ideas). However, can use sf::st_read() spatial file formats read points /lines, construct network using sfnetwork() (described ) as_sfnetwork() (described lines points). network specific file types, can use igraph::read_graph() read data R, convert spatial network format using as_sfnetwork() long required spatial information present (see ). common format latter category GraphML. example file can found , containing power grid Netherlands. reading using igraph, first convert tbl_graph can easily explore data. can see spatial geometries nodes edges stored WKT strings columns named wktsrid4326. Remember additional arguments as_sfnetwork() igraph objects forwarded sf::st_as_sf() convert nodes sf object. makes conversion sfnetwork object easy : However, affect nodes table (since one required geometries). edges explicit geometries yet. Using morpher function to_spatial_explicit(), can “explicitize” edge geometries constructed network. Also , additional arguments forwarded sf::st_as_sf().","code":"url = \"https://raw.githubusercontent.com/ComplexNetTSP/Power_grids/v1.0.0/Countries/Netherlands/graphml/Netherlands_highvoltage.graphml\" igraph::read_graph(url, format = \"graphml\") |> as_tbl_graph() #> # A tbl_graph: 91 nodes and 101 edges #> # #> # An undirected simple graph with 2 components #> # #> # Node Data: 91 × 14 (active) #> netcapacity typ wktsrid4326 lat voltage frequency ngen operator lon #> #> 1 \"\" substat… SRID=4326;… 52.3… 110000 \"\" \"\" \"TenneT\" 6.67… #> 2 \"\" substat… SRID=4326;… 52.2… 110000 \"\" \"\" \"\" 6.83… #> 3 \"\" substat… SRID=4326;… 53.4… 220000 \"\" \"\" \"TenneT\" 6.86… #> 4 \"\" joint SRID=4326;… 53.2… 220000… \"50;50;5… \"\" \"TenneT\" 6.47… #> 5 \"\" joint SRID=4326;… 51.4… 150000… \"50;50;5… \"\" \"TenneT\" 5.62… #> 6 \"\" joint SRID=4326;… 52.4… 150000… \"50;50;5… \"\" \"TenneT\" 4.87… #> 7 \"\" joint SRID=4326;… 52.4… 380000… \"50;50;5… \"\" \"TenneT\" 4.87… #> 8 \"\" substat… SRID=4326;… 52.4… 380000… \"\" \"\" \"TenneT\" 4.87… #> 9 \"\" substat… SRID=4326;… 51.8… 380000 \"\" \"\" \"TenneT\" 4.26… #> 10 \"\" substat… SRID=4326;… 51.6… 380000… \"\" \"\" \"TenneT\" 5.91… #> # ℹ 81 more rows #> # ℹ 5 more variables: ref , source , name , capacity , #> # id #> # #> # Edge Data: 101 × 18 #> from to rohmkm cables wktsrid4326 operator type lengthm voltage frequency #> #> 1 1 52 \"\" 6;3;3… SRID=4326;… \"\" line 49125.… 380000… 50 #> 2 1 21 \"\" 3;3;3… SRID=4326;… \"TenneT\" line 7653.0… 110000… 50;50 #> 3 2 23 \"\" 6;6 SRID=4326;… \"TenneT\" line 6135.3… 380000… 50 #> # ℹ 98 more rows #> # ℹ 8 more variables: cnfkm , fromrelation , ref , name , #> # xohmkm , wires , ithmaxa , lid net = igraph::read_graph(url, format = \"graphml\") |> as_sfnetwork(wkt = \"wktsrid4326\", crs = 4326) |> rename(geometry = wktsrid4326) net #> # A sfnetwork: 91 nodes and 101 edges #> # #> # An undirected simple graph with 2 components and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 3.692428 ymin: 51.14805 xmax: 7.041048 ymax: 53.44424 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 91 × 14 (active) #> netcapacity typ geometry lat voltage frequency ngen #> #> 1 \"\" substation (6.679331 52.32104) 52.3210417… 110000 \"\" \"\" #> 2 \"\" substation (6.830673 52.2139) 52.2139014… 110000 \"\" \"\" #> 3 \"\" substation (6.869683 53.42999) 53.4299869… 220000 \"\" \"\" #> 4 \"\" joint (6.474364 53.21321) 53.2132104… 220000… \"50;50;5… \"\" #> 5 \"\" joint (5.621211 51.45516) 51.4551594… 150000… \"50;50;5… \"\" #> 6 \"\" joint (4.873691 52.42842) 52.4284153… 150000… \"50;50;5… \"\" #> # ℹ 85 more rows #> # ℹ 7 more variables: operator , lon , ref , source , #> # name , capacity , id #> # #> # Edge data: 101 × 18 #> from to rohmkm cables wktsrid4326 operator type lengthm voltage frequency #> #> 1 1 52 \"\" 6;3;3… SRID=4326;… \"\" line 49125.… 380000… 50 #> 2 1 21 \"\" 3;3;3… SRID=4326;… \"TenneT\" line 7653.0… 110000… 50;50 #> 3 2 23 \"\" 6;6 SRID=4326;… \"TenneT\" line 6135.3… 380000… 50 #> # ℹ 98 more rows #> # ℹ 8 more variables: cnfkm , fromrelation , ref , name , #> # xohmkm , wires , ithmaxa , lid net = net |> convert(to_spatial_explicit, wkt = \"wktsrid4326\", crs = 4326, .clean = TRUE) |> activate(edges) |> rename(geometry = wktsrid4326) net #> # A sfnetwork: 91 nodes and 101 edges #> # #> # An undirected simple graph with 2 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 3.692428 ymin: 51.14805 xmax: 7.041048 ymax: 53.44424 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 101 × 18 (active) #> from to rohmkm cables geometry operator type lengthm #> #> 1 1 52 \"\" 6;3;3;3;3 (6.188921 52.53048, 6.67… \"\" line 49125.… #> 2 1 21 \"\" 3;3;3;3;6… (6.768035 52.27755, 6.67… \"TenneT\" line 7653.0… #> 3 2 23 \"\" 6;6 (6.830673 52.2139, 6.760… \"TenneT\" line 6135.3… #> 4 2 13 \"\" 6;6 (6.830673 52.2139, 6.888… \"\" line 4296.2… #> 5 3 53 \"\" 6 (6.869683 53.42999, 6.87… \"\" line 388.82… #> 6 3 70 \"\" 6 (6.869683 53.42999, 6.85… \"\" line 359.61… #> # ℹ 95 more rows #> # ℹ 10 more variables: voltage , frequency , cnfkm , #> # fromrelation , ref , name , xohmkm , wires , #> # ithmaxa , lid #> # #> # Node data: 91 × 14 #> netcapacity typ geometry lat voltage frequency ngen #> #> 1 \"\" substation (6.679331 52.32104) 52.3210417… 110000 \"\" \"\" #> 2 \"\" substation (6.830673 52.2139) 52.2139014… 110000 \"\" \"\" #> 3 \"\" substation (6.869683 53.42999) 53.4299869… 220000 \"\" \"\" #> # ℹ 88 more rows #> # ℹ 7 more variables: operator , lon , ref , source , #> # name , capacity , id ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"from-openstreetmap-data","dir":"Articles","previous_headings":"","what":"From OpenStreetMap data","title":"Creating and representing spatial networks","text":"common source spatial network data OpenStreetMap.open collaborative geographic database. can used example extract geometries streets rivers anywhere world. R, two main packages allow read OpenStreetMap data: osmdata package provides interface Overpass API OpenStreetMap. osmextract package can read OpenStreetMap data osm.pbf files. small areas repeated calls, Overpass API easiest way get data. However, area interest large, want load data many times, preferred overload API read osm.pbf files instead. Geofabrik one platforms can download files many different regions world. , show small example using osmdata. can read street centerlines Anif, small village Austria, shown . details workflow, check osmdata documentation. Now, can simply create network lines using as_sfnetwork(), shown . However, need aware OpenStreetMap data created primarily network structure mind. means locations two streets connect always endpoints linestring geometries, can interior point geometry well. setting subdivide = TRUE linestring geometries subdivided places interior point shared multiple features. way, node placed locations.","code":"library(osmdata) #> Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright # Call the Overpass API to extract streets in Anif. data = opq(\"Anif, Austria\") |> add_osm_feature(key = \"highway\") |> osmdata_sf() |> osm_poly2line() # Extract only the linestring geometries from the response. streets = data$osm_lines |> select(name, \"type\" = highway, surface) streets #> Simple feature collection with 1781 features and 3 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 13.03806 ymin: 47.71134 xmax: 13.08752 ymax: 47.76715 #> Geodetic CRS: WGS 84 #> First 10 features: #> name type surface #> 5205037 Sankt-Leonhard-Straße secondary asphalt #> 13868047 Christophorusstraße residential #> 13868111 Überfuhrstraße unclassified asphalt #> 16300987 motorway_link asphalt #> 16628000 Berchtesgadener Straße primary asphalt #> 20812716 Ursteinsteg cycleway asphalt #> 20812718 Tauernradweg path fine_gravel #> 22767760 motorway_link asphalt #> 22767761 motorway_link asphalt #> 22767763 motorway_link asphalt #> geometry #> 5205037 LINESTRING (13.05769 47.724... #> 13868047 LINESTRING (13.08263 47.746... #> 13868111 LINESTRING (13.08397 47.746... #> 16300987 LINESTRING (13.0515 47.7375... #> 16628000 LINESTRING (13.05344 47.739... #> 20812716 LINESTRING (13.08375 47.725... #> 20812718 LINESTRING (13.08152 47.731... #> 22767760 LINESTRING (13.04707 47.741... #> 22767761 LINESTRING (13.05249 47.738... #> 22767763 LINESTRING (13.05394 47.740... net = as_sfnetwork(streets, directed = FALSE) net #> # A sfnetwork: 2519 nodes and 1781 edges #> # #> # An undirected multigraph with 837 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 13.03806 ymin: 47.71134 xmax: 13.08752 ymax: 47.76715 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 2,519 × 1 (active) #> geometry #> #> 1 (13.05769 47.72452) #> 2 (13.05883 47.72453) #> 3 (13.08263 47.74633) #> 4 (13.08086 47.75767) #> 5 (13.08397 47.74621) #> 6 (13.0515 47.73759) #> # ℹ 2,513 more rows #> # #> # Edge data: 1,781 × 6 #> from to name type surface geometry #> #> 1 1 2 Sankt-Leonhard-Straße secondary asphalt (13.05769 47.72452, 13.0… #> 2 3 4 Christophorusstraße residenti… NA (13.08263 47.74633, 13.0… #> 3 3 5 Überfuhrstraße unclassif… asphalt (13.08397 47.74621, 13.0… #> # ℹ 1,778 more rows # The create network without subdivision has many disconnected components. with_graph(net, graph_component_count()) #> [1] 837 # Creating the network with subdivsion reduces this number drastically. net = as_sfnetwork(streets, subdivide = TRUE) with_graph(net, graph_component_count()) #> [1] 21 ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf() + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"random-networks","dir":"Articles","previous_headings":"","what":"Random networks","title":"Creating and representing spatial networks","text":"function play_geometric() creates random geometric graph. randomly samples nn nodes, connects edge within given distance threshold . default, sampling take place unit square. However, bounds argument can also provide spatial feature sample . use sf::st_sample() internally. Random network Random network B","code":"# Sample on a unit square. neta = play_geometric(10, 0.3) # Sample on a spatial feature. netb = play_geometric(20, set_units(250, \"m\"), bounds = st_bbox(mozart)) ggraph(neta, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(netb, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"validating-sfnetwork-objects","dir":"Articles","previous_headings":"","what":"Validating sfnetwork objects","title":"Creating and representing spatial networks","text":"described beginning, several requirements sfnetwork object considered valid spatial network. validate_network() utility function checks requirements met. checks executed already construction. Trying construct invalid network result error: However, work around setting force = TRUE. skip checks, create sfnetwork object even structure valid. aware functions sfnetworks designed assumption analyzed network valid. issue node edge geometries match (.e. endpoints edges equal nodes supposed source target), utility function make_edges_valid() can fix two different ways: default, replace invalid endpoint edge geometry point geometry node referenced column. set preserve_geometries = TRUE, edge geometries remain unchanged. Invalid endpoints added new nodes network, columns updated accordingly. Invalid network Valid network Valid network B","code":"validate_network(net) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> → Checking edge geometry types ... #> ✔ All edges have geometry type LINESTRING #> → Checking coordinate reference system equality ... #> ✔ Nodes and edges have the same crs #> → Checking coordinate precision equality ... #> ✔ Nodes and edges have the same precision #> → Checking if geometries match ... #> ✔ Node locations match edge boundaries #> ✔ Spatial network structure is valid p1 = st_point(c(6, 52)) p2 = st_point(c(8, 53)) p3 = st_point(c(8, 51)) p4 = st_point(c(7, 52.5)) p5 = st_point(c(7, 52)) l1 = st_linestring(c(p2, p4)) l2 = st_linestring(c(p2, p5)) edges = st_sf(geometry = st_sfc(l1, l2), crs = 4326) nodes = st_sf(geometry = st_sfc(p1, p2, p3), crs = 4326) edges$from = c(2, 2) edges$to = c(1, 3) net = sfnetwork(nodes, edges) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> → Checking edge geometry types ... #> ✔ All edges have geometry type LINESTRING #> → Checking coordinate reference system equality ... #> ✔ Nodes and edges have the same crs #> → Checking coordinate precision equality ... #> ✔ Nodes and edges have the same precision #> → Checking if geometries match ... #> Error in `validate_network()`: #> ! Node locations do not match edge boundaries net = sfnetwork(nodes, edges, force = TRUE) neta = make_edges_valid(net) netb = make_edges_valid(net, preserve_geometries = TRUE) ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(neta, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(netb, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"the-basics","dir":"Articles","previous_headings":"","what":"The basics","title":"Cleaning spatial networks","text":"Functions modify topology network implemented sfnetworks spatial morphers. Network cleaning functions belong family. applications described , sufficient know can use spatial morpher function inside tidygraph::convert() verb convert network new structure. One thing notice tidygraph keeps track original node edge indices columns .tidygraph_node_index .tidygraph_edge_index. want output, add .clean = TRUE tidygraph::convert() call. presenting cleaning functions currently implemented, lets create network cleaned.","code":"p01 = st_point(c(0, 1)) p02 = st_point(c(1, 1)) p03 = st_point(c(2, 1)) p04 = st_point(c(3, 1)) p05 = st_point(c(4, 1)) p06 = st_point(c(3, 2)) p07 = st_point(c(3, 0)) p08 = st_point(c(4, 3)) p09 = st_point(c(4, 2)) p10 = st_point(c(4, 0)) p11 = st_point(c(5, 2)) p12 = st_point(c(5, 0)) p13 = st_point(c(5, -1)) p14 = st_point(c(5.8, 1)) p15 = st_point(c(6, 1.2)) p16 = st_point(c(6.2, 1)) p17 = st_point(c(6, 0.8)) p18 = st_point(c(6, 2)) p19 = st_point(c(6, -1)) p20 = st_point(c(7, 1)) p21 = st_point(c(0, 2)) p22 = st_point(c(0, -1)) l01 = st_sfc(st_linestring(c(p01, p02, p03))) l02 = st_sfc(st_linestring(c(p03, p04, p05))) l03 = st_sfc(st_linestring(c(p06, p04, p07))) l04 = st_sfc(st_linestring(c(p08, p11, p09))) l05 = st_sfc(st_linestring(c(p09, p05, p10))) l06 = st_sfc(st_linestring(c(p08, p09))) l07 = st_sfc(st_linestring(c(p10, p12, p13, p10))) l08 = st_sfc(st_linestring(c(p05, p14))) l09 = st_sfc(st_linestring(c(p15, p14))) l10 = st_sfc(st_linestring(c(p16, p15))) l11 = st_sfc(st_linestring(c(p14, p17))) l12 = st_sfc(st_linestring(c(p17, p16))) l13 = st_sfc(st_linestring(c(p15, p18))) l14 = st_sfc(st_linestring(c(p17, p19))) l15 = st_sfc(st_linestring(c(p16, p20))) l16 = st_sfc(st_linestring(c(p21, p01))) l17 = st_sfc(st_linestring(c(p22, p01))) lines = c( l01, l02, l03, l04, l05, l06, l07, l08, l09, l10, l11, l12, l13, l14, l15 ) edges = st_sf(id = seq_along(lines), geometry = lines) net = as_sfnetwork(edges) |> bind_spatial_nodes(st_sf(geometry = st_sfc(p01, p21, p22))) |> mutate( foo = sample(letters, n(), replace = TRUE), bar = sample(c(1:10), n(), replace = TRUE) ) |> activate(edges) |> bind_spatial_edges(st_sf(from = c(17, 18), to = c(16, 16), geometry = c(l16, l17))) |> mutate( foo = sample(letters, n(), replace = TRUE), bar = sample(c(1:10), n(), replace = TRUE) ) make_ggraph = function(x) { ggraph(x, \"sf\") + geom_edge_sf(aes(color = as.factor(id)), linewidth = 2, show.legend = FALSE) + geom_node_sf(size = 4) + theme_void() } make_ggraph(net)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"simplify-the-network","dir":"Articles","previous_headings":"","what":"Simplify the network","title":"Cleaning spatial networks","text":"network may contain sets edges connect pair nodes. edges can called multiple edges. Also, may contain edge starts ends node. edge can called loop edge. graph theory, simple graph defined graph contain multiple edges loop edges. obtain simple version network, can remove multiple edges loop edges using morpher to_spatial_simple(). re-arranging edges table applying morpher can influence edges kept whenever sets multiple edges detected. example, might want always keep edge shortest distance set.","code":"simple = net |> convert(to_spatial_simple) make_ggraph(net) make_ggraph(simple) simple = net |> activate(edges) |> arrange(edge_length()) |> convert(to_spatial_simple) make_ggraph(net) make_ggraph(simple)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"subdivide-edges","dir":"Articles","previous_headings":"","what":"Subdivide edges","title":"Cleaning spatial networks","text":"constructing sfnetwork set sf linestrings, endpoints linestrings become nodes network. endpoints shared multiple lines, become single node, edges connected. However, linestring geometry can also contain interior points define shape line, endpoints. can happen interior point one edge equal either interior point endpoint another edge. network structure, however, two edges connected, don’t share endpoints. unwanted, need split two edges shared point connect accordingly. graph theory terms process splitting edge called subdivision: subdivision edge o={,b}o = \\{, b\\} (.e. edge node aa node bb) addition new node cc replacement oo two new edges p={,c}p = \\{, c\\} q={c,b}q = \\{c, b\\}. function to_spatial_subdivision() subdivides edges interior points whenever interior points equal one interior points endpoints edges, recalculates network connectivity afterwards. illustrate workflow, lets consider situation interior point pxp_{x} edge xx shared point pyp_{y} edge yy. gives two possible situations: xx subdivided pxp_{x} two new edges x1x_{1} x2x_{2} new node pxp_{x}. yy subdivided pyp_{y} two new edges y1y_{1} y2y_{2} new node pyp_{y}. new nodes pxp_{x} pyp_{y} merged single node pp edge set {x1,x2,y1,y2}\\{x_{1}, x_{2}, y_{1}, y_{2}\\} incidents. xx subdivided pxp_{x} two new edges x1x_{1} x2x_{2} new node pxp_{x}. new node pxp_{x} merged node pyp_{y} single node pp edge set {y,x1,x2}\\{y, x_{1}, x_{2}\\} incidents. Note edge subdivided crosses another edge location interior point endpoint linestring geometry two edges. example network, means:","code":"subdivision = simple |> convert(to_spatial_subdivision) make_ggraph(simple) make_ggraph(subdivision)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"smooth-pseudo-nodes","dir":"Articles","previous_headings":"","what":"Smooth pseudo nodes","title":"Cleaning spatial networks","text":"network may contain nodes one incoming one outgoing edge. tasks like calculating shortest paths, nodes redundant, don’t represent point different directions can possibly taken. Sometimes, type nodes referred pseudo nodes. Note equivalent undirected networks node two incident edges, since incoming outgoing meaning . reduce complexity subsequent operations, might want get rid pseudo nodes. graph theory terms process opposite subdivision also called smoothing: smoothing node bb incident edges o={,b}o = \\{, b\\} p={b,c}p = \\{b, c\\} removes bb, oo pp creates new edge q={,c}q = \\{, c\\}. function to_spatial_smooth() iteratively smooths pseudo nodes, removal concatenates linestring geometries two affected edges together new, single linestring geometry. Pseudo nodes may function representing location certain attribute changes. example, point street different surface type. require_equal argument allows specify one edge attributes checked equality removing pseudo node. attributes equal, node removed, , remain. argument value evaluated using tidy selection, meaning can specify column names unquoted, also use selection helpers. to_spatial_smooth() morpher also allows specify want combine attributes concatenated edges. done attribute_summary argument. attributes combined course dependent type purpose attribute. Therefore, combination technique can specified per-attribute basis. two ways specify combination technique attribute: character, referring name pre-defined combination technique igraph. Examples include mean, sum, first last. See overview implemented techniques. function, taking vector attribute values input returning single value. helpful want combine attributes way pre-defined. Providing single character single function (e.g. attribute_summary = \"sum\") apply technique attribute. Instead, can provide named list different technique attribute. list can also include one unnamed element containing technique applied attributes referenced elements. Note geometry-list column, tidygraph index columns, well columns considered attributes!","code":"smooth = subdivision |> convert(to_spatial_smooth) make_ggraph(subdivision) make_ggraph(smooth) # Only smooth pseudo nodes if incident edges have the same value for \"foo\". smooth_b = net |> convert(to_spatial_smooth, require_equal = foo) # Only smooth pseudo nodes if incident edges have the same value for all attributes. smooth_c = net |> convert(to_spatial_smooth, require_equal = everything()) smooth_d = subdivision |> convert( to_spatial_smooth, attribute_summary = list(foo = paste, bar = \"sum\") ) smooth_d #> # A sfnetwork: 17 nodes and 16 edges #> # #> # A directed simple graph with 2 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: -1 xmax: 7 ymax: 3 #> # CRS: NA #> # #> # Edge data: 16 × 7 (active) #> from to id foo bar .tidygraph_edge_index geometry #> #> 1 17 2 2 10 (3 1, 4 1) #> 2 2 7 8 8 (4 1, 5.8 1) #> 3 3 17 3 10 (3 2, 3 1) #> 4 17 4 3 10 (3 1, 3 0) #> 5 2 6 5 5 (4 1, 4 0) #> 6 7 10 11 6 (5.8 1, 6 0.8) #> # ℹ 10 more rows #> # #> # Node data: 17 × 4 #> geometry foo bar .tidygraph_node_index #> #> 1 (0 1) g 6 1 #> 2 (4 1) n 1 3 #> 3 (3 2) r 2 4 #> # ℹ 14 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"require-equal-attributes","dir":"Articles","previous_headings":"","what":"Require equal attributes","title":"Cleaning spatial networks","text":"Pseudo nodes may function representing location certain attribute changes. example, point street different surface type. require_equal argument allows specify one edge attributes checked equality removing pseudo node. attributes equal, node removed, , remain. argument value evaluated using tidy selection, meaning can specify column names unquoted, also use selection helpers.","code":"# Only smooth pseudo nodes if incident edges have the same value for \"foo\". smooth_b = net |> convert(to_spatial_smooth, require_equal = foo) # Only smooth pseudo nodes if incident edges have the same value for all attributes. smooth_c = net |> convert(to_spatial_smooth, require_equal = everything())"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"summarize-attribute-values","dir":"Articles","previous_headings":"","what":"Summarize attribute values","title":"Cleaning spatial networks","text":"to_spatial_smooth() morpher also allows specify want combine attributes concatenated edges. done attribute_summary argument. attributes combined course dependent type purpose attribute. Therefore, combination technique can specified per-attribute basis. two ways specify combination technique attribute: character, referring name pre-defined combination technique igraph. Examples include mean, sum, first last. See overview implemented techniques. function, taking vector attribute values input returning single value. helpful want combine attributes way pre-defined. Providing single character single function (e.g. attribute_summary = \"sum\") apply technique attribute. Instead, can provide named list different technique attribute. list can also include one unnamed element containing technique applied attributes referenced elements. Note geometry-list column, tidygraph index columns, well columns considered attributes!","code":"smooth_d = subdivision |> convert( to_spatial_smooth, attribute_summary = list(foo = paste, bar = \"sum\") ) smooth_d #> # A sfnetwork: 17 nodes and 16 edges #> # #> # A directed simple graph with 2 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: -1 xmax: 7 ymax: 3 #> # CRS: NA #> # #> # Edge data: 16 × 7 (active) #> from to id foo bar .tidygraph_edge_index geometry #> #> 1 17 2 2 10 (3 1, 4 1) #> 2 2 7 8 8 (4 1, 5.8 1) #> 3 3 17 3 10 (3 2, 3 1) #> 4 17 4 3 10 (3 1, 3 0) #> 5 2 6 5 5 (4 1, 4 0) #> 6 7 10 11 6 (5.8 1, 6 0.8) #> # ℹ 10 more rows #> # #> # Node data: 17 × 4 #> geometry foo bar .tidygraph_node_index #> #> 1 (0 1) g 6 1 #> 2 (4 1) n 1 3 #> 3 (3 2) r 2 4 #> # ℹ 14 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"simplify-intersections","dir":"Articles","previous_headings":"","what":"Simplify intersections","title":"Cleaning spatial networks","text":"Especially road networks may find intersections edges modeled single node. Instead, leg intersection dedicated edge. simplify topology network, might want reduce complex intersection structures single node. Hence, want reduce group nodes single node, maintaining connectivity network. graph theory terms process called contraction: contraction set nodes P={p1,p2,...,pn}P = \\{p_{1}, p_{2}, ..., p_{n}\\} replacement SS incident edges single node p*p^{*} set edges connect p*p^{*} nodes adjacent node pi∈Pp_{} \\P. morpher to_spatial_contracted() contracts groups nodes based given grouping variable. geometry contracted node (default) centroid original group members’ geometries. Moreover, geometries edges start end contracted node updated boundaries match new node geometries. Grouping variables internally forwarded dplyr::group_by(). means can group nodes based (combination ) attribute(s). However, case, want group nodes spatially, nodes close space form group get contracted. Spatial grouping nodes can done group_spatial_dbscan() function, exposes DBSCAN clustering algorithm dbscan package. main parameter ϵ\\epsilon defines radius neighborhood node meters. default, based network distance rather euclidean distance.","code":"contraction = smooth |> activate(nodes) |> convert(to_spatial_contracted, group_spatial_dbscan(0.5)) make_ggraph(smooth) make_ggraph(contraction)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"merge-nodes-at-equal-locations","dir":"Articles","previous_headings":"","what":"Merge nodes at equal locations","title":"Cleaning spatial networks","text":"attentive reader may noticed network still consists two disconnected components, caused fact two seperate nodes exactly location. to_spatial_unique() morpher implements special variation node contraction: contracts nodes share spatial location. incident edges contracted nodes become incident new node. Visually see difference, now reduced number components 1: to_spatial_unique() morpher also allows specify want combine attributes contracted nodes. done attribute_summary argument works explained to_spatial_smooth().","code":"st_equals(contraction) #> Sparse geometry binary predicate list of length 14, where the predicate #> was `equals' #> first 10 elements: #> 1: 1 #> 2: 2, 11 #> 3: 3 #> 4: 4 #> 5: 5 #> 6: 6 #> 7: 7 #> 8: 8 #> 9: 9 #> 10: 10 with_graph(contraction, graph_component_count()) #> [1] 2 unique = contraction |> convert(to_spatial_unique) make_ggraph(contraction) make_ggraph(unique) with_graph(unique, graph_component_count()) #> [1] 1 # Plot components before and after. contraction |> mutate(comp = group_components()) |> activate(edges) |> mutate(comp = .N()$comp[from]) |> ggraph(\"sf\") + geom_edge_sf(aes(color = as.factor(comp)), linewidth = 2, show.legend = FALSE) + geom_node_sf(size = 4) + theme_void() unique |> mutate(comp = group_components()) |> activate(edges) |> mutate(comp = .N()$comp[from]) |> ggraph(\"sf\") + geom_edge_sf(aes(color = as.factor(comp)), linewidth = 2, show.legend = FALSE) + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"overview","dir":"Articles","previous_headings":"","what":"Overview","title":"Cleaning spatial networks","text":"single pipeline, can clean dirty network follows.","code":"clean = net |> activate(edges) |> arrange(edge_length()) |> activate(nodes) |> convert(to_spatial_simple) |> convert(to_spatial_subdivision) |> convert(to_spatial_smooth) |> convert(to_spatial_contracted, group_spatial_dbscan(0.5)) |> convert(to_spatial_unique) make_ggraph(net) make_ggraph(clean)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"non-tidyverse-workflow","dir":"Articles","previous_headings":"","what":"Non-tidyverse workflow","title":"Cleaning spatial networks","text":"cleaning morphers internal worker exported well. can used want work outside “tidy workflow”. cleaning operation can done follows:","code":"simple = simplify_network(net) subdivision = subdivide_edges(simple) smooth = smooth_pseudo_nodes(subdivision) groups = with_graph(smooth, group_spatial_dbscan(0.5)) contraction = contract_nodes(smooth, groups) unique = contract_nodes(contraction, st_match(st_geometry(net))) make_ggraph(net) make_ggraph(unique)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"spatial-filters","dir":"Articles","previous_headings":"","what":"Spatial filters","title":"Spatial joins and filters","text":"Information can filtered network using spatial predicate functions inside sf function sf::st_filter(), works follows: function applied set geometries respect another set geometries B, removes features based spatial relation features B. practical example: using predicate intersects, geometries intersect geometry B removed. applying sf::st_filter() sfnetwork, internally applied active element network. example: filtering information network activated nodes, using set polygons B predicate intersects, remove nodes intersect polygons B network. edges active, remove edges intersect polygons B network. Although filter applied active element network, may also affect element. nodes removed, incident edges removed well. However, edges removed, nodes endpoints remain, even don’t incident edges. behavior inherited tidygraph understandable graph theory point view: definition nodes can exist peacefully isolation, edges can never exist without nodes endpoints. isolated nodes remain filtering edges can easily removed using combination regular dplyr::filter() verb tidygraph::node_is_isolated() query function. Original network Filtered nodes Filtered edges Removed isolated nodes non-spatial filters applied attribute columns, simply use dplyr::filter() instead sf::st_filter(). tidygraph, filtering information networks done using specific node edge query functions inside dplyr::filter() verb. example already shown , isolated nodes removed network. sfnetworks, several spatial predicates implemented node edge query functions can also spatial filtering tidygraph style. See list implemented spatial node query functions, spatial edge query functions. Using makes spatial filter operations fit better tidy workflows tidygraph. example, filter edges cross edge. tidygraph::.E() function used example makes possible directly access complete edges table inside verbs. Similarly, can use tidygraph::.N() access nodes table tidygraph::.G() access network object whole. Original network Filtered network Besides predicate query functions, can also use coordinate query functions spatial filters nodes. example: Original network Filtered network Filtering returns subset original geometries, leaves geometries unchanged. different clipping, get cut border provided clip feature. three ways can : sf::st_intersection() keeps parts original geometries lie within clip feature, sf::st_difference() keeps parts original geometries lie outside clip feature, sf::st_crop() keeps parts original geometries lie within bounding box clip feature. Note case nodes, clipping different filtering, since point geometries fall party inside partly outside another feature. However, case edges, clipping cut linestring geometries edges border clip feature (case cropping, bounding box feature). preserve valid spatial network structure, sfnetworks adds new nodes cut locations. Original network Filtered Clipped","code":"net = as_sfnetwork(mozart, \"gabriel\") ply = st_buffer(st_centroid(st_combine(mozart)), 300) filtered_by_nodes = net |> st_filter(ply, .pred = st_intersects) filtered_by_edges_a = net |> activate(edges) |> st_filter(ply, .pred = st_intersects) filtered_by_edges_b = net |> activate(edges) |> st_filter(ply, .pred = st_intersects) |> activate(nodes) |> filter(!node_is_isolated()) ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_nodes, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_edges_a, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_edges_b, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() complete_net = as_sfnetwork(mozart, \"complete\") filtered = complete_net |> activate(edges) |> filter(!edge_crosses(.E())) |> activate(nodes) |> filter(!node_is_isolated()) ggraph(complete_net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(filtered, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() x = 4549358 filtered_by_coords = net |> filter(node_X() > x) ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_vline(xintercept = x, linewidth = 1, color = \"orange\") + theme_void() ggraph(filtered_by_coords, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_vline(xintercept = x, linewidth = 1, color = \"orange\") + theme_void() clipped = net |> activate(edges) |> st_intersection(ply) |> activate(nodes) |> filter(!node_is_isolated()) #> Warning: attribute variables are assumed to be spatially constant throughout #> all geometries ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_edges_b, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(clipped, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"using-st_filter","dir":"Articles","previous_headings":"","what":"Using st_filter","title":"Spatial joins and filters","text":"Information can filtered network using spatial predicate functions inside sf function sf::st_filter(), works follows: function applied set geometries respect another set geometries B, removes features based spatial relation features B. practical example: using predicate intersects, geometries intersect geometry B removed. applying sf::st_filter() sfnetwork, internally applied active element network. example: filtering information network activated nodes, using set polygons B predicate intersects, remove nodes intersect polygons B network. edges active, remove edges intersect polygons B network. Although filter applied active element network, may also affect element. nodes removed, incident edges removed well. However, edges removed, nodes endpoints remain, even don’t incident edges. behavior inherited tidygraph understandable graph theory point view: definition nodes can exist peacefully isolation, edges can never exist without nodes endpoints. isolated nodes remain filtering edges can easily removed using combination regular dplyr::filter() verb tidygraph::node_is_isolated() query function. Original network Filtered nodes Filtered edges Removed isolated nodes non-spatial filters applied attribute columns, simply use dplyr::filter() instead sf::st_filter().","code":"net = as_sfnetwork(mozart, \"gabriel\") ply = st_buffer(st_centroid(st_combine(mozart)), 300) filtered_by_nodes = net |> st_filter(ply, .pred = st_intersects) filtered_by_edges_a = net |> activate(edges) |> st_filter(ply, .pred = st_intersects) filtered_by_edges_b = net |> activate(edges) |> st_filter(ply, .pred = st_intersects) |> activate(nodes) |> filter(!node_is_isolated()) ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_nodes, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_edges_a, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_edges_b, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"using-spatial-node-and-edge-query-functions","dir":"Articles","previous_headings":"","what":"Using spatial node and edge query functions","title":"Spatial joins and filters","text":"tidygraph, filtering information networks done using specific node edge query functions inside dplyr::filter() verb. example already shown , isolated nodes removed network. sfnetworks, several spatial predicates implemented node edge query functions can also spatial filtering tidygraph style. See list implemented spatial node query functions, spatial edge query functions. Using makes spatial filter operations fit better tidy workflows tidygraph. example, filter edges cross edge. tidygraph::.E() function used example makes possible directly access complete edges table inside verbs. Similarly, can use tidygraph::.N() access nodes table tidygraph::.G() access network object whole. Original network Filtered network Besides predicate query functions, can also use coordinate query functions spatial filters nodes. example: Original network Filtered network","code":"complete_net = as_sfnetwork(mozart, \"complete\") filtered = complete_net |> activate(edges) |> filter(!edge_crosses(.E())) |> activate(nodes) |> filter(!node_is_isolated()) ggraph(complete_net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(filtered, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() x = 4549358 filtered_by_coords = net |> filter(node_X() > x) ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_vline(xintercept = x, linewidth = 1, color = \"orange\") + theme_void() ggraph(filtered_by_coords, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_vline(xintercept = x, linewidth = 1, color = \"orange\") + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"clipping","dir":"Articles","previous_headings":"","what":"Clipping","title":"Spatial joins and filters","text":"Filtering returns subset original geometries, leaves geometries unchanged. different clipping, get cut border provided clip feature. three ways can : sf::st_intersection() keeps parts original geometries lie within clip feature, sf::st_difference() keeps parts original geometries lie outside clip feature, sf::st_crop() keeps parts original geometries lie within bounding box clip feature. Note case nodes, clipping different filtering, since point geometries fall party inside partly outside another feature. However, case edges, clipping cut linestring geometries edges border clip feature (case cropping, bounding box feature). preserve valid spatial network structure, sfnetworks adds new nodes cut locations. Original network Filtered Clipped","code":"clipped = net |> activate(edges) |> st_intersection(ply) |> activate(nodes) |> filter(!node_is_isolated()) #> Warning: attribute variables are assumed to be spatially constant throughout #> all geometries ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_edges_b, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(clipped, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"spatial-joins","dir":"Articles","previous_headings":"","what":"Spatial joins","title":"Spatial joins and filters","text":"Information can spatially joined network using spatial predicate functions inside sf function sf::st_join(), works follows: function applied set geometries respect another set geometries B, attaches feature attributes features B features based spatial relation. practical example: using predicate intersects, feature attributes feature y B attached feature x whenever x intersects y. applying sf::st_join() sfnetwork object, internally applied active element network. example: joining information network activated nodes, set polygons B using predicate intersects, attach attributes polygon B nodes intersect specific polygon. edges active, attach information intersecting edges instead. Lets show example first create imaginary postal code areas Mozart dataset. Original network postal codes Network joined information example , polygons spatially distinct. Hence, node can intersect single polygon. happen join polygons overlap? attributes polygon attached node intersects multiple polygons ? sf issue solved duplicating point much times number polygons intersects , attaching attributes intersecting polygon one duplicates. approach fit network case, however. edge can single node endpoints, thus, duplicated nodes isolated redundant network structure. Therefore, sfnetworks join information first match whenever multiple matches single node. warning given case aware fact information joined network. set ignore_multiple = FALSE, multiple matches result duplicated nodes, duplicates isolated (.e. connected rest network). can use morpher to_spatial_unique() merge spatially duplicated nodes one, specifying attributes combined. See example. Note case joining edges, multiple matches per edge problem network structure. simply duplicate edge (.e. creating set parallel edges) whenever occurs. non-spatial joins based attribute columns, simply use join function dplyr (e.g. dplyr::left_join() dplyr::inner_join()) instead sf::st_join(). Another network specific use-case spatial joins join information external points interest (POIs) nodes network. However, , points need exactly equal coordinates one nodes. Often case. solve situations, first need update coordinates POIs match nearest node. can done using st_project_on_network(). Original network POIs POIs snapped network snapping POIs, can use sf::st_join() expected. remember multiple POIs snapped node, information first one joined network, unless set ignore_multiple = FALSE. example , makes sense include information first POI already existing node. second POI, however, nearest node quite far away relative nearest location nearest edge. case, might want split edge location, add new node network. combination process use metaphor throwing network POIs together blender, mix smoothly together. function st_network_blend() exactly . POI, finds nearest location pp nearest edge ee. pp already existing node (.e. pp endpoint ee), joins information POI node. pp already existing node, subdivides ee pp, adds pp new node network, joins information POI new node. process, matter pp interior point linestring geometry ee. Original network POIs POIs blended network st_network_blend() function tolerance parameter, defines maximum distance POI can network order blended . Hence, POIs least close network tolerance distance blended, others ignored. tolerance can specified non-negative number. default assumed units meters, behavior can changed manually setting units units::units(). Blend without tolerance Blend tolerance important details aware using st_network_blend(). Firstly: multiple POIs nearest location nearest edge, first blended network. reasons explained : network structure clear approach dealing duplicated nodes. arranging table POIs dplyr::arrange() blending can influence (type ) POI given priority cases. also option set ignore_duplicates = FALSE. , duplicated projections result duplicated nodes, duplicates isolated (.e. connected rest network). can use morpher to_spatial_unique() merge spatially duplicated nodes one, specifying attributes combined. See example. Secondly: single POI multiple nearest edges, blended first edges. Therefore, might good idea run to_spatial_subdivision() morpher blending, intersecting unconnected edges get connected. Lastly: important aware floating point precision. See discussion GitHub issue background. short: due internal rounding rational numbers R actually possible even intersection point two lines evaluated intersecting lines . Sounds confusing? ! see example : : expect intersection edge blended network even set tolerance = 0, fact always happen. avoid problems, can better set tolerance small number instead zero. examples joining information external features network. joining two networks? st_network_join() function . takes two sfnetworks input makes spatial full join geometries nodes data, based equals spatial predicate. means, nodes network x nodes network y present joined network, nodes x equal geometries nodes y, nodes become single node joined network. Edge data combined using dplyr::bind_rows() semantic, meaning data matched column name values filled NA missing either networks. columns edge data updated automatically correctly match new node indices joined network. spatial join performed edges. Hence, edge x equal geometry edge y, remain separate edges joined network. Two networks Joined network","code":"codes = net |> st_make_grid(n = c(2, 2)) |> st_as_sf() |> mutate(code = as.character(seq(1000, 1000 + n() * 10 - 10, 10))) joined = net |> st_join(codes, join = st_intersects) joined #> # A sfnetwork: 17 nodes and 50 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 5 (active) #> name type website geometry code #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) 1010 #> 2 Haus für Mozart theatre NA (4549003 2747376) 1000 #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 1010 #> 4 Mozart Denkmal artwork NA (4549387 2747514) 1010 #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 1010 #> 6 Mozartsteg bridge NA (4549473 2747624) 1010 #> # ℹ 11 more rows #> # #> # Edge data: 50 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 1 4 (4549504 2747309, 4549387 2747514) #> 3 2 4 (4549003 2747376, 4549387 2747514) #> # ℹ 47 more rows ggraph(net, \"sf\") + geom_sf(data = codes, aes(fill = code)) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(joined, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = code), size = 4) + theme_void() box = st_as_sfc(st_bbox(mozart)) two_equal_polys = st_as_sf(c(box, box)) |> mutate(foo = c(\"a\", \"b\")) # Join on nodes gives a warning that only the first match per node is joined. # The number of nodes in the resulting network remains the same. net |> st_join(two_equal_polys, join = st_intersects) #> Warning: [1m[22m`st_join()` did not join all features. #> [33m![39m Multiple matches were detected for some nodes, of which all but the first one #> are ignored. #> [36mℹ[39m If you want to add multiple matches as isolated nodes instead, set #> `ignore_multiple` to `FALSE`. #> # A sfnetwork: 17 nodes and 50 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 5 (active) #> name type website geometry foo #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) a #> 2 Haus für Mozart theatre NA (4549003 2747376) a #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) a #> 4 Mozart Denkmal artwork NA (4549387 2747514) a #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) a #> 6 Mozartsteg bridge NA (4549473 2747624) a #> # ℹ 11 more rows #> # #> # Edge data: 50 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 1 4 (4549504 2747309, 4549387 2747514) #> 3 2 4 (4549003 2747376, 4549387 2747514) #> # ℹ 47 more rows # With these settings multiple matches result in duplicated nodes. # In this example it means we have twice the number of nodes than before. # The duplicated nodes are isolated, i.e. not connected to any other node. net |> st_join(two_equal_polys, join = st_intersects, ignore_multiple = FALSE) #> Warning: [1m[22m`st_join()` created isolated nodes. #> [33m![39m Multiple matches were detected for some nodes, of which all but the first one #> are added as isolated nodes to the network. #> [36mℹ[39m If you want to ignore multiple matches instead, set `ignore_multiple` to #> `TRUE`. #> # A sfnetwork: 34 nodes and 50 edges #> # #> # A bipartite simple graph with 18 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 34 × 5 (active) #> name type website foo geometry #> #> 1 Mozartkino cinema https://www.mo… a (4549504 2747309) #> 2 Haus für Mozart theatre NA a (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA a (4549589 2747507) #> 4 Mozart Denkmal artwork NA a (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA a (4549491 2747551) #> 6 Mozartsteg bridge NA a (4549473 2747624) #> # ℹ 28 more rows #> # #> # Edge data: 50 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 1 4 (4549504 2747309, 4549387 2747514) #> 3 2 4 (4549003 2747376, 4549387 2747514) #> # ℹ 47 more rows # Join on edges duplicates edges that have multiple matches. # The number of edges in the resulting network is higher than in the original. net |> activate(edges) |> st_join(two_equal_polys, join = st_intersects) #> # A sfnetwork: 17 nodes and 100 edges #> # #> # A bipartite multigraph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 100 × 4 (active) #> from to geometry foo #> #> 1 1 3 (4549504 2747309, 4549589 2747507) a #> 2 1 3 (4549504 2747309, 4549589 2747507) b #> 3 1 4 (4549504 2747309, 4549387 2747514) a #> 4 1 4 (4549504 2747309, 4549387 2747514) b #> 5 2 4 (4549003 2747376, 4549387 2747514) a #> 6 2 4 (4549003 2747376, 4549387 2747514) b #> # ℹ 94 more rows #> # #> # Node data: 17 × 4 #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> # ℹ 14 more rows # Create a network. n1 = st_point(c(0, 0)) n2 = st_point(c(1, 0)) net = st_sf(geometry = st_sfc(st_linestring(c(n1, n2)))) |> as_sfnetwork() # Create a set of POIs. p1 = st_point(c(0, 0.2)) p2 = st_point(c(0.6, 0.2)) pois = st_sf( poi_type = c(\"bakery\", \"butcher\"), geometry = st_sfc(p1, p2) ) # Update coordinates of POIs to match their nearest node. ppois = st_project_on_network(pois, net, on = \"nodes\") ggraph(net, \"sf\") + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(net, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(ppois)), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf( data = ppois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + theme_void() st_join(net, ppois) #> # A sfnetwork: 2 nodes and 1 edges #> # #> # A rooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 1 ymax: 0 #> # CRS: NA #> # #> # Node data: 2 × 2 (active) #> geometry poi_type #> #> 1 (0 0) bakery #> 2 (1 0) butcher #> # #> # Edge data: 1 × 3 #> from to geometry #> #> 1 1 2 (0 0, 1 0) blend = st_network_blend(net, pois) blend #> # A sfnetwork: 3 nodes and 2 edges #> # #> # A rooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 1 ymax: 0 #> # CRS: NA #> # #> # Node data: 3 × 2 (active) #> geometry poi_type #> #> 1 (0 0) bakery #> 2 (1 0) NA #> 3 (0.6 0) butcher #> # #> # Edge data: 2 × 3 #> from to geometry #> #> 1 1 3 (0 0, 0.6 0) #> 2 3 2 (0.6 0, 1 0) ggraph(net, \"sf\") + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(blend, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() # Update the POIs. p3 = st_point(c(0.4, 0.3)) pois = st_sf( poi_type = c(\"bakery\", \"butcher\", \"bar\"), geometry = st_sfc(p1, p2, p3) ) blend = st_network_blend(net, pois) blend_with_tolerance = st_network_blend(net, pois, tolerance = 0.2) ggraph(blend, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(blend_with_tolerance, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() # Create two intersecting lines. p1 = st_point(c(0.53236, 1.95377)) p2 = st_point(c(0.53209, 1.95328)) l1 = st_sfc(st_linestring(c(p1, p2))) p3 = st_point(c(0.53209, 1.95345)) p4 = st_point(c(0.53245, 1.95345)) l2 = st_sfc(st_linestring(c(p3, p4))) # The two lines share an intersection point. st_intersection(l1, l2) #> Geometry set for 1 feature #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 0.5321837 ymin: 1.95345 xmax: 0.5321837 ymax: 1.95345 #> CRS: NA #> POINT (0.5321837 1.95345) # But this intersection point does not intersects the line itself! st_intersects(l1, st_intersection(l1, l2), sparse = FALSE) #> [,1] #> [1,] FALSE # The intersection point is instead located a tiny bit next to the line. st_distance(l1, st_intersection(l1, l2)) #> [,1] #> [1,] 4.310191e-17 net = as_sfnetwork(l1) p = st_intersection(l1, l2) plot(l1) plot(l2, col = \"grey\", lwd = 2, add = TRUE) plot(st_network_blend(net, p, tolerance = 0), lwd = 2, cex = 2, add = TRUE) #> Warning: [1m[22m`st_network_blend()` did not blend any points into the network. #> [36mℹ[39m Increase `tolerance` for a higher tolerance distance. plot(l1) plot(l2, col = \"grey\", lwd = 2, add = TRUE) plot(st_network_blend(net, p, tolerance = 1e-10), lwd = 2, cex = 2, add = TRUE) # Create two networks. # Create a network. n1 = st_point(c(0, 0)) n2 = st_point(c(1, 0)) n3 = st_point(c(1, 1)) n4 = st_point(c(0, 1)) e1 = st_sfc(st_linestring(c(n1, n2))) e2 = st_sfc(st_linestring(c(n2, n3))) e3 = st_sfc(st_linestring(c(n3, n4))) neta = st_sf(geometry = c(e1, e2)) |> as_sfnetwork() netb = st_sf(geometry = c(e2, e3)) |> as_sfnetwork() # Join them into a single network. joined = st_network_join(neta, netb) joined #> # A sfnetwork: 4 nodes and 4 edges #> # #> # A directed acyclic multigraph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 1 ymax: 1 #> # CRS: NA #> # #> # Node data: 4 × 1 (active) #> geometry #> #> 1 (0 0) #> 2 (1 0) #> 3 (1 1) #> 4 (0 1) #> # #> # Edge data: 4 × 3 #> from to geometry #> #> 1 1 2 (0 0, 1 0) #> 2 2 3 (1 0, 1 1) #> 3 2 3 (1 0, 1 1) #> # ℹ 1 more row plot(neta, col = \"skyblue\", pch = 15, cex = 2, lwd = 4) plot(netb, col = \"orange\", pch = 18, cex = 2, lty = 2, lwd = 4, add = TRUE) plot(joined, cex = 2, lwd = 4)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"using-st_join","dir":"Articles","previous_headings":"","what":"Using st_join","title":"Spatial joins and filters","text":"Information can spatially joined network using spatial predicate functions inside sf function sf::st_join(), works follows: function applied set geometries respect another set geometries B, attaches feature attributes features B features based spatial relation. practical example: using predicate intersects, feature attributes feature y B attached feature x whenever x intersects y. applying sf::st_join() sfnetwork object, internally applied active element network. example: joining information network activated nodes, set polygons B using predicate intersects, attach attributes polygon B nodes intersect specific polygon. edges active, attach information intersecting edges instead. Lets show example first create imaginary postal code areas Mozart dataset. Original network postal codes Network joined information example , polygons spatially distinct. Hence, node can intersect single polygon. happen join polygons overlap? attributes polygon attached node intersects multiple polygons ? sf issue solved duplicating point much times number polygons intersects , attaching attributes intersecting polygon one duplicates. approach fit network case, however. edge can single node endpoints, thus, duplicated nodes isolated redundant network structure. Therefore, sfnetworks join information first match whenever multiple matches single node. warning given case aware fact information joined network. set ignore_multiple = FALSE, multiple matches result duplicated nodes, duplicates isolated (.e. connected rest network). can use morpher to_spatial_unique() merge spatially duplicated nodes one, specifying attributes combined. See example. Note case joining edges, multiple matches per edge problem network structure. simply duplicate edge (.e. creating set parallel edges) whenever occurs. non-spatial joins based attribute columns, simply use join function dplyr (e.g. dplyr::left_join() dplyr::inner_join()) instead sf::st_join().","code":"codes = net |> st_make_grid(n = c(2, 2)) |> st_as_sf() |> mutate(code = as.character(seq(1000, 1000 + n() * 10 - 10, 10))) joined = net |> st_join(codes, join = st_intersects) joined #> # A sfnetwork: 17 nodes and 50 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 5 (active) #> name type website geometry code #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) 1010 #> 2 Haus für Mozart theatre NA (4549003 2747376) 1000 #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 1010 #> 4 Mozart Denkmal artwork NA (4549387 2747514) 1010 #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 1010 #> 6 Mozartsteg bridge NA (4549473 2747624) 1010 #> # ℹ 11 more rows #> # #> # Edge data: 50 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 1 4 (4549504 2747309, 4549387 2747514) #> 3 2 4 (4549003 2747376, 4549387 2747514) #> # ℹ 47 more rows ggraph(net, \"sf\") + geom_sf(data = codes, aes(fill = code)) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(joined, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = code), size = 4) + theme_void() box = st_as_sfc(st_bbox(mozart)) two_equal_polys = st_as_sf(c(box, box)) |> mutate(foo = c(\"a\", \"b\")) # Join on nodes gives a warning that only the first match per node is joined. # The number of nodes in the resulting network remains the same. net |> st_join(two_equal_polys, join = st_intersects) #> Warning: [1m[22m`st_join()` did not join all features. #> [33m![39m Multiple matches were detected for some nodes, of which all but the first one #> are ignored. #> [36mℹ[39m If you want to add multiple matches as isolated nodes instead, set #> `ignore_multiple` to `FALSE`. #> # A sfnetwork: 17 nodes and 50 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 5 (active) #> name type website geometry foo #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) a #> 2 Haus für Mozart theatre NA (4549003 2747376) a #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) a #> 4 Mozart Denkmal artwork NA (4549387 2747514) a #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) a #> 6 Mozartsteg bridge NA (4549473 2747624) a #> # ℹ 11 more rows #> # #> # Edge data: 50 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 1 4 (4549504 2747309, 4549387 2747514) #> 3 2 4 (4549003 2747376, 4549387 2747514) #> # ℹ 47 more rows # With these settings multiple matches result in duplicated nodes. # In this example it means we have twice the number of nodes than before. # The duplicated nodes are isolated, i.e. not connected to any other node. net |> st_join(two_equal_polys, join = st_intersects, ignore_multiple = FALSE) #> Warning: [1m[22m`st_join()` created isolated nodes. #> [33m![39m Multiple matches were detected for some nodes, of which all but the first one #> are added as isolated nodes to the network. #> [36mℹ[39m If you want to ignore multiple matches instead, set `ignore_multiple` to #> `TRUE`. #> # A sfnetwork: 34 nodes and 50 edges #> # #> # A bipartite simple graph with 18 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 34 × 5 (active) #> name type website foo geometry #> #> 1 Mozartkino cinema https://www.mo… a (4549504 2747309) #> 2 Haus für Mozart theatre NA a (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA a (4549589 2747507) #> 4 Mozart Denkmal artwork NA a (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA a (4549491 2747551) #> 6 Mozartsteg bridge NA a (4549473 2747624) #> # ℹ 28 more rows #> # #> # Edge data: 50 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 1 4 (4549504 2747309, 4549387 2747514) #> 3 2 4 (4549003 2747376, 4549387 2747514) #> # ℹ 47 more rows # Join on edges duplicates edges that have multiple matches. # The number of edges in the resulting network is higher than in the original. net |> activate(edges) |> st_join(two_equal_polys, join = st_intersects) #> # A sfnetwork: 17 nodes and 100 edges #> # #> # A bipartite multigraph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 100 × 4 (active) #> from to geometry foo #> #> 1 1 3 (4549504 2747309, 4549589 2747507) a #> 2 1 3 (4549504 2747309, 4549589 2747507) b #> 3 1 4 (4549504 2747309, 4549387 2747514) a #> 4 1 4 (4549504 2747309, 4549387 2747514) b #> 5 2 4 (4549003 2747376, 4549387 2747514) a #> 6 2 4 (4549003 2747376, 4549387 2747514) b #> # ℹ 94 more rows #> # #> # Node data: 17 × 4 #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> # ℹ 14 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"join-points-to-their-nearest-node","dir":"Articles","previous_headings":"","what":"Join points to their nearest node","title":"Spatial joins and filters","text":"Another network specific use-case spatial joins join information external points interest (POIs) nodes network. However, , points need exactly equal coordinates one nodes. Often case. solve situations, first need update coordinates POIs match nearest node. can done using st_project_on_network(). Original network POIs POIs snapped network snapping POIs, can use sf::st_join() expected. remember multiple POIs snapped node, information first one joined network, unless set ignore_multiple = FALSE.","code":"# Create a network. n1 = st_point(c(0, 0)) n2 = st_point(c(1, 0)) net = st_sf(geometry = st_sfc(st_linestring(c(n1, n2)))) |> as_sfnetwork() # Create a set of POIs. p1 = st_point(c(0, 0.2)) p2 = st_point(c(0.6, 0.2)) pois = st_sf( poi_type = c(\"bakery\", \"butcher\"), geometry = st_sfc(p1, p2) ) # Update coordinates of POIs to match their nearest node. ppois = st_project_on_network(pois, net, on = \"nodes\") ggraph(net, \"sf\") + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(net, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(ppois)), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf( data = ppois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + theme_void() st_join(net, ppois) #> # A sfnetwork: 2 nodes and 1 edges #> # #> # A rooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 1 ymax: 0 #> # CRS: NA #> # #> # Node data: 2 × 2 (active) #> geometry poi_type #> #> 1 (0 0) bakery #> 2 (1 0) butcher #> # #> # Edge data: 1 × 3 #> from to geometry #> #> 1 1 2 (0 0, 1 0)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"blending-points-into-a-network","dir":"Articles","previous_headings":"","what":"Blending points into a network","title":"Spatial joins and filters","text":"example , makes sense include information first POI already existing node. second POI, however, nearest node quite far away relative nearest location nearest edge. case, might want split edge location, add new node network. combination process use metaphor throwing network POIs together blender, mix smoothly together. function st_network_blend() exactly . POI, finds nearest location pp nearest edge ee. pp already existing node (.e. pp endpoint ee), joins information POI node. pp already existing node, subdivides ee pp, adds pp new node network, joins information POI new node. process, matter pp interior point linestring geometry ee. Original network POIs POIs blended network st_network_blend() function tolerance parameter, defines maximum distance POI can network order blended . Hence, POIs least close network tolerance distance blended, others ignored. tolerance can specified non-negative number. default assumed units meters, behavior can changed manually setting units units::units(). Blend without tolerance Blend tolerance important details aware using st_network_blend(). Firstly: multiple POIs nearest location nearest edge, first blended network. reasons explained : network structure clear approach dealing duplicated nodes. arranging table POIs dplyr::arrange() blending can influence (type ) POI given priority cases. also option set ignore_duplicates = FALSE. , duplicated projections result duplicated nodes, duplicates isolated (.e. connected rest network). can use morpher to_spatial_unique() merge spatially duplicated nodes one, specifying attributes combined. See example. Secondly: single POI multiple nearest edges, blended first edges. Therefore, might good idea run to_spatial_subdivision() morpher blending, intersecting unconnected edges get connected. Lastly: important aware floating point precision. See discussion GitHub issue background. short: due internal rounding rational numbers R actually possible even intersection point two lines evaluated intersecting lines . Sounds confusing? ! see example : : expect intersection edge blended network even set tolerance = 0, fact always happen. avoid problems, can better set tolerance small number instead zero.","code":"blend = st_network_blend(net, pois) blend #> # A sfnetwork: 3 nodes and 2 edges #> # #> # A rooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 1 ymax: 0 #> # CRS: NA #> # #> # Node data: 3 × 2 (active) #> geometry poi_type #> #> 1 (0 0) bakery #> 2 (1 0) NA #> 3 (0.6 0) butcher #> # #> # Edge data: 2 × 3 #> from to geometry #> #> 1 1 3 (0 0, 0.6 0) #> 2 3 2 (0.6 0, 1 0) ggraph(net, \"sf\") + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(blend, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() # Update the POIs. p3 = st_point(c(0.4, 0.3)) pois = st_sf( poi_type = c(\"bakery\", \"butcher\", \"bar\"), geometry = st_sfc(p1, p2, p3) ) blend = st_network_blend(net, pois) blend_with_tolerance = st_network_blend(net, pois, tolerance = 0.2) ggraph(blend, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(blend_with_tolerance, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() # Create two intersecting lines. p1 = st_point(c(0.53236, 1.95377)) p2 = st_point(c(0.53209, 1.95328)) l1 = st_sfc(st_linestring(c(p1, p2))) p3 = st_point(c(0.53209, 1.95345)) p4 = st_point(c(0.53245, 1.95345)) l2 = st_sfc(st_linestring(c(p3, p4))) # The two lines share an intersection point. st_intersection(l1, l2) #> Geometry set for 1 feature #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 0.5321837 ymin: 1.95345 xmax: 0.5321837 ymax: 1.95345 #> CRS: NA #> POINT (0.5321837 1.95345) # But this intersection point does not intersects the line itself! st_intersects(l1, st_intersection(l1, l2), sparse = FALSE) #> [,1] #> [1,] FALSE # The intersection point is instead located a tiny bit next to the line. st_distance(l1, st_intersection(l1, l2)) #> [,1] #> [1,] 4.310191e-17 net = as_sfnetwork(l1) p = st_intersection(l1, l2) plot(l1) plot(l2, col = \"grey\", lwd = 2, add = TRUE) plot(st_network_blend(net, p, tolerance = 0), lwd = 2, cex = 2, add = TRUE) #> Warning: [1m[22m`st_network_blend()` did not blend any points into the network. #> [36mℹ[39m Increase `tolerance` for a higher tolerance distance. plot(l1) plot(l2, col = \"grey\", lwd = 2, add = TRUE) plot(st_network_blend(net, p, tolerance = 1e-10), lwd = 2, cex = 2, add = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"joining-two-networks","dir":"Articles","previous_headings":"","what":"Joining two networks","title":"Spatial joins and filters","text":"examples joining information external features network. joining two networks? st_network_join() function . takes two sfnetworks input makes spatial full join geometries nodes data, based equals spatial predicate. means, nodes network x nodes network y present joined network, nodes x equal geometries nodes y, nodes become single node joined network. Edge data combined using dplyr::bind_rows() semantic, meaning data matched column name values filled NA missing either networks. columns edge data updated automatically correctly match new node indices joined network. spatial join performed edges. Hence, edge x equal geometry edge y, remain separate edges joined network. Two networks Joined network","code":"# Create two networks. # Create a network. n1 = st_point(c(0, 0)) n2 = st_point(c(1, 0)) n3 = st_point(c(1, 1)) n4 = st_point(c(0, 1)) e1 = st_sfc(st_linestring(c(n1, n2))) e2 = st_sfc(st_linestring(c(n2, n3))) e3 = st_sfc(st_linestring(c(n3, n4))) neta = st_sf(geometry = c(e1, e2)) |> as_sfnetwork() netb = st_sf(geometry = c(e2, e3)) |> as_sfnetwork() # Join them into a single network. joined = st_network_join(neta, netb) joined #> # A sfnetwork: 4 nodes and 4 edges #> # #> # A directed acyclic multigraph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 1 ymax: 1 #> # CRS: NA #> # #> # Node data: 4 × 1 (active) #> geometry #> #> 1 (0 0) #> 2 (1 0) #> 3 (1 1) #> 4 (0 1) #> # #> # Edge data: 4 × 3 #> from to geometry #> #> 1 1 2 (0 0, 1 0) #> 2 2 3 (1 0, 1 1) #> 3 2 3 (1 0, 1 1) #> # ℹ 1 more row plot(neta, col = \"skyblue\", pch = 15, cex = 2, lwd = 4) plot(netb, col = \"orange\", pch = 18, cex = 2, lty = 2, lwd = 4, add = TRUE) plot(joined, cex = 2, lwd = 4)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"the-basics","dir":"Articles","previous_headings":"","what":"The basics","title":"Routing on spatial networks","text":"sfnetworks two core functions routing spatial networks. first one, st_network_paths(), returns course optimal paths pairs nodes. second one, st_network_cost(), returns matrix optimal travel costs pairs nodes. functions need provided nodes route (origins), nodes route (destinations). basic way integer node indices, correspond rownumbers nodes table. many ways, though, explained detail section. Secondly, specified weight edge . Higher edge weights result higher travel costs. default, sfnetworks always use geographic lengths edges. possible specify different edge weights, explained detail section. function st_network_paths() returns sf object one row per requested path. Columns contain node indices origin destination path. column node_path contains indices nodes path, order visit. Similarly, column edge_path contains indices edges paths, order visit. nodes /edges names stored column named name want use values instead encode , set use_names = TRUE. Column cost stores total travel cost path. geometry column linestring resulted concatenating individual geometries visited edges. function st_network_cost() returns n×mn \\times m matrix, nn number specified origins, mm number specified destinations. Element AijA_{ij} stores total travel cost shortest path ii-th origin jj-th destination. matrix usually important starting point analysis. example, can serve input route optimization algorithms, spatial clustering algorithms calculation statistical measures based spatial proximity. also function st_network_distance(), synonym st_network_cost() edge weights always geographic edge length. function added provide intuitive network-specific alternative sf::st_distance(). note nice little example network nodes connected . many real-world networks may always case, meaning node pairs path . case st_network_paths() still return “path”, empty geometry FALSE value path_found column. st_network_cost() store Inf value. many cases, good idea first extract largest connected component network computing routes. can done morpher tidygraph::to_largest_component(). Full network Largest component want extract shortest paths linestring geometries, rather subset network keep nodes edges path, to_spatial_shortest_paths() morpher choice. accepts arguments st_network_paths(), return filtered network requested path. nodes edges tables sub-network arranged order appear path. Path 1 -> 12 Path 1 -> 16 Path 1 -> 17","code":"# Create a network. net = as_sfnetwork(mozart, \"gabriel\", directed = FALSE) # Compute the shortest path between node 1 and nodes 12 and 17. paths = st_network_paths(net, 1, c(12, 17)) paths #> Simple feature collection with 2 features and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549504 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 2 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 1 12 TRUE 1081. (4549504 2747309, 4549387 27… #> 2 1 17 TRUE 1436. (4549504 2747309, 4549387 27… # Do the same but now use node names to encode nodes in the output. paths = st_network_paths(net, 1, c(12, 17), use_names = TRUE) paths #> Simple feature collection with 2 features and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549504 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 2 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 Mozartki… Moza… TRUE 1081. (4549504 2747309, 454938… #> 2 Mozartki… Moza… TRUE 1436. (4549504 2747309, 454938… ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = paths, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(net)[1, ], size = 6) + geom_sf(data = node_data(net)[c(12, 17), ], pch = 15, size = 6) + theme_void() # Compute the cost matrix for travel between three nodes. st_network_cost(net, c(1, 12, 17), c(1, 12, 17)) #> Units: [m] #> 1 12 17 #> 1 0.000 1081.3335 1435.9344 #> 12 1081.333 0.0000 795.9422 #> 17 1435.934 795.9422 0.0000 # Use node names to encode nodes. st_network_cost(net, c(1, 12, 17), c(1, 12, 17), use_names = TRUE) #> Units: [m] #> Mozartkino Mozart-Eine Hommage Mozart Studentenheim #> Mozartkino 0.000 1081.3335 1435.9344 #> Mozart-Eine Hommage 1081.333 0.0000 795.9422 #> Mozart Studentenheim 1435.934 795.9422 0.0000 divided_net = as_sfnetwork(mozart, \"knn\", k = 3, directed = FALSE) #> Warning in spdep::knn2nb(spdep::knearneigh(st_geometry(x), k = k), sym = #> FALSE): neighbour object has 2 sub-graphs paths = st_network_paths(divided_net, 12, c(1, 17)) paths #> Simple feature collection with 2 features and 6 fields (with 1 geometry empty) #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4548664 ymin: 2747868 xmax: 4548984 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 2 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 12 1 FALSE Inf EMPTY #> 2 12 17 TRUE 796. (4548664 2747868, 4548897 274… ggraph(divided_net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = paths, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(divided_net)[12, ], size = 6) + geom_sf(data = node_data(divided_net)[c(1, 17), ], pch = 15, size = 6) + theme_void() st_network_cost(divided_net, c(1, 12, 17), c(1, 12, 17)) #> Units: [m] #> 1 12 17 #> 1 0 Inf Inf #> 12 Inf 0.0000 795.9422 #> 17 Inf 795.9422 0.0000 # Extract only the largest connected component. component = convert(divided_net, to_largest_component) ggraph(divided_net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(component, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() paths = net |> morph(to_spatial_shortest_paths, 1, c(12, 16, 17)) |> crystallize() paths #> # A tibble: 3 × 2 #> name graph #> #> 1 1 #> 2 2 #> 3 3 purrr::walk(paths$graph, plot, cex = 4)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"choosing-a-routing-backend","dir":"Articles","previous_headings":"","what":"Choosing a routing backend","title":"Routing on spatial networks","text":"mentioned, {sfnetwork} implement routing algorithms . , relies packages, call “routing backends” “routers” short. default routing backend igraph. st_network_paths() function wraps, depending argument settings, igraph::shortest_paths(), igraph::all_shortest_paths() igraph::k_shortest_paths(). st_network_cost() function wraps igraph::distances(). benefits routing backend : 1) can compute shortest paths, exists one; 2) can compute kk shortest paths Yen’s algorithm; 3) internal conversion data structures needed. However, routing supported single origin. Hence, many--many routing possible. second routing backend currently supported dodgr. package implements fast routing algorithm C++. exposed sfnetworks wrapping dodgr::dodgr_paths() st_network_paths() dodgr::dodgr_dists() st_network_cost(). benefits routing backend : 1) can route multiple origins multiple destinations, .e. many--many routing; 2) supports dual-weighted routing (see ); 3) fast also large networks. However, currently support kk shortest paths routing, internal conversions needed bridge different data structures. can specify routing backend use router argument. want change default routing backend, update global options: options(sfn_default_router = \"dodgr\").","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"specifying-origins-and-destinations","dir":"Articles","previous_headings":"","what":"Specifying origins and destinations","title":"Routing on spatial networks","text":"nodes route (.e. origins) nodes route (.e. destinations) referenced integer index, corresponds rownumber nodes table network. However, sfnetworks allows reference nodes also different ways, internally find corresponding node indices . called sfnetwork node query, evaluated evaluate_node_query(). However, normally never call function directly user. Instead, simply specify node query argument value arguments. query can formatted follows: spatial features: Spatial features can given object class sf sfc. nearest node feature found calling nearest_nodes(). node type query function: node type query specific type node measure function defines node given type . Nodes meet criterium queried. node predicate query function: node predicate query specific type node measure function defines node given spatial predicate applies spatial relation node spatial features. Nodes meet criterium queried. column name: referenced column expected logical values defining node queried . Tidy evaluation used hence column name unquoted. integers: Integers interpreted node indices. node index corresponds row-number nodes table network. characters: Characters interpreted node names. node name corresponds value column named name nodes table network. Note column expected store unique names without duplicated values. logicals: Logicals define node queried .","code":"pt = st_centroid(st_combine(mozart)) pl = st_buffer(mozart[15, ], 350) paths_A = st_network_paths( net, from = pt, to = centrality_degree() < 3 ) paths_B = st_network_paths( net, from = \"Mozartkino\", to = node_is_within(pl) ) ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = paths_A, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(net)[unique(paths_A$from), ], size = 6) + geom_sf(data = node_data(net)[unique(paths_A$to), ], pch = 15, size = 6) + geom_sf(data = pt, color = \"skyblue\", size = 6) + theme_void() ggraph(net, \"sf\") + geom_sf(data = pl, fill = \"skyblue\", alpha = 0.8) + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = paths_B, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(net)[unique(paths_B$from), ], size = 6) + geom_sf(data = node_data(net)[unique(paths_B$to), ], pch = 15, size = 6) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"specifying-edge-weights","dir":"Articles","previous_headings":"","what":"Specifying edge weights","title":"Routing on spatial networks","text":"shortest path , depends weight edge. higher weight, longer edge. spatial network analysis, often makes sense use geographic length edge weights, shortest path path shortest geographic distance. Therefore, sfnetworks uses default. possible specify different edge weights weights argument. Weights specified numeric vector length number edges network. However, sfnetworks allows specify also different ways, internally compute numeric vector . called sfnetwork edge specification, evaluated evaluate_weight_spec(). However, normally never call function directly user. Instead, simply provide specification argument value weights argument. specification can formatted follows: edge measure function: spatial edge measure function computes given measure edge, used edge weights. default edge_length() measure used routing functions. column name: column edges table network contains edge weights. Tidy evaluation used hence column name unquoted. numeric vector: vector length number edges network, specifying edge weight . dual weights: Dual weights can specified dual_weights() function. allows use different set weights shortest paths computation reporting total cost paths. dodgr routing backend supports dual-weighted routing. See example. Edge length Edge speed Shortest route Fastest route important note functions sfnetworks consider edge weights use edge_length() default, case tidygraph. always explicitly specify weights, example computing betweenness centrality using tidygraph::centrality_betweenness(). Otherwise, edge weighted 1, shortest path path fewest number edges. Furthermore, important know igraph different behavior regarding edge weights. weights = NULL, look edge attribute named weight use whenever present. tidygraph, therefore also sfnetworks, , always default edge weights 1 whenever weights = NULL.","code":"# Assign each edge a speed. # Some edges will have a higher speed. # Based on this, compute the travel time of each edge. speeds = set_units(rep(15, n_edges(net)), \"km/h\") speeds[c(17, 25)] = set_units(20, \"km/h\") net = net |> activate(edges) |> mutate(speed = speeds) |> mutate(time = edge_length() / speed) # Now compute the shortest and the fastest routes. shortest = st_network_paths(net, 1, 17, weights = edge_length()) # The default. fastest = st_network_paths(net, 1, 17, weights = time) ggraph(net, \"sf\") + geom_edge_sf(aes(color = drop_units(edge_length())), linewidth = 2) + geom_node_sf(size = 4) + scale_edge_color_continuous(\"length [m]\") + theme_void() ggraph(net, \"sf\") + geom_edge_sf(aes(color = drop_units(speed)), linewidth = 2) + geom_node_sf(size = 4) + scale_edge_color_continuous(\"speed [km/h]\") + theme_void() ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = shortest, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(net)[1, ], size = 6) + geom_sf(data = node_data(net)[17, ], pch = 15, size = 6) + theme_void() ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = fastest, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(net)[1, ], size = 6) + geom_sf(data = node_data(net)[17, ], pch = 15, size = 6) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"applications","dir":"Articles","previous_headings":"","what":"Applications","title":"Routing on spatial networks","text":"section, show small set applications routing related functions. meant overview covers everything. Also, remember sfnetworks general-purpose spatial network analysis package optimized specific application. However, especially combination packages can address wide variety use-cases. Thanks igraph routing backend, can compute shortest path two nodes, also next k−1k-1 shortest paths. , set k argument st_network_paths() integer higher 1. supported one--one routing, .e. single origin single destination. purpose closest facility analysis , given set destination locations (also referred facilities) origin locations (also referred sites), find closest nn facilities site. example, might want find nearest transit hub address city, nearest hospital high-risk road intersections. solve problem, can calculate cost matrix sites origins, facilities destinations points. , row (.e. site) find column(s) lowest cost value. Note facility site represented nearest node network. First blending network using st_network_blend() gives accurate results. traveling salesman problem aims find shortest tour visits every location set exactly . solve , sfnetworks provides interface TSP::TSP() function. requires TSP package installed. st_network_travel() function returns sf object similar output st_network_paths(). row represent one leg route, one location next. Note location visit represented nearest node network. First blending network using st_network_blend() gives accurate results. respect given point pp given distance dd, isodistance line holds distance point line pp equal dd. spatial network analysis, common find nodes fall within isodistance line computed given source node pp. enclosing nodes concave hull, obtain isodistance polygon. workflow implemented function st_network_iso(). first compute distance matrix given source node pp (can specified explained ) nodes network using st_network_cost(), filter nodes within given distance dd. Using sf::st_concave_hull(), compute concave hull around nodes obtain isodistance polygon. Multiple distance thresholds can given, resulting multiple isodistance polygons drawn. output function sf object one row per requested polygon. setting ratio argument (value 0 1, 1 convex hull), can increase decrease level detail polygons. default, holes allowed polygons, can changed setting allow_holes = TRUE. note changing ratio requires GEOS version least 3.11. GEOS C/C++ library computational geometry used sf. different approach can taken morpher to_spatial_neighborhood(). Instead drawing polygons, function subset network contain nodes inside isodistance line, edges connect . st_network_iso() to_spatial_neighborhood() allow specify edge weights geographic distance. can done weights argument, explained . using time edge weight, talk isochrones instead isodistances. many cases shortest path based geographical distances travel time necessarily optimal path. appropriate route may depend many factors, example staying away large potentially unpleasant roads motor traffic. networks different characteristics. OpenStreetMap networks highway attribute often good (albeit crude) approximation road type. roxel demo dataset derived OpenStreetMap stores highway attribute type column. can see Roxel largely residential road network: Building shortest paths calculated previous section can try alternative routing profile. purposes illustration, lets imagine ’re routing vehicle want keep away residential roads. can now compare shortest path optimal path according weighting profile. Shortest route Optimal route Note developing sophisticated routing profiles beyond scope package. need complex mode-specific routing profiles, recommend looking routing profiles associated open source routing engines OSRM, dodgr R package. Another direction travel extend approach illustrated , work well-suited separate package builds sfnetworks, possibly integrating routing profiles dodgr. ’d like work project improve mode-specific routing R building package, please let us know discussion room! many cases may interested obtaining cost matrix stores geographic distances optimal routes according custom set edge weights. , want use custom weights define “shortest” path , report actual geographic distance path. called dual-weighted routing. dodgr routing backend supports . sfnetworks offers dual_weights() function allow specify dual weights weights argument routing functions. accepts two sets weights, can specified ways explained section. first set weights reported weights, second set weights actual weights used define optimal path.","code":"paths = st_network_paths(net, 1, 17, k = 3) paths #> Simple feature collection with 3 features and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4548984 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 3 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 1 17 TRUE 1436. (4549504 2747309, 4549387 27… #> 2 1 17 TRUE 1580. (4549504 2747309, 4549589 27… #> 3 1 17 TRUE 1602. (4549504 2747309, 4549589 27… paths = paths |> mutate(k = c(1:n())) |> arrange(desc(k)) ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = paths, aes(color = as.factor(k)), linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(net)[1, ], size = 6) + geom_sf(data = node_data(net)[17, ], pch = 15, size = 6) + scale_color_discrete(\"k\") + theme_void() # Create a network. net = as_sfnetwork(roxel, directed = FALSE) |> st_transform(3035) # Create some facility locations spread over the area. facilities = st_sfc( st_point(c(4151100, 3207700)), st_point(c(4151040, 3206660)), st_point(c(4151800, 3207200)), st_point(c(4152000, 3207600)), crs = 3035 ) # Select a random set of sites. sites = st_sample(st_convex_hull(st_combine(net)), 50) # Blend the sites and facilities into the network to get better results. # Also select only the largest connected component. # Such that we avoid points being blended to a small disconnected component. net = net |> convert(to_largest_component, .clean = TRUE) |> st_network_blend(c(sites, facilities)) # Calculate the cost matrix. mat = net |> st_network_cost(from = sites, to = facilities) # Find for each site which facility is closest. closest = facilities[apply(mat, 1, function(x) which(x == min(x))[1])] # Create a line between each site and its closest facility, for visualization. draw_lines = function(sources, targets) { f = function(a, b) st_sfc(st_cast(c(a, b), \"LINESTRING\")) lines = do.call(\"c\", mapply(f, sources, targets, SIMPLIFY = FALSE)) st_crs(lines) = st_crs(sources) lines } connections = draw_lines(sites, closest) ggraph(net, \"sf\") + geom_edge_sf(color = \"grey\") + geom_node_sf(color = \"grey\") + geom_sf(data = connections, color = \"orange\") + geom_sf(data = sites, color = \"orange\", size = 4) + geom_sf(data = facilities, color = \"skyblue\", size = 6) + theme_void() # We will use the facilities from the previous section as visiting locations. # They are already blended into the largest component of the network. route = st_network_travel(net, facilities) route #> Simple feature collection with 4 features and 6 fields #> Geometry type: MULTILINESTRING #> Dimension: XY #> Bounding box: xmin: 4150908 ymin: 3206643 xmax: 4152015 ymax: 3207744 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 4 × 7 #> from to node_path edge_path path_found cost geometry #> * [m] #> 1 633 1003 TRUE 1074. ((4151039 3206662, 4151063… #> 2 1003 869 TRUE 602. ((4151793 3207244, 4151805… #> 3 869 999 TRUE 1178. ((4151073 3207744, 4151097… #> 4 999 633 TRUE 1385. ((4151138 3207734, 4151160… ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = route, color = \"orange\", linewidth = 2) + geom_sf(data = facilities, size = 6) + theme_void() # Define the source. # This point will be snapped to its nearest node. pt = st_centroid(st_transform(st_as_sfc(st_bbox(roxel)), 3035)) # Compute isodistance polygons for four different thresholds. polys = st_network_iso(net, pt, rev(c(100, 250, 500, 1000))) polys #> Simple feature collection with 4 features and 1 field #> Geometry type: POLYGON #> Dimension: XY #> Bounding box: xmin: 4150754 ymin: 3206653 xmax: 4152337 ymax: 3208212 #> Projected CRS: ETRS89-extended / LAEA Europe #> cost geometry #> 1 1000 [m] POLYGON ((4151598 3206653, ... #> 2 500 [m] POLYGON ((4151611 3207041, ... #> 3 250 [m] POLYGON ((4151519 3207212, ... #> 4 100 [m] POLYGON ((4151540 3207378, ... ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = polys, aes(fill = drop_units(cost)), alpha = 0.5) + scale_fill_continuous(\"distance [m]\") + theme_void() sub_net = convert(net, to_spatial_neighborhood, pt, 500) plot(net, col = \"darkgrey\") plot(sub_net, col = \"orange\", lwd = 2, cex = 1, add = TRUE) roxel |> count(type) #> Simple feature collection with 9 features and 2 fields #> Geometry type: MULTILINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 9 × 3 #> type n geometry #> * #> 1 cycleway 5 ((7.540663 51.95534, 7.540831 51.95536), (7.534414 51.9547… #> 2 footway 134 ((7.543404 51.94779, 7.54358 51.94786, 7.543685 51.9479), … #> 3 path 113 ((7.54059 51.95077, 7.54127 51.95012), (7.53819 51.95738, … #> 4 residential 325 ((7.537815 51.95867, 7.537015 51.95848, 7.537374 51.95787,… #> 5 secondary 54 ((7.532301 51.95559, 7.532214 51.95575, 7.532142 51.95589,… #> 6 service 256 ((7.525727 51.94672, 7.52585 51.94668, 7.526145 51.94655, … #> 7 track 15 ((7.541088 51.95588, 7.541908 51.95604), (7.535803 51.9433… #> 8 unclassified 57 ((7.534157 51.94654, 7.534845 51.94597, 7.534993 51.94583,… #> 9 NA 256 ((7.526311 51.94653, 7.526298 51.94649, 7.526311 51.94644,… ggraph(net, \"sf\") + geom_edge_sf(aes(color = as.factor(type)), linewidth = 2) + geom_node_sf() + scale_edge_color_discrete(\"type\") + theme_void() weighting_profile = c( cycleway = Inf, footway = Inf, path = Inf, residential = 3, secondary = 1, service = 3, track = 10, unclassified = 10 ) net = net |> activate(edges) |> mutate(multiplier = ifelse(is.na(type), 1, weighting_profile[type])) |> mutate(weight = drop_units(edge_length() * multiplier)) shortest = st_network_paths(net, 452, 212) optimal = st_network_paths(net, 452, 212, weights = weight) ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = shortest, color = \"orange\", linewidth = 2) + geom_sf(data = node_data(net)[452, ], size = 6) + geom_sf(data = node_data(net)[212, ], pch = 15, size = 6) + theme_void() ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = optimal, color = \"orange\", linewidth = 2) + geom_sf(data = node_data(net)[452, ], size = 6) + geom_sf(data = node_data(net)[212, ], pch = 15, size = 6) + theme_void() # Cost matrix reporting the custom weights. st_network_cost( net, seq(1, 901, by = 150), seq(1, 901, by = 150), weights = weight, router = \"dodgr\" ) |> round() #> 1 151 301 451 601 751 901 #> 1 0 2953 374 1644 1445 863 5485 #> 151 2953 0 2579 3721 2371 3816 7772 #> 301 374 2579 0 1244 1071 1237 5567 #> 451 1971 3721 1244 0 2213 1349 5310 #> 601 1445 2371 1071 2213 0 2308 6437 #> 751 863 3816 1237 1349 2308 0 4811 #> 901 5485 8385 5806 5559 6876 4811 0 # Cost matrix using custom weights but reporting real distances. st_network_cost( net, seq(1, 901, by = 150), seq(1, 901, by = 150), weights = dual_weights(edge_length(), weight), router = \"dodgr\" ) |> round() #> 1 151 301 451 601 751 901 #> 1 0 994 249 886 768 305 1127 #> 151 994 0 758 1588 588 1264 1622 #> 301 249 758 0 914 530 519 1350 #> 451 886 1588 914 0 1360 696 1334 #> 601 768 588 530 1360 0 1036 1510 #> 751 305 1264 519 696 1036 0 894 #> 901 1127 1622 1350 1334 1510 894 0"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"k-shortest-paths","dir":"Articles","previous_headings":"","what":"K shortest paths","title":"Routing on spatial networks","text":"Thanks igraph routing backend, can compute shortest path two nodes, also next k−1k-1 shortest paths. , set k argument st_network_paths() integer higher 1. supported one--one routing, .e. single origin single destination.","code":"paths = st_network_paths(net, 1, 17, k = 3) paths #> Simple feature collection with 3 features and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4548984 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 3 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 1 17 TRUE 1436. (4549504 2747309, 4549387 27… #> 2 1 17 TRUE 1580. (4549504 2747309, 4549589 27… #> 3 1 17 TRUE 1602. (4549504 2747309, 4549589 27… paths = paths |> mutate(k = c(1:n())) |> arrange(desc(k)) ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = paths, aes(color = as.factor(k)), linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(net)[1, ], size = 6) + geom_sf(data = node_data(net)[17, ], pch = 15, size = 6) + scale_color_discrete(\"k\") + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"closest-facility-analysis","dir":"Articles","previous_headings":"","what":"Closest facility analysis","title":"Routing on spatial networks","text":"purpose closest facility analysis , given set destination locations (also referred facilities) origin locations (also referred sites), find closest nn facilities site. example, might want find nearest transit hub address city, nearest hospital high-risk road intersections. solve problem, can calculate cost matrix sites origins, facilities destinations points. , row (.e. site) find column(s) lowest cost value. Note facility site represented nearest node network. First blending network using st_network_blend() gives accurate results.","code":"# Create a network. net = as_sfnetwork(roxel, directed = FALSE) |> st_transform(3035) # Create some facility locations spread over the area. facilities = st_sfc( st_point(c(4151100, 3207700)), st_point(c(4151040, 3206660)), st_point(c(4151800, 3207200)), st_point(c(4152000, 3207600)), crs = 3035 ) # Select a random set of sites. sites = st_sample(st_convex_hull(st_combine(net)), 50) # Blend the sites and facilities into the network to get better results. # Also select only the largest connected component. # Such that we avoid points being blended to a small disconnected component. net = net |> convert(to_largest_component, .clean = TRUE) |> st_network_blend(c(sites, facilities)) # Calculate the cost matrix. mat = net |> st_network_cost(from = sites, to = facilities) # Find for each site which facility is closest. closest = facilities[apply(mat, 1, function(x) which(x == min(x))[1])] # Create a line between each site and its closest facility, for visualization. draw_lines = function(sources, targets) { f = function(a, b) st_sfc(st_cast(c(a, b), \"LINESTRING\")) lines = do.call(\"c\", mapply(f, sources, targets, SIMPLIFY = FALSE)) st_crs(lines) = st_crs(sources) lines } connections = draw_lines(sites, closest) ggraph(net, \"sf\") + geom_edge_sf(color = \"grey\") + geom_node_sf(color = \"grey\") + geom_sf(data = connections, color = \"orange\") + geom_sf(data = sites, color = \"orange\", size = 4) + geom_sf(data = facilities, color = \"skyblue\", size = 6) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"traveling-salesman-problem","dir":"Articles","previous_headings":"","what":"Traveling salesman problem","title":"Routing on spatial networks","text":"traveling salesman problem aims find shortest tour visits every location set exactly . solve , sfnetworks provides interface TSP::TSP() function. requires TSP package installed. st_network_travel() function returns sf object similar output st_network_paths(). row represent one leg route, one location next. Note location visit represented nearest node network. First blending network using st_network_blend() gives accurate results.","code":"# We will use the facilities from the previous section as visiting locations. # They are already blended into the largest component of the network. route = st_network_travel(net, facilities) route #> Simple feature collection with 4 features and 6 fields #> Geometry type: MULTILINESTRING #> Dimension: XY #> Bounding box: xmin: 4150908 ymin: 3206643 xmax: 4152015 ymax: 3207744 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 4 × 7 #> from to node_path edge_path path_found cost geometry #> * [m] #> 1 633 1003 TRUE 1074. ((4151039 3206662, 4151063… #> 2 1003 869 TRUE 602. ((4151793 3207244, 4151805… #> 3 869 999 TRUE 1178. ((4151073 3207744, 4151097… #> 4 999 633 TRUE 1385. ((4151138 3207734, 4151160… ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = route, color = \"orange\", linewidth = 2) + geom_sf(data = facilities, size = 6) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"isodistance-polygons","dir":"Articles","previous_headings":"","what":"Isodistance polygons","title":"Routing on spatial networks","text":"respect given point pp given distance dd, isodistance line holds distance point line pp equal dd. spatial network analysis, common find nodes fall within isodistance line computed given source node pp. enclosing nodes concave hull, obtain isodistance polygon. workflow implemented function st_network_iso(). first compute distance matrix given source node pp (can specified explained ) nodes network using st_network_cost(), filter nodes within given distance dd. Using sf::st_concave_hull(), compute concave hull around nodes obtain isodistance polygon. Multiple distance thresholds can given, resulting multiple isodistance polygons drawn. output function sf object one row per requested polygon. setting ratio argument (value 0 1, 1 convex hull), can increase decrease level detail polygons. default, holes allowed polygons, can changed setting allow_holes = TRUE. note changing ratio requires GEOS version least 3.11. GEOS C/C++ library computational geometry used sf. different approach can taken morpher to_spatial_neighborhood(). Instead drawing polygons, function subset network contain nodes inside isodistance line, edges connect . st_network_iso() to_spatial_neighborhood() allow specify edge weights geographic distance. can done weights argument, explained . using time edge weight, talk isochrones instead isodistances.","code":"# Define the source. # This point will be snapped to its nearest node. pt = st_centroid(st_transform(st_as_sfc(st_bbox(roxel)), 3035)) # Compute isodistance polygons for four different thresholds. polys = st_network_iso(net, pt, rev(c(100, 250, 500, 1000))) polys #> Simple feature collection with 4 features and 1 field #> Geometry type: POLYGON #> Dimension: XY #> Bounding box: xmin: 4150754 ymin: 3206653 xmax: 4152337 ymax: 3208212 #> Projected CRS: ETRS89-extended / LAEA Europe #> cost geometry #> 1 1000 [m] POLYGON ((4151598 3206653, ... #> 2 500 [m] POLYGON ((4151611 3207041, ... #> 3 250 [m] POLYGON ((4151519 3207212, ... #> 4 100 [m] POLYGON ((4151540 3207378, ... ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = polys, aes(fill = drop_units(cost)), alpha = 0.5) + scale_fill_continuous(\"distance [m]\") + theme_void() sub_net = convert(net, to_spatial_neighborhood, pt, 500) plot(net, col = \"darkgrey\") plot(sub_net, col = \"orange\", lwd = 2, cex = 1, add = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"custom-routing","dir":"Articles","previous_headings":"","what":"Custom routing","title":"Routing on spatial networks","text":"many cases shortest path based geographical distances travel time necessarily optimal path. appropriate route may depend many factors, example staying away large potentially unpleasant roads motor traffic. networks different characteristics. OpenStreetMap networks highway attribute often good (albeit crude) approximation road type. roxel demo dataset derived OpenStreetMap stores highway attribute type column. can see Roxel largely residential road network: Building shortest paths calculated previous section can try alternative routing profile. purposes illustration, lets imagine ’re routing vehicle want keep away residential roads. can now compare shortest path optimal path according weighting profile. Shortest route Optimal route Note developing sophisticated routing profiles beyond scope package. need complex mode-specific routing profiles, recommend looking routing profiles associated open source routing engines OSRM, dodgr R package. Another direction travel extend approach illustrated , work well-suited separate package builds sfnetworks, possibly integrating routing profiles dodgr. ’d like work project improve mode-specific routing R building package, please let us know discussion room!","code":"roxel |> count(type) #> Simple feature collection with 9 features and 2 fields #> Geometry type: MULTILINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 9 × 3 #> type n geometry #> * #> 1 cycleway 5 ((7.540663 51.95534, 7.540831 51.95536), (7.534414 51.9547… #> 2 footway 134 ((7.543404 51.94779, 7.54358 51.94786, 7.543685 51.9479), … #> 3 path 113 ((7.54059 51.95077, 7.54127 51.95012), (7.53819 51.95738, … #> 4 residential 325 ((7.537815 51.95867, 7.537015 51.95848, 7.537374 51.95787,… #> 5 secondary 54 ((7.532301 51.95559, 7.532214 51.95575, 7.532142 51.95589,… #> 6 service 256 ((7.525727 51.94672, 7.52585 51.94668, 7.526145 51.94655, … #> 7 track 15 ((7.541088 51.95588, 7.541908 51.95604), (7.535803 51.9433… #> 8 unclassified 57 ((7.534157 51.94654, 7.534845 51.94597, 7.534993 51.94583,… #> 9 NA 256 ((7.526311 51.94653, 7.526298 51.94649, 7.526311 51.94644,… ggraph(net, \"sf\") + geom_edge_sf(aes(color = as.factor(type)), linewidth = 2) + geom_node_sf() + scale_edge_color_discrete(\"type\") + theme_void() weighting_profile = c( cycleway = Inf, footway = Inf, path = Inf, residential = 3, secondary = 1, service = 3, track = 10, unclassified = 10 ) net = net |> activate(edges) |> mutate(multiplier = ifelse(is.na(type), 1, weighting_profile[type])) |> mutate(weight = drop_units(edge_length() * multiplier)) shortest = st_network_paths(net, 452, 212) optimal = st_network_paths(net, 452, 212, weights = weight) ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = shortest, color = \"orange\", linewidth = 2) + geom_sf(data = node_data(net)[452, ], size = 6) + geom_sf(data = node_data(net)[212, ], pch = 15, size = 6) + theme_void() ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = optimal, color = \"orange\", linewidth = 2) + geom_sf(data = node_data(net)[452, ], size = 6) + geom_sf(data = node_data(net)[212, ], pch = 15, size = 6) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"dual-weighted-routing","dir":"Articles","previous_headings":"","what":"Dual-weighted routing","title":"Routing on spatial networks","text":"many cases may interested obtaining cost matrix stores geographic distances optimal routes according custom set edge weights. , want use custom weights define “shortest” path , report actual geographic distance path. called dual-weighted routing. dodgr routing backend supports . sfnetworks offers dual_weights() function allow specify dual weights weights argument routing functions. accepts two sets weights, can specified ways explained section. first set weights reported weights, second set weights actual weights used define optimal path.","code":"# Cost matrix reporting the custom weights. st_network_cost( net, seq(1, 901, by = 150), seq(1, 901, by = 150), weights = weight, router = \"dodgr\" ) |> round() #> 1 151 301 451 601 751 901 #> 1 0 2953 374 1644 1445 863 5485 #> 151 2953 0 2579 3721 2371 3816 7772 #> 301 374 2579 0 1244 1071 1237 5567 #> 451 1971 3721 1244 0 2213 1349 5310 #> 601 1445 2371 1071 2213 0 2308 6437 #> 751 863 3816 1237 1349 2308 0 4811 #> 901 5485 8385 5806 5559 6876 4811 0 # Cost matrix using custom weights but reporting real distances. st_network_cost( net, seq(1, 901, by = 150), seq(1, 901, by = 150), weights = dual_weights(edge_length(), weight), router = \"dodgr\" ) |> round() #> 1 151 301 451 601 751 901 #> 1 0 994 249 886 768 305 1127 #> 151 994 0 758 1588 588 1264 1622 #> 301 249 758 0 914 530 519 1350 #> 451 886 1588 914 0 1360 696 1334 #> 601 768 588 530 1360 0 1036 1510 #> 751 305 1264 519 696 1036 0 894 #> 901 1127 1622 1350 1334 1510 894 0"},{"path":"https://luukvdmeer.github.io/sfnetworks/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Lucas van der Meer. Author, maintainer. Lorena Abad. Author. Andrea Gilardi. Author. Robin Lovelace. Author.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"van der Meer L, Abad L, Gilardi , Lovelace R (2024). sfnetworks: Tidy Geospatial Networks. R package version 1.0.0, https://github.com/luukvdmeer/sfnetworks, https://luukvdmeer.github.io/sfnetworks/.","code":"@Manual{, title = {sfnetworks: Tidy Geospatial Networks}, author = {Lucas {van der Meer} and Lorena Abad and Andrea Gilardi and Robin Lovelace}, year = {2024}, note = {R package version 1.0.0, https://github.com/luukvdmeer/sfnetworks}, url = {https://luukvdmeer.github.io/sfnetworks/}, }"},{"path":"https://luukvdmeer.github.io/sfnetworks/index.html","id":"tidy-geospatial-networks-in-r-","dir":"","previous_headings":"","what":"Tidy Geospatial Networks","title":"Tidy Geospatial Networks","text":"{sfnetworks} R package analysis geospatial networks. connects extends functionalities {tidygraph} package network analysis {sf} package spatial data science.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/index.html","id":"background","dir":"","previous_headings":"","what":"Background","title":"Tidy Geospatial Networks","text":"Geospatial networks graphs embedded geographical space. means nodes edges graph can represented geographic features: nodes commonly points, edges linestrings. play important role many different domains, ranging transportation planning logistics ecology epidemiology. structure characteristics geospatial networks go beyond standard graph topology, therefore crucial explicitly take space account analyzing . created {sfnetworks} facilitate integrated workflow. combines forces two popular R packages: {sf} spatial data science {tidygraph} standard graph analysis. core package dedicated data structure geospatial networks, can provided input graph analytical functions {tidygraph} well spatial analytical functions {sf}, without need conversion. Additionally, implemented set geospatial network specific functions, routines shortest path calculation, network cleaning topology modification. {sfnetworks} designed general-purpose package suitable usage across different application domains, can seamlessly integrated tidyverse workflows.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/index.html","id":"installation","dir":"","previous_headings":"","what":"Installation","title":"Tidy Geospatial Networks","text":"can install latest stable version {sfnetworks} CRAN : can install development version GitHub : Note: Two important dependencies {sfnetworks}, {sf} package spatial data science {igraph} package network analysis (main “analysis backend” {tidygraph}), require low-level software libraries installed system. Depending operating system use, can mean install system requirements first, can install {sfnetworks}. See installation guides sf igraph details.","code":"install.packages(\"sfnetworks\") remotes::install_github(\"luukvdmeer/sfnetworks\")"},{"path":"https://luukvdmeer.github.io/sfnetworks/index.html","id":"usage","dir":"","previous_headings":"","what":"Usage","title":"Tidy Geospatial Networks","text":"get started {sfnetworks}, read Introduction sfnetworks. Four additional package vignettes guide detail functionalities package: Creating representing spatial networks Cleaning spatial networks Spatial joins filters Routing spatial networks","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/index.html","id":"contribution","dir":"","previous_headings":"","what":"Contribution","title":"Tidy Geospatial Networks","text":"look much forward contributions package. See contributing guide details. project released Contributor Code Conduct. participating project agree abide terms.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/index.html","id":"acknowledgment","dir":"","previous_headings":"","what":"Acknowledgment","title":"Tidy Geospatial Networks","text":"project gratefully acknowledges financial support ","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as.linnet.html","id":null,"dir":"Reference","previous_headings":"","what":"Convert a sfnetwork into a linnet — as.linnet","title":"Convert a sfnetwork into a linnet — as.linnet","text":"method convert object class sfnetwork linnet format enhance interoperability sfnetworks spatstat. Use method without .sfnetwork suffix loading spatstat package.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as.linnet.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Convert a sfnetwork into a linnet — as.linnet","text":"","code":"as.linnet.sfnetwork(X, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as.linnet.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Convert a sfnetwork into a linnet — as.linnet","text":"X object class sfnetwork projected CRS. ... Arguments passed linnet.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as.linnet.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Convert a sfnetwork into a linnet — as.linnet","text":"object class linnet.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_s2_geography.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract the geometries of a sfnetwork as a S2 geography vector — as_s2_geography","title":"Extract the geometries of a sfnetwork as a S2 geography vector — as_s2_geography","text":"method convert object class sfnetwork s2_geography format. Use method without .sfnetwork suffix loading s2 package.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_s2_geography.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract the geometries of a sfnetwork as a S2 geography vector — as_s2_geography","text":"","code":"as_s2_geography.sfnetwork(x, focused = TRUE, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_s2_geography.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract the geometries of a sfnetwork as a S2 geography vector — as_s2_geography","text":"x object class sfnetwork. focused features focus extracted? Defaults TRUE. See focus information focused networks. ... Arguments passed corresponding s2 function.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_s2_geography.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract the geometries of a sfnetwork as a S2 geography vector — as_s2_geography","text":"object class s2_geography.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_sfnetwork.html","id":null,"dir":"Reference","previous_headings":"","what":"Convert a foreign object to a sfnetwork — as_sfnetwork","title":"Convert a foreign object to a sfnetwork — as_sfnetwork","text":"Convert given object object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_sfnetwork.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Convert a foreign object to a sfnetwork — as_sfnetwork","text":"","code":"as_sfnetwork(x, ...) # Default S3 method as_sfnetwork(x, ...) # S3 method for class 'sf' as_sfnetwork(x, ...) # S3 method for class 'sfc' as_sfnetwork(x, ...) # S3 method for class 'dodgr_streetnet' as_sfnetwork(x, ...) # S3 method for class 'linnet' as_sfnetwork(x, ...) # S3 method for class 'psp' as_sfnetwork(x, ...) # S3 method for class 'sfNetwork' as_sfnetwork(x, ...) # S3 method for class 'tbl_graph' as_sfnetwork(x, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_sfnetwork.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Convert a foreign object to a sfnetwork — as_sfnetwork","text":"x Object converted sfnetwork. ... Additional arguments passed functions.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_sfnetwork.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Convert a foreign object to a sfnetwork — as_sfnetwork","text":"object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_sfnetwork.html","id":"methods-by-class-","dir":"Reference","previous_headings":"","what":"Methods (by class)","title":"Convert a foreign object to a sfnetwork — as_sfnetwork","text":"as_sfnetwork(default): default, provided object first converted tbl_graph using as_tbl_graph. conversion sfnetwork work long nodes can converted sf object st_as_sf. Arguments st_as_sf can provided additional arguments forwarded st_as_sf sfnetwork construction function. as_sfnetwork(sf): Convert spatial features class sf directly sfnetwork. Supported geometry types either LINESTRING POINT. first case, lines become edges network, nodes placed boundaries. Additional arguments forwarded create_from_spatial_lines. latter case, points become nodes network, connected edges according specified method. Additional arguments forwarded create_from_spatial_points. as_sfnetwork(sfc): Convert spatial geometries class sfc directly sfnetwork. Supported geometry types either LINESTRING POINT. first case, lines become edges network, nodes placed boundaries. Additional arguments forwarded create_from_spatial_lines. latter case, points become nodes network, connected edges according specified method. Additional arguments forwarded create_from_spatial_points. as_sfnetwork(dodgr_streetnet): Convert directed graph class dodgr_streetnet directly sfnetwork. Additional arguments forwarded dodgr_to_sfnetwork. requires dodgr package installed. as_sfnetwork(linnet): Convert spatial linear networks class linnet directly sfnetwork. Additional arguments forwarded create_from_spatial_lines. requires spatstat.geom package installed. as_sfnetwork(psp): Convert spatial line segments class psp directly sfnetwork. lines become edges network, nodes placed boundary points. Additional arguments forwarded create_from_spatial_lines. as_sfnetwork(sfNetwork): Convert spatial networks class sfNetwork stplanr package directly sfnetwork. extract edges sf object re-create network structure. Additional arguments forwarded create_from_spatial_lines.directness original network preserved unless specified otherwise directed argument. as_sfnetwork(tbl_graph): Convert graph objects class tbl_graph directly sfnetwork. work least nodes can converted sf object st_as_sf. Arguments st_as_sf can provided additional arguments forwarded st_as_sf sfnetwork construction function. directness original graph preserved unless specified otherwise directed argument.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_sfnetwork.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Convert a foreign object to a sfnetwork — as_sfnetwork","text":"","code":"# From an sf object with LINESTRING geometries. library(sf, quietly = TRUE) #> Linking to GEOS 3.10.2, GDAL 3.4.1, PROJ 8.2.1; sf_use_s2() is TRUE oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) as_sfnetwork(roxel) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows plot(st_geometry(roxel)) plot(as_sfnetwork(roxel)) # From an sf object with POINT geometries. # For more examples see ?create_from_spatial_points. as_sfnetwork(mozart) #> # A sfnetwork: 17 nodes and 272 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 4 (active) #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> 4 Mozart Denkmal artwork NA (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) #> 6 Mozartsteg bridge NA (4549473 2747624) #> # ℹ 11 more rows #> # #> # Edge data: 272 × 3 #> from to geometry #> #> 1 1 2 (4549504 2747309, 4549003 2747376) #> 2 1 3 (4549504 2747309, 4549589 2747507) #> 3 1 4 (4549504 2747309, 4549387 2747514) #> # ℹ 269 more rows plot(st_geometry(mozart)) plot(as_sfnetwork(mozart)) par(oldpar) # From a dodgr_streetnet object. if (require(dodgr, quietly = TRUE) & require(geodist, quietly = TRUE)) { as_sfnetwork(dodgr::weight_streetnet(hampi)) } #> # A sfnetwork: 3337 nodes and 6813 edges #> # #> # A directed simple graph with 3 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 76.37261 ymin: 15.30104 xmax: 76.49232 ymax: 15.36033 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3,337 × 4 (active) #> name component n geometry #> #> 1 339318500 1 0 (76.47491 15.34167) #> 2 339318502 1 1 (76.47612 15.34173) #> 3 2398958028 1 2 (76.47621 15.34174) #> 4 1427116077 1 3 (76.47628 15.34179) #> 5 7799710916 1 4 (76.47634 15.34184) #> 6 339318503 1 5 (76.47641 15.3419) #> # ℹ 3,331 more rows #> # #> # Edge data: 6,813 × 12 #> from to weight d_weighted time time_weighted xfr yfr xto yto #> #> 1 1 2 130. 144. 39.0 43.3 76.5 15.3 76.5 15.3 #> 2 2 1 130. 144. 39.0 43.3 76.5 15.3 76.5 15.3 #> 3 2 3 8.89 9.88 2.67 2.96 76.5 15.3 76.5 15.3 #> # ℹ 6,810 more rows #> # ℹ 2 more variables: component , geometry # From a linnet object. if (require(spatstat.geom, quietly = TRUE)) { as_sfnetwork(simplenet) } #> spatstat.univar 3.1-1 #> spatstat.geom 3.3-3 #> # A sfnetwork: 10 nodes and 10 edges #> # #> # A directed acyclic simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0.1497036 ymin: 0.1608339 xmax: 0.8418658 ymax: 0.9415173 #> # CRS: NA #> # #> # Node data: 10 × 1 (active) #> geom #> #> 1 (0.181276 0.8345078) #> 2 (0.3254689 0.4607012) #> 3 (0.1497036 0.2119066) #> 4 (0.5358572 0.8028913) #> 5 (0.4411403 0.1608339) #> 6 (0.3795058 0.3206155) #> # ℹ 4 more rows #> # #> # Edge data: 10 × 4 #> from to label geom #> #> 1 1 2 segment (0.181276 0.8345078, 0.3254689 0.4607012) #> 2 3 2 segment (0.1497036 0.2119066, 0.3254689 0.4607012) #> 3 2 4 segment (0.3254689 0.4607012, 0.5358572 0.8028913) #> # ℹ 7 more rows # From a psp object. if (require(spatstat.geom, quietly = TRUE)) { set.seed(42) test_psp = psp(runif(10), runif(10), runif(10), runif(10), window=owin()) as_sfnetwork(test_psp) } #> # A sfnetwork: 20 nodes and 10 edges #> # #> # A rooted forest with 10 trees and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0.08243756 ymin: 0.003948339 xmax: 0.9888917 ymax: 0.9782264 #> # CRS: NA #> # #> # Node data: 20 × 1 (active) #> geom #> #> 1 (0.914806 0.4577418) #> 2 (0.9040314 0.7375956) #> 3 (0.9370754 0.7191123) #> 4 (0.1387102 0.8110551) #> 5 (0.2861395 0.9346722) #> 6 (0.9888917 0.3881083) #> # ℹ 14 more rows #> # #> # Edge data: 10 × 4 #> from to label geom #> #> 1 1 2 segment (0.914806 0.4577418, 0.9040314 0.7375956) #> 2 3 4 segment (0.9370754 0.7191123, 0.1387102 0.8110551) #> 3 5 6 segment (0.2861395 0.9346722, 0.9888917 0.3881083) #> # ℹ 7 more rows # From a tbl_graph with coordinate columns. library(tidygraph, quietly = TRUE) #> #> Attaching package: ‘tidygraph’ #> The following object is masked from ‘package:stats’: #> #> filter nodes = data.frame(lat = c(7, 7, 8), lon = c(51, 52, 52)) edges = data.frame(from = c(1, 1, 3), to = c(2, 3, 2)) tbl_net = tbl_graph(nodes, edges) as_sfnetwork(tbl_net, coords = c(\"lon\", \"lat\"), crs = 4326) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> ✔ Spatial network structure is valid #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed acyclic simple graph with 1 component and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 51 ymin: 7 xmax: 52 ymax: 8 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 1 (active) #> geometry #> #> 1 (51 7) #> 2 (52 7) #> 3 (52 8) #> # #> # Edge data: 3 × 2 #> from to #> #> 1 1 2 #> 2 1 3 #> 3 3 2"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_tibble.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract the active element of a sfnetwork as spatial tibble — as_tibble","title":"Extract the active element of a sfnetwork as spatial tibble — as_tibble","text":"sfnetwork method as_tibble conceptually different. Whenever geometry list column present, default return call 'spatial tibble'. mean object class c('sf', 'tbl_df') instead object class 'tbl_df'. little conceptual trick essential tidyverse functions handle sfnetwork objects, .e. always using corresponding sf method present. using as_tibble sfnetwork objects directly user, can disable behaviour setting spatial = FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_tibble.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract the active element of a sfnetwork as spatial tibble — as_tibble","text":"","code":"# S3 method for class 'sfnetwork' as_tibble(x, active = NULL, focused = TRUE, spatial = TRUE, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_tibble.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract the active element of a sfnetwork as spatial tibble — as_tibble","text":"x object class sfnetwork. active network element (.e. nodes edges) activate extracting. NULL, set current active element given network. Defaults NULL. focused features focus extracted? Defaults TRUE. See focus information focused networks. spatial extracted tibble 'spatial tibble', .e. object class c('sf', 'tbl_df'), contains geometry list column. Defaults TRUE. ... Arguments passed as_tibble.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_tibble.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract the active element of a sfnetwork as spatial tibble — as_tibble","text":"active element network object class sf geometry list column present spatial = TRUE, object class tibble otherwise.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_tibble.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Extract the active element of a sfnetwork as spatial tibble — as_tibble","text":"","code":"library(tibble, quietly = TRUE) net = as_sfnetwork(roxel) # Extract the active network element as a spatial tibble. as_tibble(net) #> Simple feature collection with 987 features and 0 fields #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> 7 (7.525977 51.95283) #> 8 (7.526581 51.95293) #> 9 (7.532301 51.95559) #> 10 (7.532142 51.95589) #> # ℹ 977 more rows # Extract any network element as a spatial tibble. as_tibble(net, \"edges\") #> Simple feature collection with 1215 features and 4 fields #> Attribute-geometry relationships: constant (2), NA's (2) #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… #> 5 9 10 Annette-von-Droste-Hülshoff-Stra… seco… (7.532301 51.95559, 7.53… #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… #> 7 13 14 Deermannskamp resi… (7.537675 51.95689, 7.53… #> 8 15 16 Lindenstraße resi… (7.539105 51.9504, 7.540… #> 9 17 18 NA NA (7.534875 51.95795, 7.53… #> 10 19 20 Annette-von-Droste-Hülshoff-Stra… seco… (7.532465 51.95424, 7.53… #> # ℹ 1,205 more rows # Extract the active network element as a regular tibble. as_tibble(net, spatial = FALSE) #> # A tibble: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> 7 (7.525977 51.95283) #> 8 (7.526581 51.95293) #> 9 (7.532301 51.95559) #> 10 (7.532142 51.95589) #> # ℹ 977 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/autoplot.html","id":null,"dir":"Reference","previous_headings":"","what":"Plot sfnetwork geometries with ggplot2 — autoplot","title":"Plot sfnetwork geometries with ggplot2 — autoplot","text":"Plot geometries object class sfnetwork automatically ggplot object. Use method without .sfnetwork suffix loading ggplot2 package.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/autoplot.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Plot sfnetwork geometries with ggplot2 — autoplot","text":"","code":"autoplot.sfnetwork(object, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/autoplot.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Plot sfnetwork geometries with ggplot2 — autoplot","text":"object object class sfnetwork. ... Ignored.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/autoplot.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Plot sfnetwork geometries with ggplot2 — autoplot","text":"object class ggplot.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/autoplot.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Plot sfnetwork geometries with ggplot2 — autoplot","text":"See autoplot.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/bind_spatial.html","id":null,"dir":"Reference","previous_headings":"","what":"Add nodes or edges to a spatial network. — bind_spatial","title":"Add nodes or edges to a spatial network. — bind_spatial","text":"functions spatially aware versions tidygraph's bind_nodes bind_edges allow add rows nodes edges tables sfnetwork object. bind_rows columns matched name filled NA column exist instances.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/bind_spatial.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Add nodes or edges to a spatial network. — bind_spatial","text":"","code":"bind_spatial_nodes(.data, ...) bind_spatial_edges(.data, ..., node_key = \"name\", force = FALSE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/bind_spatial.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Add nodes or edges to a spatial network. — bind_spatial","text":".data object class sfnetwork. ... One objects class sf containing nodes edges added. node_key name column nodes table character represented columns matched . NA, first column always chosen. setting effect given integers. Defaults 'name'. force network validity checks skipped? Defaults FALSE, meaning network validity checks executed binding edges, making sure boundary points edges match corresponding node coordinates.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/bind_spatial.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Add nodes or edges to a spatial network. — bind_spatial","text":"object class sfnetwork added nodes edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/bind_spatial.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Add nodes or edges to a spatial network. — bind_spatial","text":"","code":"library(sf, quietly = TRUE) library(dplyr, quietly = TRUE) #> #> Attaching package: ‘dplyr’ #> The following objects are masked from ‘package:stats’: #> #> filter, lag #> The following objects are masked from ‘package:base’: #> #> intersect, setdiff, setequal, union net = roxel |> slice(c(1:2)) |> st_transform(3035) |> as_sfnetwork() pts = roxel |> slice(c(3:4)) |> st_transform(3035) |> st_centroid() #> Warning: st_centroid assumes attributes are constant over geometries bind_spatial_nodes(net, pts) #> # A sfnetwork: 6 nodes and 2 edges #> # #> # A rooted forest with 4 trees and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150969 ymin: 3207609 xmax: 4151784 ymax: 3208259 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 6 × 3 (active) #> name type geometry #> #> 1 NA NA (4151782 3207612) #> 2 NA NA (4151765 3207609) #> 3 NA NA (4151784 3208259) #> 4 NA NA (4151728 3208240) #> 5 Havixbecker Straße residential (4151473 3207938) #> 6 Holzschuhmacherweg residential (4150969 3207642) #> # #> # Edge data: 2 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (4151782 3207612, 4151765 3207609) #> 2 3 4 Stiegkamp residential (4151784 3208259, 4151728 3208240)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/contract_nodes.html","id":null,"dir":"Reference","previous_headings":"","what":"Contract groups of nodes in a spatial network — contract_nodes","title":"Contract groups of nodes in a spatial network — contract_nodes","text":"Combine groups nodes single node per group. centroid group used default new geometry contracted node. edges spatially explicit, edge geometries updated accordingly valid spatial network structure preserved.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/contract_nodes.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Contract groups of nodes in a spatial network — contract_nodes","text":"","code":"contract_nodes( x, groups, simplify = TRUE, compute_centroids = TRUE, reconnect_edges = TRUE, attribute_summary = \"ignore\", store_original_ids = FALSE, store_original_data = FALSE )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/contract_nodes.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Contract groups of nodes in a spatial network — contract_nodes","text":"x object class sfnetwork. groups group index node x. simplify network simplified contraction? Defaults TRUE. means multiple edges loop edges removed. Multiple edges introduced contraction several connections groups nodes. Loop edges introduced contraction connections within group. Note however setting TRUE also removes multiple edges loop edges already existed contraction. compute_centroids new geometry contracted group nodes centroid group members? Defaults TRUE. set FALSE, geometry first node group used instead, requires considerably less computing time. reconnect_edges geometries edges updated match new node geometries? Defaults TRUE. set FALSE know node geometries change, otherwise valid spatial network structure broken. attribute_summary attributes contracted nodes summarized? several options, see igraph-attribute-combination details. store_original_ids group contracted nodes, indices original nodes stored attribute new edge, column named .tidygraph_node_index? line design principles tidygraph. Defaults FALSE. store_original_data group contracted nodes, data original nodes stored attribute new edge, column named .orig_data? line design principles tidygraph. Defaults FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/contract_nodes.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Contract groups of nodes in a spatial network — contract_nodes","text":"contracted network object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_lines.html","id":null,"dir":"Reference","previous_headings":"","what":"Create a spatial network from linestring geometries — create_from_spatial_lines","title":"Create a spatial network from linestring geometries — create_from_spatial_lines","text":"Create spatial network linestring geometries","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_lines.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Create a spatial network from linestring geometries — create_from_spatial_lines","text":"","code":"create_from_spatial_lines( x, directed = TRUE, compute_length = FALSE, subdivide = FALSE )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_lines.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Create a spatial network from linestring geometries — create_from_spatial_lines","text":"x object class sf sfc LINESTRING geometries. directed constructed network directed? Defaults TRUE. compute_length geographic length edges stored column named length? Uses st_length compute length edge geometries. already column named length, overwritten. Please note values column automatically recognized edge weights. needs specified explicitly calling function uses edge weights. Defaults FALSE. subdivide given linestring geometries subdivided locations interior point equal interior boundary point another feature? connect features locations. Defaults FALSE, meaning features connected boundaries.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_lines.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Create a spatial network from linestring geometries — create_from_spatial_lines","text":"object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_lines.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Create a spatial network from linestring geometries — create_from_spatial_lines","text":"assumed given linestring geometries form edges network. Nodes created line boundaries. Shared boundaries multiple linestrings become node.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_lines.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Create a spatial network from linestring geometries — create_from_spatial_lines","text":"default sfnetworks rounds coordinates 12 decimal places determine spatial equality. can influence behavior explicitly setting precision linestrings using st_set_precision.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_lines.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Create a spatial network from linestring geometries — create_from_spatial_lines","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) net = as_sfnetwork(roxel) net #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows plot(st_geometry(roxel)) plot(net) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_points.html","id":null,"dir":"Reference","previous_headings":"","what":"Create a spatial network from point geometries — create_from_spatial_points","title":"Create a spatial network from point geometries — create_from_spatial_points","text":"Create spatial network point geometries","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_points.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Create a spatial network from point geometries — create_from_spatial_points","text":"","code":"create_from_spatial_points( x, connections = \"complete\", directed = TRUE, edges_as_lines = TRUE, compute_length = FALSE, k = 1 )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_points.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Create a spatial network from point geometries — create_from_spatial_points","text":"x object class sf sfc POINT geometries. connections connect given point geometries ? Can specified either adjacency matrix, character describing specific method define connections. See Details. directed constructed network directed? Defaults TRUE. edges_as_lines created edges spatially explicit, .e. LINESTRING geometries stored geometry list column? Defaults TRUE. compute_length geographic length edges stored column named length? Uses st_length compute length edge geometries edges spatially explicit, st_distance compute distance boundary nodes edges spatially implicit. Please note values column automatically recognized edge weights. needs specified explicitly calling function uses edge weights. Defaults FALSE. k amount neighbors connect connections = 'knn'. Defaults 1, meaning nodes connected nearest neighbor. Ignored value connected argument.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_points.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Create a spatial network from point geometries — create_from_spatial_points","text":"object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_points.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Create a spatial network from point geometries — create_from_spatial_points","text":"assumed given points form nodes network. nodes connected edges depends connections argument. connections can specified adjacency matrix , n x n matrix n number nodes, element Aij holding TRUE value edge node node j, FALSE value otherwise. case undirected networks, matrix tested symmetry, edge exist node node j either element Aij element Aji TRUE. Non-logical matrices first converted logical matrices using .logical, whenever possible. provided adjacency matrix may also sparse. can object one sparse matrix classes Matrix package, list-formatted sparse matrix. list one element per node, holding integer indices nodes adjacent . example sgbp objects. values integers, first converted integers using .integer, whenever possible. Alternatively, connections can specified providing name specific method create adjacency matrix internally. Valid options : complete: nodes directly connected . sequence: nodes sequentially connected , meaning first node connected second node, second node connected third node, et cetera. mst: nodes connected spatial minimum spanning tree, .e. set edges minimum total edge length required connect nodes. tree always constructed undirected network, regardless value directed. argument. directed = TRUE, edge duplicated reversed ensure full connectivity network. Can also specified minimum_spanning_tree. delaunay: nodes connected Delaunay triangulation. Requires spdep package installed, assumes planar coordinates. gabriel: nodes connected Gabriel graph. Requires spdep package installed, assumes planar coordinates. rn: nodes connected relative neighborhood graph. Can also specified relative_neighborhood relative_neighbourhood. Requires spdep package installed, assumes planar coordinates. knn: node connected k nearest neighbors, k specified k argument. default, k = 1, meaning nodes connected nearest neighbor graph. Can also specified nearest_neighbors nearest_neighbours. Requires spdep package installed.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_points.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Create a spatial network from point geometries — create_from_spatial_points","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) pts = st_transform(mozart, 3035) # Using a custom adjacency matrix adj = matrix(c(rep(TRUE, 17), rep(rep(FALSE, 17), 16)), nrow = 17) net = as_sfnetwork(pts, connections = adj) plot(net) # Using a sparse adjacency matrix from a spatial predicate dst = units::set_units(300, \"m\") adj = st_is_within_distance(pts, dist = dst, remove_self = TRUE) net = as_sfnetwork(pts, connections = adj, directed = FALSE) plot(net) # Using pre-defined methods cnet = as_sfnetwork(pts, connections = \"complete\") snet = as_sfnetwork(pts, connections = \"sequence\") mnet = as_sfnetwork(pts, connections = \"mst\") dnet = as_sfnetwork(pts, connections = \"delaunay\") gnet = as_sfnetwork(pts, connections = \"gabriel\") rnet = as_sfnetwork(pts, connections = \"rn\") nnet = as_sfnetwork(pts, connections = \"knn\") #> Warning: neighbour object has 4 sub-graphs knet = as_sfnetwork(pts, connections = \"knn\", k = 2) #> Warning: neighbour object has 2 sub-graphs par(mar = c(1,1,1,1), mfrow = c(4,2)) plot(cnet, main = \"complete\") plot(snet, main = \"sequence\") plot(mnet, main = \"minimum spanning tree\") plot(dnet, main = \"delaunay triangulation\") plot(gnet, main = \"gabriel graph\") plot(rnet, main = \"relative neighborhood graph\") plot(nnet, main = \"nearest neighbor graph\") plot(knet, main = \"k nearest neighbor graph (k = 2)\") par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/data.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract the node or edge data from a spatial network — data","title":"Extract the node or edge data from a spatial network — data","text":"Extract node edge data spatial network","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/data.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract the node or edge data from a spatial network — data","text":"","code":"node_data(x, focused = TRUE) edge_data(x, focused = TRUE, require_sf = FALSE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/data.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract the node or edge data from a spatial network — data","text":"x object class sfnetwork. focused features focus extracted? Defaults TRUE. See focus information focused networks. require_sf sf object required? make extraction edge data fail edges spatially implicit. Defaults FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/data.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract the node or edge data from a spatial network — data","text":"nodes, always object class sf. edges, object class sf edges spatially explicit, object class tibble edges spatially implicity require_sf = FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/data.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Extract the node or edge data from a spatial network — data","text":"","code":"net = as_sfnetwork(roxel[1:10, ]) node_data(net) #> Simple feature collection with 20 features and 0 fields #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 7.525978 ymin: 51.94779 xmax: 7.543685 ymax: 51.95867 #> Geodetic CRS: WGS 84 #> # A tibble: 20 × 1 #> geometry #> * #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> 7 (7.525977 51.95283) #> 8 (7.526581 51.95293) #> 9 (7.532301 51.95559) #> 10 (7.532142 51.95589) #> 11 (7.543404 51.94779) #> 12 (7.543685 51.9479) #> 13 (7.537675 51.95689) #> 14 (7.537904 51.95656) #> 15 (7.539105 51.9504) #> 16 (7.540105 51.95058) #> 17 (7.534875 51.95795) #> 18 (7.533743 51.95769) #> 19 (7.532465 51.95424) #> 20 (7.532441 51.95482) edge_data(net) #> Simple feature collection with 10 features and 4 fields #> Attribute-geometry relationships: constant (2), NA's (2) #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.525978 ymin: 51.94779 xmax: 7.543685 ymax: 51.95867 #> Geodetic CRS: WGS 84 #> # A tibble: 10 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… #> 5 9 10 Annette-von-Droste-Hülshoff-Stra… seco… (7.532301 51.95559, 7.53… #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… #> 7 13 14 Deermannskamp resi… (7.537675 51.95689, 7.53… #> 8 15 16 Lindenstraße resi… (7.539105 51.9504, 7.540… #> 9 17 18 NA NA (7.534875 51.95795, 7.53… #> 10 19 20 Annette-von-Droste-Hülshoff-Stra… seco… (7.532465 51.95424, 7.53…"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/dual_weights.html","id":null,"dir":"Reference","previous_headings":"","what":"Specify dual edge weights — dual_weights","title":"Specify dual edge weights — dual_weights","text":"Dual edge weights two sets edge weights, one (actual weight) determine shortest path, (reported weight) report cost path.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/dual_weights.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Specify dual edge weights — dual_weights","text":"","code":"dual_weights(reported, actual)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/dual_weights.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Specify dual edge weights — dual_weights","text":"reported edge weights reported. Evaluated evaluate_weight_spec. actual actual edge weights used determine shortest paths. Evaluated evaluate_weight_spec.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/dual_weights.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Specify dual edge weights — dual_weights","text":"object class dual_weights.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/dual_weights.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Specify dual edge weights — dual_weights","text":"Dual edge weights enable dual-weighted routing. supported dodgr routing backend.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_edge_query.html","id":null,"dir":"Reference","previous_headings":"","what":"Query specific edge indices from a spatial network — evaluate_edge_query","title":"Query specific edge indices from a spatial network — evaluate_edge_query","text":"function meant called directly, used inside functions accept edge query.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_edge_query.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query specific edge indices from a spatial network — evaluate_edge_query","text":"","code":"evaluate_edge_query(data, query)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_edge_query.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Query specific edge indices from a spatial network — evaluate_edge_query","text":"data object class sfnetwork. query query defines edges extract indices, defused quosure. See Details different ways edge queries can formulated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_edge_query.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query specific edge indices from a spatial network — evaluate_edge_query","text":"vector queried edge indices.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_edge_query.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Query specific edge indices from a spatial network — evaluate_edge_query","text":"multiple ways edge indices can queried sfnetworks. query can formatted follows: spatial features: Spatial features can given object class sf sfc. nearest edge feature found calling st_nearest_feature. edge type query function: edge type query function defines edge given type . Nodes meet criterium queried. edge predicate query function: edge predicate query function defines edge given spatial predicate applies spatial relation edge spatial features. Nodes meet criterium queried. column name: referenced column expected logical values defining edge queried . Note tidy evaluation used hence column name unquoted. integers: Integers interpreted edge indices. edge index corresponds row-number edges table network. characters: Characters interpreted edge names. edge name corresponds value column named \"name\" edges table network. Note column expected store unique names without duplicated values. logicals: Logicals define edge queried . Queries can evaluated ways described forcefully converted integers using .integer.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_node_query.html","id":null,"dir":"Reference","previous_headings":"","what":"Query specific node indices from a spatial network — evaluate_node_query","title":"Query specific node indices from a spatial network — evaluate_node_query","text":"function meant called directly, used inside functions accept node query.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_node_query.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query specific node indices from a spatial network — evaluate_node_query","text":"","code":"evaluate_node_query(data, query)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_node_query.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Query specific node indices from a spatial network — evaluate_node_query","text":"data object class sfnetwork. query query defines nodes extract indices, defused quosure. See Details different ways node queries can formulated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_node_query.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query specific node indices from a spatial network — evaluate_node_query","text":"vector queried node indices.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_node_query.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Query specific node indices from a spatial network — evaluate_node_query","text":"multiple ways node indices can queried sfnetworks. query can formatted follows: spatial features: Spatial features can given object class sf sfc. nearest node feature found calling st_nearest_feature. node type query function: node type query function defines node given type . Nodes meet criterium queried. node predicate query function: node predicate query function defines node given spatial predicate applies spatial relation node spatial features. Nodes meet criterium queried. column name: referenced column expected logical values defining node queried . Note tidy evaluation used hence column name unquoted. integers: Integers interpreted node indices. node index corresponds row-number nodes table network. characters: Characters interpreted node names. node name corresponds value column named \"name\" nodes table network. Note column expected store unique names without duplicated values. logicals: Logicals define node queried . Queries can evaluated ways described forcefully converted integers using .integer.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_weight_spec.html","id":null,"dir":"Reference","previous_headings":"","what":"Specify edge weights in a spatial network — evaluate_weight_spec","title":"Specify edge weights in a spatial network — evaluate_weight_spec","text":"function meant called directly, used inside functions accept specification edge weights.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_weight_spec.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Specify edge weights in a spatial network — evaluate_weight_spec","text":"","code":"evaluate_weight_spec(data, spec)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_weight_spec.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Specify edge weights in a spatial network — evaluate_weight_spec","text":"data object class sfnetwork. spec specification defines compute extract edge weights defused quosure. See Details different ways edge weights can specified.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_weight_spec.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Specify edge weights in a spatial network — evaluate_weight_spec","text":"numeric vector edge weights.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_weight_spec.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Specify edge weights in a spatial network — evaluate_weight_spec","text":"multiple ways edge weights can specified sfnetworks. specification can formatted follows: edge measure function: spatial edge measure function computes given measure edge, used edge weights. column name: column edges table network contains edge weights. Note tidy evaluation used hence column name unquoted. numeric vector: vector length number edges network, specifying edge weight . dual weights: Dual weights can specified dual_weights function. allows use different set weights shortest paths computation reporting total cost paths. Note every routing backend support dual-weighted routing. weight specification NULL NA, means edge weights used. shortest path computation, means shortest path simply path fewest number edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_weight_spec.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Specify edge weights in a spatial network — evaluate_weight_spec","text":"backward compatibility currently also still possible format specification quoted column name, may removed future versions. Also note many shortest path algorithms require edge weights positive.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/group_spatial.html","id":null,"dir":"Reference","previous_headings":"","what":"Group nodes based on spatial distance — group_spatial","title":"Group nodes based on spatial distance — group_spatial","text":"functions forms spatial extension grouping functions tidygraph, allowing detect communities spatial clustering algorithms.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/group_spatial.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Group nodes based on spatial distance — group_spatial","text":"","code":"group_spatial_dbscan(epsilon, min_pts = 1, use_network_distance = TRUE, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/group_spatial.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Group nodes based on spatial distance — group_spatial","text":"epsilon value epsilon parameter DBSCAN clustering algorithm, defining radius neighborhood node. min_pts value minPts parameter DBSCAN clustering algorithm, defining minimum number points neighborhood considered core point. use_network_distance distance nodes computed distance network (using st_network_distance? Defaults TRUE. set FALSE, straight-line distance (using st_distance) computed instead. ... Additional arguments passed clustering algorithm.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/group_spatial.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Group nodes based on spatial distance — group_spatial","text":"numeric vector membership node network. enumeration happens order based group size progressing largest smallest group.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/group_spatial.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Group nodes based on spatial distance — group_spatial","text":"Just grouping functions tidygraph, spatial grouping functions meant called inside tidygraph verbs mutate filter, network currently worked known thus needed argument function. want use algorithm outside tidygraph framework can use with_graph set context temporarily algorithm evaluated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/group_spatial.html","id":"functions","dir":"Reference","previous_headings":"","what":"Functions","title":"Group nodes based on spatial distance — group_spatial","text":"group_spatial_dbscan(): Uses density-based spatial clustering implemented dbscan function dbscan package. requires dbscan package installed. node marked noise form cluster.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/group_spatial.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Group nodes based on spatial distance — group_spatial","text":"","code":"library(tidygraph, quietly = TRUE) play_geometric(10, 0.5) |> activate(nodes) |> mutate(group = group_spatial_dbscan(0.25)) #> # A sfnetwork: 10 nodes and 23 edges #> # #> # An undirected simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0.03743103 ymin: 0.1712643 xmax: 0.9709666 ymax: 0.9735399 #> # CRS: NA #> # #> # Node data: 10 × 2 (active) #> geometry group #> #> 1 (0.03743103 0.4357716) 2 #> 2 (0.03893649 0.9735399) 1 #> 3 (0.261088 0.9575766) 1 #> 4 (0.3334272 0.6399788) 1 #> 5 (0.3795592 0.6188382) 1 #> 6 (0.3984854 0.3467482) 3 #> # ℹ 4 more rows #> # #> # Edge data: 23 × 3 #> from to geometry #> #> 1 1 4 (0.03743103 0.4357716, 0.3334272 0.6399788) #> 2 1 5 (0.03743103 0.4357716, 0.3795592 0.6188382) #> 3 1 6 (0.03743103 0.4357716, 0.3984854 0.3467482) #> # ℹ 20 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/ids.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract all node or edge indices from a spatial network — ids","title":"Extract all node or edge indices from a spatial network — ids","text":"Extract node edge indices spatial network","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/ids.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract all node or edge indices from a spatial network — ids","text":"","code":"node_ids(x, focused = TRUE) edge_ids(x, focused = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/ids.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract all node or edge indices from a spatial network — ids","text":"x object class sfnetwork. focused indices features focus extracted? Defaults TRUE. See focus information focused networks.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/ids.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract all node or edge indices from a spatial network — ids","text":"vector integers.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/ids.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Extract all node or edge indices from a spatial network — ids","text":"indices objects always integers correspond rownumbers respectively nodes edges table.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/ids.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Extract all node or edge indices from a spatial network — ids","text":"","code":"net = as_sfnetwork(roxel[1:10, ]) node_ids(net) #> [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 edge_ids(net) #> [1] 1 2 3 4 5 6 7 8 9 10"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/is_sfnetwork.html","id":null,"dir":"Reference","previous_headings":"","what":"Check if an object is a sfnetwork — is_sfnetwork","title":"Check if an object is a sfnetwork — is_sfnetwork","text":"Check object sfnetwork","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/is_sfnetwork.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Check if an object is a sfnetwork — is_sfnetwork","text":"","code":"is_sfnetwork(x) is.sfnetwork(x)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/is_sfnetwork.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Check if an object is a sfnetwork — is_sfnetwork","text":"x Object checked.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/is_sfnetwork.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Check if an object is a sfnetwork — is_sfnetwork","text":"TRUE given object object class sfnetwork, FALSE otherwise.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/is_sfnetwork.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Check if an object is a sfnetwork — is_sfnetwork","text":"","code":"library(tidygraph, quietly = TRUE, warn.conflicts = FALSE) net = as_sfnetwork(roxel) is_sfnetwork(net) #> [1] TRUE is_sfnetwork(as_tbl_graph(net)) #> [1] FALSE"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_directed.html","id":null,"dir":"Reference","previous_headings":"","what":"Convert undirected edges into directed edges based on their geometries — make_edges_directed","title":"Convert undirected edges into directed edges based on their geometries — make_edges_directed","text":"function converts undirected network directed network following direction given linestring geometries edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_directed.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Convert undirected edges into directed edges based on their geometries — make_edges_directed","text":"","code":"make_edges_directed(x)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_directed.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Convert undirected edges into directed edges based on their geometries — make_edges_directed","text":"x object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_directed.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Convert undirected edges into directed edges based on their geometries — make_edges_directed","text":"directed network object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_directed.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Convert undirected edges into directed edges based on their geometries — make_edges_directed","text":"undirected spatial networks required boundary edge geometries contain incident node geometries. However, required start point equals specified ** node end point specified ** node. Instead, may vice versa. undirected networks ** ** indices always swopped ** index lower ** index. Therefore, direction given ** ** indices necessarily match direction given edge geometries.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_directed.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Convert undirected edges into directed edges based on their geometries — make_edges_directed","text":"network already directed returned unmodified.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_explicit.html","id":null,"dir":"Reference","previous_headings":"","what":"Construct edge geometries for spatially implicit networks — make_edges_explicit","title":"Construct edge geometries for spatially implicit networks — make_edges_explicit","text":"function turns spatially implicit networks spatially explicit networks adding geometry column edge data.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_explicit.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Construct edge geometries for spatially implicit networks — make_edges_explicit","text":"","code":"make_edges_explicit(x, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_explicit.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Construct edge geometries for spatially implicit networks — make_edges_explicit","text":"x object class sfnetwork. ... Arguments forwarded st_as_sf directly convert edges table sf object. arguments given, edges made explicit simply drawing straight lines start end node edge.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_explicit.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Construct edge geometries for spatially implicit networks — make_edges_explicit","text":"object class sfnetwork spatially explicit edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_explicit.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Construct edge geometries for spatially implicit networks — make_edges_explicit","text":"network already spatially explicit returned unmodified.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_follow_indices.html","id":null,"dir":"Reference","previous_headings":"","what":"Match the direction of edge geometries to their specified incident nodes — make_edges_follow_indices","title":"Match the direction of edge geometries to their specified incident nodes — make_edges_follow_indices","text":"function updates edge geometries undirected networks guaranteed start specified ** node end specified ** node.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_follow_indices.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Match the direction of edge geometries to their specified incident nodes — make_edges_follow_indices","text":"","code":"make_edges_follow_indices(x)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_follow_indices.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Match the direction of edge geometries to their specified incident nodes — make_edges_follow_indices","text":"x object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_follow_indices.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Match the direction of edge geometries to their specified incident nodes — make_edges_follow_indices","text":"object class sfnetwork updated edge geometries.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_follow_indices.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Match the direction of edge geometries to their specified incident nodes — make_edges_follow_indices","text":"undirected spatial networks required boundary edge geometries contain incident node geometries. However, required start point equals specified ** node end point specified ** node. Instead, may vice versa. undirected networks ** ** indices always swopped ** index lower ** index. function reverses edge geometries start ** node end ** node, resulting network guaranteed edge boundary points exactly match incident node geometries. directed networks, change.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_implicit.html","id":null,"dir":"Reference","previous_headings":"","what":"Drop edge geometries of spatially explicit networks — make_edges_implicit","title":"Drop edge geometries of spatially explicit networks — make_edges_implicit","text":"function turns spatially explicit networks spatially implicit networks dropping geometry column edge data.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_implicit.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Drop edge geometries of spatially explicit networks — make_edges_implicit","text":"","code":"make_edges_implicit(x)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_implicit.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Drop edge geometries of spatially explicit networks — make_edges_implicit","text":"x object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_implicit.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Drop edge geometries of spatially explicit networks — make_edges_implicit","text":"object class sfnetwork spatially implicit edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_implicit.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Drop edge geometries of spatially explicit networks — make_edges_implicit","text":"network already spatially implicit returned unmodified.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_mixed.html","id":null,"dir":"Reference","previous_headings":"","what":"Make some edges directed and some undirected — make_edges_mixed","title":"Make some edges directed and some undirected — make_edges_mixed","text":"function creates mixed network, meaning edges directed, undirected. practice implemented directed network edges meant undirected duplicated reversed.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_mixed.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Make some edges directed and some undirected — make_edges_mixed","text":"","code":"make_edges_mixed(x, directed)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_mixed.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Make some edges directed and some undirected — make_edges_mixed","text":"x object class sfnetwork. directed integer vector edge indices specifying edges directed.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_mixed.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Make some edges directed and some undirected — make_edges_mixed","text":"mixed network object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_valid.html","id":null,"dir":"Reference","previous_headings":"","what":"Match edge geometries to their incident node locations — make_edges_valid","title":"Match edge geometries to their incident node locations — make_edges_valid","text":"function makes invalid edges valid modifying either edge node geometries boundary points edge linestring geometries always match point geometries nodes specified incident nodes ** ** columns.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_valid.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Match edge geometries to their incident node locations — make_edges_valid","text":"","code":"make_edges_valid(x, preserve_geometries = FALSE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_valid.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Match edge geometries to their incident node locations — make_edges_valid","text":"x object class sfnetwork. preserve_geometries edge geometries remain unmodified? Defaults FALSE. See Details.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_valid.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Match edge geometries to their incident node locations — make_edges_valid","text":"object class sfnetwork corrected edge geometries.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_valid.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Match edge geometries to their incident node locations — make_edges_valid","text":"geometries preserved, edges made valid adding edge boundary points equal corresponding node geometry new nodes network, updating ** ** indices match newly added nodes. FALSE, edges made valid modifying geometries, .e. edge boundary points equal corresponding node geometry replaced node geometry.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_valid.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Match edge geometries to their incident node locations — make_edges_valid","text":"function works edge geometries meant start specified ** node end specified ** node. undirected networks necessarily case, since edge geometries allowed start specified ** node end specified ** node. Therefore, undirected networks edges first reversed running function. Use make_edges_follow_indices .","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/mozart.html","id":null,"dir":"Reference","previous_headings":"","what":"Point locations for places about W. A. Mozart in Salzburg, Austria — mozart","title":"Point locations for places about W. A. Mozart in Salzburg, Austria — mozart","text":"dataset containing point locations (museums, sculptures, squares, universities, etc.) places named Wolfgang Amadeus Mozart city Salzburg, Austria. data taken OpenStreetMap. See `data-raw/mozart.R` code creation.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/mozart.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Point locations for places about W. A. Mozart in Salzburg, Austria — mozart","text":"","code":"mozart"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/mozart.html","id":"format","dir":"Reference","previous_headings":"","what":"Format","title":"Point locations for places about W. A. Mozart in Salzburg, Austria — mozart","text":"object class sf LINESTRING geometries, containing 17 features four columns: name name point location type type location, e.g. museum, artwork, cinema, etc. website website URL information place, available geometry geometry list column","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/mozart.html","id":"source","dir":"Reference","previous_headings":"","what":"Source","title":"Point locations for places about W. A. Mozart in Salzburg, Austria — mozart","text":"https://www.openstreetmap.org","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/n.html","id":null,"dir":"Reference","previous_headings":"","what":"Count the number of nodes or edges in a network — n","title":"Count the number of nodes or edges in a network — n","text":"Count number nodes edges network","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/n.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Count the number of nodes or edges in a network — n","text":"","code":"n_nodes(x, focused = FALSE) n_edges(x, focused = FALSE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/n.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Count the number of nodes or edges in a network — n","text":"x object class sfnetwork, network object inheriting igraph. focused features focus counted? Defaults FALSE. See focus information focused networks.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/n.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Count the number of nodes or edges in a network — n","text":"integer.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/n.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Count the number of nodes or edges in a network — n","text":"","code":"net = as_sfnetwork(roxel) n_nodes(net) #> [1] 987 n_edges(net) #> [1] 1215"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nb.html","id":null,"dir":"Reference","previous_headings":"","what":"Conversion between neighbor lists and sfnetworks — nb","title":"Conversion between neighbor lists and sfnetworks — nb","text":"Neighbor lists sparse adjacency matrices list format specify node nodes adjacent. occur example sf package sgbp objects, also frequently used spdep package.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nb.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Conversion between neighbor lists and sfnetworks — nb","text":"","code":"nb_to_sfnetwork( x, nodes, directed = TRUE, edges_as_lines = TRUE, compute_length = FALSE, force = FALSE ) sfnetwork_to_nb(x, direction = \"out\")"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nb.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Conversion between neighbor lists and sfnetworks — nb","text":"x conversion sfnetwork: neighbor list, list adjacent . conversion sfnetwork: object class sfnetwork. nodes nodes object class sf sfc POINT geometries. directed constructed network directed? Defaults TRUE. edges_as_lines created edges spatially explicit, .e. LINESTRING geometries stored geometry list column? Defaults TRUE. compute_length geographic length edges stored column named length? Defaults FALSE. force validity checks skipped? Defaults FALSE, meaning network validity checks executed constructing network. checks make sure provided neighbor list valid structure, .e. length equal number provided nodes values integers referring one nodes. direction direction defines two nodes neighbors. Defaults '', meaning direction given network followed node j neighbor node exists edge ->j. May set '', meaning opposite direction followed node j neighbor node exists edge j->. May also set '', meaning network considered undirected. argument ignored undirected networks.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nb.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Conversion between neighbor lists and sfnetworks — nb","text":"conversion sfnetwork: object class sfnetwork. conversion sfnetwork: neighbor list, list one element per node holds integer indices nodes adjacent .","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract the nearest nodes or edges to given spatial features — nearest","title":"Extract the nearest nodes or edges to given spatial features — nearest","text":"Extract nearest nodes edges given spatial features","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract the nearest nodes or edges to given spatial features — nearest","text":"","code":"nearest_nodes(x, y, focused = TRUE) nearest_edges(x, y, focused = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract the nearest nodes or edges to given spatial features — nearest","text":"x object class sfnetwork. y Spatial features object class sf sfc. focused features focus extracted? Defaults TRUE. See focus information focused networks.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract the nearest nodes or edges to given spatial features — nearest","text":"object class sf row containing nearest node edge corresponding spatial features y.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Extract the nearest nodes or edges to given spatial features — nearest","text":"determine nearest node edge feature y function st_nearest_feature used. extracting nearest edges, spatially explicit edges required, .e. edges table geometry column.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Extract the nearest nodes or edges to given spatial features — nearest","text":"","code":"library(sf, quietly = TRUE) net = as_sfnetwork(roxel) pts = st_sample(st_bbox(roxel), 6) nodes = nearest_nodes(net, pts) edges = nearest_edges(net, pts) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) plot(net, main = \"Nearest nodes\") plot(pts, cex = 2, col = \"red\", pch = 20, add = TRUE) plot(st_geometry(nodes), cex = 2, col = \"orange\", pch = 20, add = TRUE) plot(net, main = \"Nearest edges\") plot(pts, cex = 2, col = \"red\", pch = 20, add = TRUE) plot(st_geometry(edges), lwd = 2, col = \"orange\", pch = 20, add = TRUE) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest_ids.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract the indices of nearest nodes or edges to given spatial features — nearest_ids","title":"Extract the indices of nearest nodes or edges to given spatial features — nearest_ids","text":"Extract indices nearest nodes edges given spatial features","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest_ids.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract the indices of nearest nodes or edges to given spatial features — nearest_ids","text":"","code":"nearest_node_ids(x, y, focused = TRUE) nearest_edge_ids(x, y, focused = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest_ids.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract the indices of nearest nodes or edges to given spatial features — nearest_ids","text":"x object class sfnetwork. y Spatial features object class sf sfc. focused indices features focus extracted? Defaults TRUE. See focus information focused networks.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest_ids.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract the indices of nearest nodes or edges to given spatial features — nearest_ids","text":"integer vector element containing index nearest node edge corresponding spatial features y.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest_ids.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Extract the indices of nearest nodes or edges to given spatial features — nearest_ids","text":"determine nearest node edge feature y function st_nearest_feature used. extracting nearest edges, spatially explicit edges required, .e. edges table geometry column.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest_ids.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Extract the indices of nearest nodes or edges to given spatial features — nearest_ids","text":"","code":"library(sf, quietly = TRUE) net = as_sfnetwork(roxel) pts = st_sample(st_bbox(roxel), 6) nearest_node_ids(net, pts) #> [1] 761 256 8 353 985 730 nearest_edge_ids(net, pts) #> [1] 618 144 4 210 1192 939"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/node_coordinates.html","id":null,"dir":"Reference","previous_headings":"","what":"Query node coordinates — node_coordinates","title":"Query node coordinates — node_coordinates","text":"functions allow query specific coordinate values geometries nodes.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/node_coordinates.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query node coordinates — node_coordinates","text":"","code":"node_X() node_Y() node_Z() node_M()"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/node_coordinates.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query node coordinates — node_coordinates","text":"numeric vector length number nodes network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/node_coordinates.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Query node coordinates — node_coordinates","text":"Just query functions tidygraph, functions meant called inside tidygraph verbs mutate filter, network currently worked known thus needed argument function. want use algorithm outside tidygraph framework can use with_graph set context temporarily algorithm evaluated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/node_coordinates.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Query node coordinates — node_coordinates","text":"requested coordinate value available node, NA returned.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/node_coordinates.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Query node coordinates — node_coordinates","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) # Create a network. net = as_sfnetwork(roxel) # Use query function in a filter call. filtered = net |> activate(nodes) |> filter(node_X() > 7.54) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) plot(net, col = \"grey\") plot(filtered, col = \"red\", add = TRUE) par(oldpar) # Use query function in a mutate call. net |> activate(nodes) |> mutate(X = node_X(), Y = node_Y()) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 3 (active) #> geometry X Y #> #> 1 (7.538109 51.95286) 7.54 52.0 #> 2 (7.537867 51.95282) 7.54 52.0 #> 3 (7.537815 51.95867) 7.54 52.0 #> 4 (7.537015 51.95848) 7.54 52.0 #> 5 (7.533441 51.95578) 7.53 52.0 #> 6 (7.533415 51.95561) 7.53 52.0 #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows # Use query function directly. X = with_graph(net, node_X()) head(X) #> [1] 7.538109 7.537867 7.537815 7.537015 7.533441 7.533415"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/play_spatial.html","id":null,"dir":"Reference","previous_headings":"","what":"Create random spatial networks — play_spatial","title":"Create random spatial networks — play_spatial","text":"Random spatial networks created randomly sampling nodes within given area, connecting edges according specified method.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/play_spatial.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Create random spatial networks — play_spatial","text":"","code":"play_geometric( n, radius, bounds = NULL, edges_as_lines = TRUE, compute_length = FALSE, ... )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/play_spatial.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Create random spatial networks — play_spatial","text":"n number nodes sampled. radius radius within nodes connected edge. bounds spatial features within nodes sampled object class sf, sfc, sfg bbox. set NULL, nodes sampled within unit square. edges_as_lines created edges spatially explicit, .e. LINESTRING geometries stored geometry list column? Defaults TRUE. compute_length geographic length edges stored column named length? Uses st_length compute length edge geometries edges spatially explicit, st_distance compute distance boundary nodes edges spatially implicit. Please note values column automatically recognized edge weights. needs specified explicitly calling function uses edge weights. Defaults FALSE. ... Additional arguments passed st_sample. Ignored bounds = NULL.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/play_spatial.html","id":"functions","dir":"Reference","previous_headings":"","what":"Functions","title":"Create random spatial networks — play_spatial","text":"play_geometric(): Creates random geometric graph. Two nodes connected edge distance within given radius. nodes sampled unit square (.e. bounds = NULL) radius unitless. bounds given spatial feature, radius assumed meters geographic coordinates, units coordinate reference system projected coordinates. Alternatively, units can also specified explicitly providing units object.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/play_spatial.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Create random spatial networks — play_spatial","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) # Sample 10 nodes on a unit square # Connect nodes by an edge if they are within 0.25 distance from each other net = play_geometric(10, 0.25) net #> # A sfnetwork: 10 nodes and 6 edges #> # #> # An undirected simple graph with 5 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0.08561206 ymin: 0.0002388966 xmax: 0.9256447 ymax: 0.9330341 #> # CRS: NA #> # #> # Node data: 10 × 1 (active) #> geometry #> #> 1 (0.08561206 0.5636468) #> 2 (0.20857 0.08998052) #> 3 (0.2165673 0.3052184) #> 4 (0.2337034 0.0002388966) #> 5 (0.333072 0.9330341) #> 6 (0.6262453 0.7340943) #> # ℹ 4 more rows #> # #> # Edge data: 6 × 3 #> from to geometry #> #> 1 2 3 (0.20857 0.08998052, 0.2165673 0.3052184) #> 2 2 4 (0.20857 0.08998052, 0.2337034 0.0002388966) #> 3 6 7 (0.6262453 0.7340943, 0.6674265 0.5150633) #> # ℹ 3 more rows plot(net) # Sample 10 nodes within a spatial bounding box # Connect nodes by an edge if they are within 1 km from each other net = play_geometric(10, units::set_units(1, \"km\"), bounds = st_bbox(roxel)) net #> # A sfnetwork: 10 nodes and 32 edges #> # #> # An undirected simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.52265 ymin: 51.94154 xmax: 7.545803 ymax: 51.95783 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 10 × 1 (active) #> geometry #> #> 1 (7.545317 51.95206) #> 2 (7.545803 51.95209) #> 3 (7.540433 51.94154) #> 4 (7.540273 51.94851) #> 5 (7.535512 51.95356) #> 6 (7.52265 51.95783) #> # ℹ 4 more rows #> # #> # Edge data: 32 × 3 #> from to geometry #> #> 1 1 2 (7.545317 51.95206, 7.545803 51.95209) #> 2 1 4 (7.545317 51.95206, 7.540273 51.94851) #> 3 1 5 (7.545317 51.95206, 7.535512 51.95356) #> # ℹ 29 more rows plot(net) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/plot.sfnetwork.html","id":null,"dir":"Reference","previous_headings":"","what":"Plot the geometries of a sfnetwork — plot.sfnetwork","title":"Plot the geometries of a sfnetwork — plot.sfnetwork","text":"Plot geometries object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/plot.sfnetwork.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Plot the geometries of a sfnetwork — plot.sfnetwork","text":"","code":"# S3 method for class 'sfnetwork' plot(x, draw_lines = TRUE, node_args = list(), edge_args = list(), ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/plot.sfnetwork.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Plot the geometries of a sfnetwork — plot.sfnetwork","text":"x Object class sfnetwork. draw_lines edges network spatially implicit, straight lines drawn connected nodes? Defaults TRUE. Ignored edges network spatially explicit. node_args named list arguments passed plot.sf plotting nodes. edge_args named list arguments passed plot.sf plotting edges. ... Arguments passed plot.sf apply plot whole.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/plot.sfnetwork.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Plot the geometries of a sfnetwork — plot.sfnetwork","text":"Invisible.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/plot.sfnetwork.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Plot the geometries of a sfnetwork — plot.sfnetwork","text":"Arguments passed ... used plotting nodes plotting edges. Edges always plotted first. Arguments specified node_args edge_args specified ... well, result error.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/plot.sfnetwork.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Plot the geometries of a sfnetwork — plot.sfnetwork","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,1)) net = as_sfnetwork(roxel) plot(net) # When edges are spatially implicit. # By default straight lines will be drawn between connected nodes. par(mar = c(1,1,1,1), mfrow = c(1,2)) inet = st_drop_geometry(activate(net, \"edges\")) plot(inet) plot(inet, draw_lines = FALSE) # Changing plot settings. par(mar = c(1,1,1,1), mfrow = c(1,1)) plot(net, main = \"My network\", col = \"blue\", pch = 18, lwd = 1, cex = 2) # Changing plot settings for nodes and edges separately. plot(net, node_args = list(col = \"red\"), edge_args = list(col = \"blue\")) # Add grid and axis par(mar = c(2.5,2.5,1,1)) plot(net, graticule = TRUE, axes = TRUE) # Plot two networks on top of each other. par(mar = c(1,1,1,1), mfrow = c(1,1)) neta = as_sfnetwork(roxel[1:10, ]) netb = as_sfnetwork(roxel[50:60, ]) plot(neta) plot(netb, node_args = list(col = \"orange\"), add = TRUE) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/reexports.html","id":null,"dir":"Reference","previous_headings":"","what":"Objects exported from other packages — reexports","title":"Objects exported from other packages — reexports","text":"objects imported packages. Follow links see documentation. tidygraph %>%, activate, active, convert, crystallise, crystallize, morph, unmorph, with_graph","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/roxel.html","id":null,"dir":"Reference","previous_headings":"","what":"Road network of Münster Roxel — roxel","title":"Road network of Münster Roxel — roxel","text":"dataset containing road network (roads, bikelanes, footpaths, etc.) Roxel, neighborhood city Münster, Germany. data taken OpenStreetMap, querying key = 'highway'. See `data-raw/roxel.R` code creation.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/roxel.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Road network of Münster Roxel — roxel","text":"","code":"roxel"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/roxel.html","id":"format","dir":"Reference","previous_headings":"","what":"Format","title":"Road network of Münster Roxel — roxel","text":"object class sf LINESTRING geometries, containing 1215 features three columns: name name road, exists type type road, e.g. cycleway geometry geometry list column","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/roxel.html","id":"source","dir":"Reference","previous_headings":"","what":"Source","title":"Road network of Münster Roxel — roxel","text":"https://www.openstreetmap.org","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_attr.html","id":null,"dir":"Reference","previous_headings":"","what":"Query sf attributes from the active element of a sfnetwork — sf_attr","title":"Query sf attributes from the active element of a sfnetwork — sf_attr","text":"Query sf attributes active element sfnetwork","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_attr.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query sf attributes from the active element of a sfnetwork — sf_attr","text":"","code":"sf_attr(x, name, active = NULL)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_attr.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Query sf attributes from the active element of a sfnetwork — sf_attr","text":"x object class sfnetwork. name Name attribute query. Either 'sf_column' extract name geometry list column, 'agr' extract specification attribute-geometry relationships. active network element (.e. nodes edges) activate extracting. NULL, set current active element given network. Defaults NULL.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_attr.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query sf attributes from the active element of a sfnetwork — sf_attr","text":"value queried attribute.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_attr.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Query sf attributes from the active element of a sfnetwork — sf_attr","text":"","code":"net = as_sfnetwork(roxel) sf_attr(net, \"agr\", active = \"edges\") #> from to name type #> constant constant #> Levels: constant aggregate identity sf_attr(net, \"sf_column\", active = \"nodes\") #> [1] \"geometry\""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_methods.html","id":null,"dir":"Reference","previous_headings":"","what":"sf methods for sfnetworks — sf_methods","title":"sf methods for sfnetworks — sf_methods","text":"sf methods sfnetwork objects.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_methods.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"sf methods for sfnetworks — sf_methods","text":"","code":"# S3 method for class 'sfnetwork' st_as_sf(x, active = NULL, focused = TRUE, ...) # S3 method for class 'sfnetwork' st_geometry(obj, active = NULL, focused = TRUE, ...) # S3 method for class 'sfnetwork' st_geometry(x) <- value # S3 method for class 'sfnetwork' st_drop_geometry(x, ...) # S3 method for class 'sfnetwork' st_bbox(obj, active = NULL, ...) # S3 method for class 'sfnetwork' st_coordinates(x, active = NULL, ...) # S3 method for class 'sfnetwork' st_is(x, ...) # S3 method for class 'sfnetwork' st_is_valid(x, ...) # S3 method for class 'sfnetwork' st_as_s2(x, active = NULL, focused = TRUE, ...) # S3 method for class 'sfnetwork' st_crs(x, ...) # S3 method for class 'sfnetwork' st_crs(x) <- value # S3 method for class 'sfnetwork' st_precision(x) # S3 method for class 'sfnetwork' st_set_precision(x, precision) # S3 method for class 'sfnetwork' st_shift_longitude(x, ...) # S3 method for class 'sfnetwork' st_transform(x, ...) # S3 method for class 'sfnetwork' st_wrap_dateline(x, ...) # S3 method for class 'sfnetwork' st_normalize(x, ...) # S3 method for class 'sfnetwork' st_zm(x, ...) # S3 method for class 'sfnetwork' st_m_range(obj, active = NULL, ...) # S3 method for class 'sfnetwork' st_z_range(obj, active = NULL, ...) # S3 method for class 'sfnetwork' st_agr(x, active = NULL, ...) # S3 method for class 'sfnetwork' st_agr(x) <- value # S3 method for class 'sfnetwork' st_reverse(x, ...) # S3 method for class 'sfnetwork' st_segmentize(x, ...) # S3 method for class 'sfnetwork' st_simplify(x, ...) # S3 method for class 'sfnetwork' st_join(x, y, ..., ignore_multiple = TRUE) # S3 method for class 'morphed_sfnetwork' st_join(x, y, ...) # S3 method for class 'sfnetwork' st_filter(x, y, ...) # S3 method for class 'morphed_sfnetwork' st_filter(x, y, ...) # S3 method for class 'sfnetwork' st_crop(x, y, ...) # S3 method for class 'morphed_sfnetwork' st_crop(x, y, ...) # S3 method for class 'sfnetwork' st_difference(x, y, ...) # S3 method for class 'morphed_sfnetwork' st_difference(x, y, ...) # S3 method for class 'sfnetwork' st_intersection(x, y, ...) # S3 method for class 'morphed_sfnetwork' st_intersection(x, y, ...) # S3 method for class 'sfnetwork' st_intersects(x, y, ...) # S3 method for class 'sfnetwork' st_sample(x, ...) # S3 method for class 'sfnetwork' st_nearest_points(x, y, ...) # S3 method for class 'sfnetwork' st_area(x, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_methods.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"sf methods for sfnetworks — sf_methods","text":"x object class sfnetwork. active network element (.e. nodes edges) activate extracting. NULL, set current active element given network. Defaults NULL. focused features focus extracted? Defaults TRUE. See focus information focused networks. ... Arguments passed corresponding sf function. obj object class sfnetwork. value value assigned. See documentation corresponding sf function details. precision precision assigned. See st_precision details. y object class sf, directly convertible using st_as_sf. cases, can also object sfg bbox. Always look documentation corresponding sf function details. ignore_multiple performing spatial join nodes table, multiple matches single node, first one joined network. happen others? argument set TRUE, ignored. argument set FALSE, added isolated nodes returned network. Nodes equal locations can merged using spatial morpher to_spatial_unique. Defaults TRUE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_methods.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"sf methods for sfnetworks — sf_methods","text":"methods st_join, st_filter, st_intersection, st_difference st_crop, well methods setter functions geometric unary operations preserve class object applied , .e. either sfnetwork object morphed equivalent. dropping node geometries, object class tbl_graph returned. methods return type objects corresponding sf function. See sf documentation details.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_methods.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"sf methods for sfnetworks — sf_methods","text":"See sf documentation. following methods special behavior: st_geometry<-: geometry setter requires replacement geometries CRS network. Node replacements points, edge replacements linestrings. replacing node geometries, boundaries edge geometries replaced well preserve valid spatial network structure. replacing edge geometries, new edge boundaries match location specified incident node added new nodes network. st_transform: matter applied nodes edge table, method update coordinates tables. holds methods update way coordinates encoded without changing actual location, st_precision, st_normalize, st_zm, others. st_join: applied nodes table multiple matches exist node, first match joined. warning given case. ignore_multiple = FALSE, multiple mathces instead added isolated nodes returned network. st_intersection, st_difference st_crop: methods clip edge geometries applied edges table. preserve valid spatial network structure, clipped edge boundaries added new nodes network. st_reverse: reversing edge geometries directed network, indices columns swapped well. st_segmentize: segmentizing edge geometries, edge boundaries forced remain valid spatial network structure preserved. may lead slightly inaccurate results. Geometric unary operations supported sfnetwork objects change geometry type spatial location original features, since break valid spatial network structure. applying unsupported operations, first extract element interest (nodes edges) using st_as_sf.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_methods.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"sf methods for sfnetworks — sf_methods","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) net = as_sfnetwork(roxel) # Extract the active network element as sf object. st_as_sf(net) #> Simple feature collection with 987 features and 0 fields #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 987 × 1 #> geometry #> * #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> 7 (7.525977 51.95283) #> 8 (7.526581 51.95293) #> 9 (7.532301 51.95559) #> 10 (7.532142 51.95589) #> # ℹ 977 more rows # Extract any network element as sf object. st_as_sf(net, \"edges\") #> Simple feature collection with 1215 features and 4 fields #> Attribute-geometry relationships: constant (2), NA's (2) #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 1,215 × 5 #> from to name type geometry #> * #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… #> 5 9 10 Annette-von-Droste-Hülshoff-Stra… seco… (7.532301 51.95559, 7.53… #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… #> 7 13 14 Deermannskamp resi… (7.537675 51.95689, 7.53… #> 8 15 16 Lindenstraße resi… (7.539105 51.9504, 7.540… #> 9 17 18 NA NA (7.534875 51.95795, 7.53… #> 10 19 20 Annette-von-Droste-Hülshoff-Stra… seco… (7.532465 51.95424, 7.53… #> # ℹ 1,205 more rows # Get the geometry of the active network element. st_geometry(net) #> Geometry set for 987 features #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> First 5 geometries: #> POINT (7.538109 51.95286) #> POINT (7.537867 51.95282) #> POINT (7.537815 51.95867) #> POINT (7.537015 51.95848) #> POINT (7.533441 51.95578) # Get the geometry of any network element. st_geometry(net, \"edges\") #> Geometry set for 1215 features #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> First 5 geometries: #> LINESTRING (7.538109 51.95286, 7.537867 51.95282) #> LINESTRING (7.537815 51.95867, 7.537015 51.95848) #> LINESTRING (7.533441 51.95578, 7.533467 51.9557... #> LINESTRING (7.525977 51.95283, 7.526581 51.95293) #> LINESTRING (7.532301 51.95559, 7.532214 51.9557... # Replace the geometry of the nodes. # This will automatically update edge geometries to match the new nodes. newnet = net newnds = rep(st_centroid(st_combine(st_geometry(net))), n_nodes(net)) st_geometry(newnet) = newnds plot(net) plot(newnet) # Drop the geometries of the edges. # This returns an sfnetwork with spatially implicit edges. st_drop_geometry(activate(net, \"edges\")) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 4 (active) #> from to name type #> #> 1 1 2 Hagemanns Kämpken residential #> 2 3 4 Stiegkamp residential #> 3 5 6 Havixbecker Straße residential #> 4 7 8 Holzschuhmacherweg residential #> 5 9 10 Annette-von-Droste-Hülshoff-Straße secondary #> 6 11 12 NA footway #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows # Drop the geometries of the nodes. # This returns a tbl_graph. st_drop_geometry(net) #> # A tbl_graph: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components #> # #> # Node Data: 987 × 0 (active) #> # #> # Edge Data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows # Get the bounding box of the active network element. st_bbox(net) #> xmin ymin xmax ymax #> 7.522595 51.941511 7.546705 51.961194 # Get CRS of the network. st_crs(net) #> Coordinate Reference System: #> User input: EPSG:4326 #> wkt: #> GEOGCRS[\"WGS 84\", #> ENSEMBLE[\"World Geodetic System 1984 ensemble\", #> MEMBER[\"World Geodetic System 1984 (Transit)\"], #> MEMBER[\"World Geodetic System 1984 (G730)\"], #> MEMBER[\"World Geodetic System 1984 (G873)\"], #> MEMBER[\"World Geodetic System 1984 (G1150)\"], #> MEMBER[\"World Geodetic System 1984 (G1674)\"], #> MEMBER[\"World Geodetic System 1984 (G1762)\"], #> ELLIPSOID[\"WGS 84\",6378137,298.257223563, #> LENGTHUNIT[\"metre\",1]], #> ENSEMBLEACCURACY[2.0]], #> PRIMEM[\"Greenwich\",0, #> ANGLEUNIT[\"degree\",0.0174532925199433]], #> CS[ellipsoidal,2], #> AXIS[\"geodetic latitude (Lat)\",north, #> ORDER[1], #> ANGLEUNIT[\"degree\",0.0174532925199433]], #> AXIS[\"geodetic longitude (Lon)\",east, #> ORDER[2], #> ANGLEUNIT[\"degree\",0.0174532925199433]], #> USAGE[ #> SCOPE[\"Horizontal component of 3D system.\"], #> AREA[\"World.\"], #> BBOX[-90,-180,90,180]], #> ID[\"EPSG\",4326]] # Get agr factor of the active network element. st_agr(net) #> factor() #> Levels: constant aggregate identity # Get agr factor of any network element. st_agr(net, \"edges\") #> from to name type #> constant constant #> Levels: constant aggregate identity # Spatial join applied to the active network element. net = st_transform(net, 3035) codes = st_as_sf(st_make_grid(net, n = c(2, 2))) codes$post_code = as.character(seq(1000, 1000 + nrow(codes) * 10 - 10, 10)) joined = st_join(net, codes, join = st_intersects) joined #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150707 ymin: 3206375 xmax: 4152366 ymax: 3208564 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 987 × 2 (active) #> geometry post_code #> #> 1 (4151782 3207612) 1030 #> 2 (4151765 3207609) 1030 #> 3 (4151784 3208259) 1030 #> 4 (4151728 3208240) 1030 #> 5 (4151472 3207948) 1020 #> 6 (4151470 3207929) 1020 #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (4151782 3207612, 4151765 3207609) #> 2 3 4 Stiegkamp residential (4151784 3208259, 4151728 3208240) #> 3 5 6 Havixbecker Straße residential (4151472 3207948, 4151474 3207941,… #> # ℹ 1,212 more rows plot(net, col = \"grey\") plot(codes, col = NA, border = \"red\", lty = 4, lwd = 4, add = TRUE) text(st_coordinates(st_centroid(st_geometry(codes))), codes$post_code) plot(st_geometry(joined, \"edges\")) plot(st_as_sf(joined, \"nodes\"), pch = 20, add = TRUE) par(oldpar) # Spatial filter applied to the active network element. p1 = st_point(c(4151358, 3208045)) p2 = st_point(c(4151340, 3207520)) p3 = st_point(c(4151756, 3207506)) p4 = st_point(c(4151774, 3208031)) poly = st_multipoint(c(p1, p2, p3, p4)) |> st_cast('POLYGON') |> st_sfc(crs = 3035) |> st_as_sf() filtered = st_filter(net, poly, .pred = st_intersects) plot(net, col = \"grey\") plot(poly, border = \"red\", lty = 4, lwd = 4, add = TRUE) plot(filtered) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork.html","id":null,"dir":"Reference","previous_headings":"","what":"Create a sfnetwork — sfnetwork","title":"Create a sfnetwork — sfnetwork","text":"sfnetwork tidy data structure geospatial networks. extends tbl_graph data structure relational data domain geospatial networks, nodes edges embedded geographical space, offers smooth integration sf spatial data analysis.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Create a sfnetwork — sfnetwork","text":"","code":"sfnetwork( nodes, edges = NULL, directed = TRUE, node_key = \"name\", edges_as_lines = NULL, compute_length = FALSE, length_as_weight = deprecated(), force = FALSE, message = TRUE, ... )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Create a sfnetwork — sfnetwork","text":"nodes nodes network. object class sf, directly convertible using st_as_sf. features associated geometry type POINT. edges edges network. May object class sf, features associated geometry type LINESTRING. may also regular data.frame tbl_df object. case, nodes ends edge must referenced column, integers characters. Integers refer position node nodes table, characters refer name node stored column referred node_key argument. Setting edges NULL create network without edges. directed constructed network directed? Defaults TRUE. node_key name column nodes table character represented columns matched . NA, first column always chosen. setting effect given integers. Defaults 'name'. edges_as_lines edges spatially explicit, .e. LINESTRING geometries stored geometry list column? NULL, automatically defined, setting argument TRUE edges given object class sf, FALSE otherwise. Defaults NULL. compute_length geographic length edges stored column named length? Uses st_length compute length edge geometries edges spatially explicit, st_distance compute distance boundary nodes edges spatially implicit. already column named length, overwritten. Please note values column automatically recognized edge weights. needs specified explicitly calling function uses edge weights. Defaults FALSE. length_as_weight Deprecated, use compute_length instead. force network validity checks skipped? Defaults FALSE, meaning network validity checks executed constructing network. checks guarantee valid spatial network structure. nodes, means POINT geometries. case spatially explicit edges, also checked edges LINESTRING geometries, nodes edges CRS boundary points edges match corresponding node coordinates. checks important, also time consuming. already sure input data meet requirements, checks unnecessary can turned improve performance. message informational messages (messages neither warnings errors) printed constructing network? Defaults TRUE. ... Arguments passed st_as_sf, nodes need converted sf object construction.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Create a sfnetwork — sfnetwork","text":"object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Create a sfnetwork — sfnetwork","text":"","code":"library(sf, quietly = TRUE) p1 = st_point(c(7, 51)) p2 = st_point(c(7, 52)) p3 = st_point(c(8, 52)) nodes = st_as_sf(st_sfc(p1, p2, p3, crs = 4326)) e1 = st_cast(st_union(p1, p2), \"LINESTRING\") e2 = st_cast(st_union(p1, p3), \"LINESTRING\") e3 = st_cast(st_union(p3, p2), \"LINESTRING\") edges = st_as_sf(st_sfc(e1, e2, e3, crs = 4326)) edges$from = c(1, 1, 3) edges$to = c(2, 3, 2) # Default. sfnetwork(nodes, edges) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> → Checking edge geometry types ... #> ✔ All edges have geometry type LINESTRING #> → Checking coordinate reference system equality ... #> ✔ Nodes and edges have the same crs #> → Checking coordinate precision equality ... #> ✔ Nodes and edges have the same precision #> → Checking if geometries match ... #> ✔ Node locations match edge boundaries #> ✔ Spatial network structure is valid #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed acyclic simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 1 (active) #> x #> #> 1 (7 51) #> 2 (7 52) #> 3 (8 52) #> # #> # Edge data: 3 × 3 #> from to x #> #> 1 1 2 (7 51, 7 52) #> 2 1 3 (7 51, 8 52) #> 3 3 2 (8 52, 7 52) # Undirected network. sfnetwork(nodes, edges, directed = FALSE) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> → Checking edge geometry types ... #> ✔ All edges have geometry type LINESTRING #> → Checking coordinate reference system equality ... #> ✔ Nodes and edges have the same crs #> → Checking coordinate precision equality ... #> ✔ Nodes and edges have the same precision #> → Checking if geometries match ... #> ✔ Node locations match edge boundaries #> ✔ Spatial network structure is valid #> # A sfnetwork: 3 nodes and 3 edges #> # #> # An undirected simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 1 (active) #> x #> #> 1 (7 51) #> 2 (7 52) #> 3 (8 52) #> # #> # Edge data: 3 × 3 #> from to x #> #> 1 1 2 (7 51, 7 52) #> 2 1 3 (7 51, 8 52) #> 3 2 3 (8 52, 7 52) # Using character encoded from and to columns. nodes$name = c(\"city\", \"village\", \"farm\") edges$from = c(\"city\", \"city\", \"farm\") edges$to = c(\"village\", \"farm\", \"village\") sfnetwork(nodes, edges, node_key = \"name\") #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> → Checking edge geometry types ... #> ✔ All edges have geometry type LINESTRING #> → Checking coordinate reference system equality ... #> ✔ Nodes and edges have the same crs #> → Checking coordinate precision equality ... #> ✔ Nodes and edges have the same precision #> → Checking if geometries match ... #> ✔ Node locations match edge boundaries #> ✔ Spatial network structure is valid #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed acyclic simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 2 (active) #> x name #> #> 1 (7 51) city #> 2 (7 52) village #> 3 (8 52) farm #> # #> # Edge data: 3 × 3 #> from to x #> #> 1 1 2 (7 51, 7 52) #> 2 1 3 (7 51, 8 52) #> 3 3 2 (8 52, 7 52) # Spatially implicit edges. sfnetwork(nodes, edges, edges_as_lines = FALSE) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> ✔ Spatial network structure is valid #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed acyclic simple graph with 1 component and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 2 (active) #> x name #> #> 1 (7 51) city #> 2 (7 52) village #> 3 (8 52) farm #> # #> # Edge data: 3 × 2 #> from to #> #> 1 1 2 #> 2 1 3 #> 3 3 2 # Store edge lenghts in a column named 'length'. sfnetwork(nodes, edges, compute_length = TRUE) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> → Checking edge geometry types ... #> ✔ All edges have geometry type LINESTRING #> → Checking coordinate reference system equality ... #> ✔ Nodes and edges have the same crs #> → Checking coordinate precision equality ... #> ✔ Nodes and edges have the same precision #> → Checking if geometries match ... #> ✔ Node locations match edge boundaries #> ✔ Spatial network structure is valid #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed acyclic simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 2 (active) #> x name #> #> 1 (7 51) city #> 2 (7 52) village #> 3 (8 52) farm #> # #> # Edge data: 3 × 4 #> from to x length #> [m] #> 1 1 2 (7 51, 7 52) 111195. #> 2 1 3 (7 51, 8 52) 130977. #> 3 3 2 (8 52, 7 52) 68458."},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork_to_dodgr.html","id":null,"dir":"Reference","previous_headings":"","what":"Conversion between dodgr streetnets and sfnetworks — sfnetwork_to_dodgr","title":"Conversion between dodgr streetnets and sfnetworks — sfnetwork_to_dodgr","text":"dodgr package designed routing directed graphs, known fast computations cost matrices, shortest paths, . sfnetwork, dodgr can chosen routing backend.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork_to_dodgr.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Conversion between dodgr streetnets and sfnetworks — sfnetwork_to_dodgr","text":"","code":"dodgr_to_sfnetwork(x, edges_as_lines = TRUE) sfnetwork_to_dodgr(x, weights = edge_length(), time = FALSE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork_to_dodgr.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Conversion between dodgr streetnets and sfnetworks — sfnetwork_to_dodgr","text":"x conversion sfnetwork: object class dodgr_streetnet. conversion sfnetwork: object class sfnetwork. edges_as_lines created edges spatially explicit, .e. LINESTRING geometries stored geometry list column? Defaults TRUE. weights edge weights stored dodgr streetnet. Evaluated evaluate_weight_spec. default edge_length, computes geographic lengths edges. Dual-weights can provided dual_weights. time provided weights time values? TRUE, stored column named 'time' rather 'd'. Defaults FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork_to_dodgr.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Conversion between dodgr streetnets and sfnetworks — sfnetwork_to_dodgr","text":"conversion sfnetwork: object class sfnetwork. conversion sfnetwork: object class dodgr_streetnet.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork_to_dodgr.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Conversion between dodgr streetnets and sfnetworks — sfnetwork_to_dodgr","text":"dodgr package designed directed graphs. provided sfnetwork object undirected, made directed duplicating reversing edge.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetworks-package.html","id":null,"dir":"Reference","previous_headings":"","what":"sfnetworks: Tidy Geospatial Networks — sfnetworks-package","title":"sfnetworks: Tidy Geospatial Networks — sfnetworks-package","text":"Provides tidy approach spatial network analysis, form classes functions enable seamless interaction network analysis package 'tidygraph' spatial analysis package 'sf'.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetworks-package.html","id":"author","dir":"Reference","previous_headings":"","what":"Author","title":"sfnetworks: Tidy Geospatial Networks — sfnetworks-package","text":"Maintainer: Lucas van der Meer luukvandermeer@live.nl (ORCID) Authors: Lorena Abad lore.abad6@gmail.com (ORCID) Andrea Gilardi andrea.gilardi@unimib.(ORCID) Robin Lovelace r.lovelace@leeds.ac.uk (ORCID)","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/simplify_network.html","id":null,"dir":"Reference","previous_headings":"","what":"Simplify a spatial network — simplify_network","title":"Simplify a spatial network — simplify_network","text":"Construct simple version network. simple network defined network without loop edges multiple edges. loop edge edge starts ends node. Multiple edges different edges node pair.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/simplify_network.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Simplify a spatial network — simplify_network","text":"","code":"simplify_network( x, remove_multiple = TRUE, remove_loops = TRUE, attribute_summary = \"first\", store_original_ids = FALSE, store_original_data = FALSE )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/simplify_network.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Simplify a spatial network — simplify_network","text":"x object class sfnetwork. remove_multiple multiple edges merged one. Defaults TRUE. remove_loops loop edges removed. Defaults TRUE. attribute_summary attributes merged multiple edges summarized? several options, see igraph-attribute-combination details. store_original_ids group merged multiple edges, indices original edges stored attribute new edge, column named .tidygraph_edge_index? line design principles tidygraph. Defaults FALSE. store_original_data group merged multiple edges, data original edges stored attribute new edge, column named .orig_data? line design principles tidygraph. Defaults FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/simplify_network.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Simplify a spatial network — simplify_network","text":"simple network object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/simplify_network.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Simplify a spatial network — simplify_network","text":"merging groups multiple edges single edge, geometry first edge group preserved. order edges can influenced calling arrange simplifying.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/smooth_pseudo_nodes.html","id":null,"dir":"Reference","previous_headings":"","what":"Smooth pseudo nodes — smooth_pseudo_nodes","title":"Smooth pseudo nodes — smooth_pseudo_nodes","text":"Construct smoothed version network iteratively removing pseudo nodes, preserving connectivity network. case directed networks, pseudo nodes nodes one incoming one outgoing edge. undirected networks, pseudo nodes nodes two incident edges. Equality attribute values among two edges can defined additional requirement setting require_equal parameter. Connectivity network preserved concatenating incident edges removed pseudo node.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/smooth_pseudo_nodes.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Smooth pseudo nodes — smooth_pseudo_nodes","text":"","code":"smooth_pseudo_nodes( x, protect = NULL, require_equal = NULL, attribute_summary = \"ignore\", store_original_ids = FALSE, store_original_data = FALSE )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/smooth_pseudo_nodes.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Smooth pseudo nodes — smooth_pseudo_nodes","text":"x object class sfnetwork. protect integer vector edge indices specifying nodes protected removed. Defaults NULL, meaning none nodes protected. require_equal character vector edge column names specifying attributes incident edges pseudo node equal order pseudo node removed? Defaults NULL, meaning attribute equality considered pseudo node removal. attribute_summary attributes concatenated edges summarized? several options, see igraph-attribute-combination details. store_original_ids concatenated edge, indices original edges stored attribute new edge, column named .tidygraph_edge_index? line design principles tidygraph. Defaults FALSE. store_original_data concatenated edge, data original edges stored attribute new edge, column named .orig_data? line design principles tidygraph. Defaults FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/smooth_pseudo_nodes.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Smooth pseudo nodes — smooth_pseudo_nodes","text":"smoothed network object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_centrality.html","id":null,"dir":"Reference","previous_headings":"","what":"Compute spatial centrality measures — spatial_centrality","title":"Compute spatial centrality measures — spatial_centrality","text":"functions collection centrality measures specific spatial networks, form spatial extension centrality measures tidygraph.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_centrality.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Compute spatial centrality measures — spatial_centrality","text":"","code":"centrality_straightness(...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_centrality.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Compute spatial centrality measures — spatial_centrality","text":"... Additional arguments passed functions.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_centrality.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Compute spatial centrality measures — spatial_centrality","text":"numeric vector length number nodes network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_centrality.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Compute spatial centrality measures — spatial_centrality","text":"Just centrality functions tidygraph, functions meant called inside tidygraph verbs mutate filter, network currently worked known thus needed argument function. want use algorithm outside tidygraph framework can use with_graph set context temporarily algorithm evaluated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_centrality.html","id":"functions","dir":"Reference","previous_headings":"","what":"Functions","title":"Compute spatial centrality measures — spatial_centrality","text":"centrality_straightness(): straightness centrality node average ratio Euclidean distance network distance node nodes network. ... forwarded st_network_distance compute network distance matrix. Euclidean distances computed using st_distance.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_centrality.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Compute spatial centrality measures — spatial_centrality","text":"","code":"library(tidygraph, quietly = TRUE) net = as_sfnetwork(roxel, directed = FALSE) net |> activate(nodes) |> mutate(sc = centrality_straightness()) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # An undirected multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 2 (active) #> geometry sc #> #> 1 (7.538109 51.95286) 0.738 #> 2 (7.537867 51.95282) 0.737 #> 3 (7.537815 51.95867) 0.776 #> 4 (7.537015 51.95848) 0.767 #> 5 (7.533441 51.95578) 0.768 #> 6 (7.533415 51.95561) 0.768 #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_measures.html","id":null,"dir":"Reference","previous_headings":"","what":"Query spatial edge measures — spatial_edge_measures","title":"Query spatial edge measures — spatial_edge_measures","text":"functions collection edge measures spatial networks.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_measures.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query spatial edge measures — spatial_edge_measures","text":"","code":"edge_azimuth(degrees = FALSE) edge_circuity(Inf_as_NaN = FALSE) edge_length() edge_displacement() edge_segment_count()"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_measures.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Query spatial edge measures — spatial_edge_measures","text":"degrees angle returned degrees instead radians? Defaults FALSE. Inf_as_NaN circuity values loop edges stored NaN instead Inf? Defaults FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_measures.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query spatial edge measures — spatial_edge_measures","text":"numeric vector length number edges graph.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_measures.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Query spatial edge measures — spatial_edge_measures","text":"Just query functions tidygraph, spatial edge measures meant called inside tidygraph verbs mutate filter, network currently worked known thus needed argument function. want use algorithm outside tidygraph framework can use with_graph set context temporarily algorithm evaluated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_measures.html","id":"functions","dir":"Reference","previous_headings":"","what":"Functions","title":"Query spatial edge measures — spatial_edge_measures","text":"edge_azimuth(): angle radians straight line edge startpoint pointing north, straight line edge startpoint edge endpoint. Calculated st_geod_azimuth. Requires geographic CRS. edge_circuity(): ratio length edge linestring geometry versus straight-line distance boundary nodes, described Giacomin & Levinson, 2015. DOI: 10.1068/b130131p. edge_length(): length edge linestring geometry calculated st_length. edges spatially implicit, straight-line distance boundary nodes computed instead, using st_distance. edge_displacement(): straight-line distance two boundary nodes edge, calculated st_distance. edge_segment_count(): number segments contained linestring geometry edge. Segments parts linestring geometry contain interior points.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_measures.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Query spatial edge measures — spatial_edge_measures","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) net = as_sfnetwork(roxel) net |> activate(edges) |> mutate(azimuth = edge_azimuth()) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 6 (active) #> from to name type geometry azimuth #> [rad] #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… -1.83 #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… -1.93 #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… -3.05 #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… 1.32 #> 5 9 10 Annette-von-Droste-Hülsho… seco… (7.532301 51.95559, 7.53… -0.315 #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… 1.00 #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows net |> activate(edges) |> mutate(azimuth = edge_azimuth(degrees = TRUE)) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 6 (active) #> from to name type geometry azimuth #> [°] #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… -105. #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… -111. #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… -175. #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… 75.5 #> 5 9 10 Annette-von-Droste-Hülsho… seco… (7.532301 51.95559, 7.53… -18.0 #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… 57.5 #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows net |> activate(edges) |> mutate(circuity = edge_circuity()) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 6 (active) #> from to name type geometry circuity #> #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… 1 #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… 1 #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… 1.04 #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… 1 #> 5 9 10 Annette-von-Droste-Hülsh… seco… (7.532301 51.95559, 7.53… 1.00 #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… 1.00 #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows net |> activate(edges) |> mutate(length = edge_length()) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 6 (active) #> from to name type geometry length #> [m] #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… 17.2 #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… 58.6 #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… 20.3 #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… 42.7 #> 5 9 10 Annette-von-Droste-Hülshof… seco… (7.532301 51.95559, 7.53… 35.3 #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… 22.9 #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows net |> activate(edges) |> mutate(displacement = edge_displacement()) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 6 (active) #> from to name type geometry displacement #> [m] #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… 17.2 #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… 58.6 #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… 19.5 #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… 42.7 #> 5 9 10 Annette-von-Droste-H… seco… (7.532301 51.95559, 7.53… 35.3 #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… 22.9 #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows net |> activate(edges) |> mutate(n_segs = edge_segment_count()) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 6 (active) #> from to name type geometry n_segs #> #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… 1 #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… 1 #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… 3 #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… 1 #> 5 9 10 Annette-von-Droste-Hülshof… seco… (7.532301 51.95559, 7.53… 2 #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… 2 #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_predicates.html","id":null,"dir":"Reference","previous_headings":"","what":"Query edges with spatial predicates — spatial_edge_predicates","title":"Query edges with spatial predicates — spatial_edge_predicates","text":"functions allow interpret spatial relations edges geospatial features directly inside filter mutate calls. functions return logical vector length number edges network. Element vector TRUE whenever chosen spatial predicate applies spatial relation -th edge features y.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_predicates.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query edges with spatial predicates — spatial_edge_predicates","text":"","code":"edge_intersects(y, ...) edge_is_disjoint(y, ...) edge_touches(y, ...) edge_crosses(y, ...) edge_is_within(y, ...) edge_contains(y, ...) edge_contains_properly(y, ...) edge_overlaps(y, ...) edge_equals(y, ...) edge_covers(y, ...) edge_is_covered_by(y, ...) edge_is_within_distance(y, ...) edge_is_nearest(y)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_predicates.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Query edges with spatial predicates — spatial_edge_predicates","text":"y geospatial features test edges , either object class sf sfc. ... Arguments passed corresponding spatial predicate function sf. See geos_binary_pred. argument sparse set.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_predicates.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query edges with spatial predicates — spatial_edge_predicates","text":"logical vector length number edges network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_predicates.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Query edges with spatial predicates — spatial_edge_predicates","text":"See geos_binary_pred details spatial predicate. function edge_is_nearest instead wraps around st_nearest_feature returns TRUE element -th edge nearest edge features y. Just query functions tidygraph, functions meant called inside tidygraph verbs mutate filter, network currently worked known thus needed argument function. want use algorithm outside tidygraph framework can use with_graph set context temporarily algorithm evaluated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_predicates.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Query edges with spatial predicates — spatial_edge_predicates","text":"Note edge_is_within_distance wrapper around st_is_within_distance predicate sf. Hence, based '--crow-flies' distance, distances network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_predicates.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Query edges with spatial predicates — spatial_edge_predicates","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) # Create a network. net = as_sfnetwork(roxel) |> st_transform(3035) # Create a geometry to test against. p1 = st_point(c(4151358, 3208045)) p2 = st_point(c(4151340, 3207520)) p3 = st_point(c(4151756, 3207506)) p4 = st_point(c(4151774, 3208031)) poly = st_multipoint(c(p1, p2, p3, p4)) |> st_cast('POLYGON') |> st_sfc(crs = 3035) # Use predicate query function in a filter call. intersects = net |> activate(edges) |> filter(edge_intersects(poly)) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) plot(st_geometry(net, \"edges\")) plot(st_geometry(intersects, \"edges\"), col = \"red\", lwd = 2, add = TRUE) par(oldpar) # Use predicate query function in a mutate call. net |> activate(edges) |> mutate(disjoint = edge_is_disjoint(poly)) |> select(disjoint) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150707 ymin: 3206375 xmax: 4152366 ymax: 3208564 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 1,215 × 4 (active) #> from to disjoint geometry #> #> 1 1 2 TRUE (4151782 3207612, 4151765 3207609) #> 2 3 4 TRUE (4151784 3208259, 4151728 3208240) #> 3 5 6 FALSE (4151472 3207948, 4151474 3207941, 4151473 3207934, 4151… #> 4 7 8 TRUE (4150948 3207637, 4150990 3207647) #> 5 9 10 FALSE (4151393 3207929, 4151388 3207948, 4151383 3207963) #> 6 11 12 TRUE (4152127 3207036, 4152139 3207043, 4152146 3207047) #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (4151782 3207612) #> 2 (4151765 3207609) #> 3 (4151784 3208259) #> # ℹ 984 more rows # Use predicate query function directly. intersects = with_graph(net, edge_intersects(poly)) head(intersects) #> [1] FALSE FALSE TRUE FALSE TRUE FALSE"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_morphers.html","id":null,"dir":"Reference","previous_headings":"","what":"Morph spatial networks into a different structure — spatial_morphers","title":"Morph spatial networks into a different structure — spatial_morphers","text":"Spatial morphers form spatial add-ons set morphers provided tidygraph. functions change existing structure network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_morphers.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Morph spatial networks into a different structure — spatial_morphers","text":"","code":"to_spatial_contracted( x, ..., simplify = TRUE, compute_centroids = TRUE, attribute_summary = \"ignore\", summarise_attributes = deprecated(), store_original_data = FALSE ) to_spatial_directed(x) to_spatial_explicit(x, ...) to_spatial_implicit(x) to_spatial_mixed(x, directed) to_spatial_neighborhood(x, node, threshold, weights = edge_length(), ...) to_spatial_reversed(x, protect = NULL) to_spatial_shortest_paths(x, ...) to_spatial_simple( x, remove_multiple = TRUE, remove_loops = TRUE, attribute_summary = \"first\", summarise_attributes = deprecated(), store_original_data = FALSE ) to_spatial_smooth( x, protect = NULL, require_equal = NULL, attribute_summary = \"ignore\", summarise_attributes = deprecated(), store_original_data = FALSE ) to_spatial_subdivision(x, protect = NULL, all = FALSE, merge = TRUE) to_spatial_subset(x, ..., subset_by = NULL) to_spatial_transformed(x, ...) to_spatial_unique(x, attribute_summary = \"ignore\", store_original_data = FALSE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_morphers.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Morph spatial networks into a different structure — spatial_morphers","text":"x object class sfnetwork. ... Arguments passed functions. See description morpher details. simplify network simplified contraction? Defaults TRUE. means multiple edges loop edges removed. Multiple edges introduced contraction several connections groups nodes. Loop edges introduced contraction connections within group. Note however setting TRUE also removes multiple edges loop edges already existed contraction. compute_centroids new geometry contracted group nodes centroid group members? Defaults TRUE. set FALSE, geometry first node group used instead, requires considerably less computing time. attribute_summary Whenever groups nodes edges merged single feature morphing, attributes summarized? several options, see igraph-attribute-combination details. summarise_attributes Deprecated, use attribute_summary instead. store_original_data Whenever groups nodes edges merged single feature morphing, data original features stored attribute new feature, column named .orig_data. line design principles tidygraph. Defaults FALSE. directed edges directed? Evaluated evaluate_edge_query. node node neighborhood calculated. Evaluated evaluate_node_query. multiple nodes given, first one used. threshold threshold cost used. nodes reachable within threshold cost reference node included neighborhood. numeric value units given edge weights. Alternatively, units can specified explicitly providing units object. Multiple threshold values may given, result mutliple neigborhoods returned. weights edge weights used travel cost computation. Evaluated evaluate_weight_spec. default edge_length, computes geographic lengths edges. protect Nodes edges protected changed structure. Evaluated evaluate_node_query case nodes evaluate_edge_query case edges. Defaults NULL, meaning features protected. remove_multiple multiple edges merged one. Defaults TRUE. remove_loops loop edges removed. Defaults TRUE. require_equal attributes incident edges equal order pseudo node removed? Evaluated dplyr_tidy_select argument. Defaults NULL, meaning attribute equality considered pseudo node removal. edges subdivided interior points? set FALSE, edges subdivided interior points share location interior boundary point (node) edges table. Defaults FALSE. default sfnetworks rounds coordinates 12 decimal places determine spatial equality. can influence behavior explicitly setting precision network using st_set_precision. merge multiple subdivision points location merged single node, subdivision points location existing node merged node? Defaults TRUE. set FALSE, subdivision point added separately new node network. default sfnetworks rounds coordinates 12 decimal places determine spatial equality. can influence behavior explicitly setting precision network using st_set_precision. subset_by Whether create subgraphs based nodes edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_morphers.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Morph spatial networks into a different structure — spatial_morphers","text":"Either morphed_sfnetwork, list one sfnetwork objects, morphed_tbl_graph, list one tbl_graph objects. See description morpher details.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_morphers.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Morph spatial networks into a different structure — spatial_morphers","text":"Morphers meant called directly. Instead, called inside morph verb change network structure temporarily. Depending chosen morpher, results list one network objects. Single elements list can extracted directly new network calling morpher inside convert verb instead, make changes lasting rather temporary. also possible create morphers. See documentation morph requirements custom morphers.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_morphers.html","id":"functions","dir":"Reference","previous_headings":"","what":"Functions","title":"Morph spatial networks into a different structure — spatial_morphers","text":"to_spatial_contracted(): Combine groups nodes single node per group. ... forwarded group_by create groups. centroid group used default geometry contracted node. edges spatially explicit, edge geometries updated accordingly valid spatial network structure preserved. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_directed(): Make network directed direction given linestring geometries edges. Differs to_directed, makes network directed based node indices given columns. undirected networks indices may correspond endpoints linestring geometries. Returns morphed_sfnetwork containing single element class sfnetwork. morpher requires edges spatially explicit. , use to_directed. to_spatial_explicit(): Create linestring geometries source target nodes edges. edges data can directly converted object class sf using st_as_sf, extra arguments can provided ... forwarded st_as_sf internally. Otherwise, straight lines drawn source target node edge. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_implicit(): Drop edge geometries network. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_mixed(): Construct mixed network edges directed, undirected. practice implemented directed network edges meant undirected duplicated reversed. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_neighborhood(): Limit network spatial neighborhood specific node. ... forwarded st_network_cost compute travel cost specified node nodes network. Returns morphed_sfnetwork may contain multiple elements class sfnetwork, depending number given thresholds. unmorphing first instance node edge data used, node /edge can present multiple neighborhoods. to_spatial_reversed(): Reverse direction edges. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_shortest_paths(): Limit network nodes edges part shortest path two nodes. ... evaluated manner st_network_paths. Returns morphed_sfnetwork may contain multiple elements class sfnetwork, depending number requested paths. unmorphing first instance node edge data used, node /edge can present multiple paths. to_spatial_simple(): Construct simple version network. simple network defined network without loop edges multiple edges. loop edge edge starts ends node. Multiple edges different edges node pair. merging single edge, geometry first edge preserved. order edges can influenced calling arrange simplifying. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_smooth(): Construct smoothed version network iteratively removing pseudo nodes, preserving connectivity network. case directed networks, pseudo nodes nodes one incoming one outgoing edge. undirected networks, pseudo nodes nodes two incident edges. Equality attribute values among two edges can defined additional requirement setting require_equal parameter. Connectivity network preserved concatenating incident edges removed pseudo node. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_subdivision(): Construct subdivision network subdividing edges interior points. Subdividing means new node added edge, edge split two location. Interior points points shape linestring geometry feature endpoints . Returns morphed_sfnetwork containing single element class sfnetwork. morpher requires edges spatially explicit. to_spatial_subset(): Subset network applying spatial filter, .e. filter geometry column based spatial predicate. ... evaluated manner st_filter. Returns morphed_sfnetwork containing single element class sfnetwork. filters attribute column, use to_subgraph. to_spatial_transformed(): Transform geospatial coordinates network different coordinate reference system. ... evaluated manner st_transform. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_unique(): Merge nodes equal geometries single node. Returns morphed_sfnetwork containing single element class sfnetwork. default sfnetworks rounds coordinates 12 decimal places determine spatial equality. can influence behavior explicitly setting precision network using st_set_precision.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_morphers.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Morph spatial networks into a different structure — spatial_morphers","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) net = as_sfnetwork(roxel, directed = FALSE) |> st_transform(3035) # Temporary changes with morph and unmorph. net |> activate(edges) |> morph(to_spatial_shortest_paths, from = 1, to = 10) |> mutate(in_paths = TRUE) |> unmorph() #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # An undirected multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150707 ymin: 3206375 xmax: 4152366 ymax: 3208564 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 1,215 × 6 (active) #> from to name type geometry in_paths #> #> 1 1 2 Hagemanns Kämpken resi… (4151782 3207612, 415176… TRUE #> 2 3 4 Stiegkamp resi… (4151784 3208259, 415172… NA #> 3 5 6 Havixbecker Straße resi… (4151472 3207948, 415147… NA #> 4 7 8 Holzschuhmacherweg resi… (4150948 3207637, 415099… NA #> 5 9 10 Annette-von-Droste-Hülsh… seco… (4151393 3207929, 415138… NA #> 6 11 12 NA foot… (4152127 3207036, 415213… NA #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (4151782 3207612) #> 2 (4151765 3207609) #> 3 (4151784 3208259) #> # ℹ 984 more rows # Lasting changes with convert. net |> activate(edges) |> convert(to_spatial_shortest_paths, from = 1, to = 10) #> # A sfnetwork: 22 nodes and 21 edges #> # #> # An unrooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4151383 ymin: 3207582 xmax: 4151782 ymax: 3207963 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 21 × 6 (active) #> from to name type geometry .tidygraph_edge_index #> #> 1 1 2 Hagemanns K… resi… (4151782 3207612, 415176… 1 #> 2 2 3 Hagemanns K… resi… (4151765 3207609, 415174… 55 #> 3 3 4 Hagemanns K… resi… (4151747 3207604, 415172… 106 #> 4 4 5 Hagemanns K… resi… (4151710 3207595, 415166… 112 #> 5 5 6 Dorffeldstr… resi… (4151661 3207612, 415166… 780 #> 6 6 7 Dorffeldstr… resi… (4151650 3207655, 415165… 402 #> # ℹ 15 more rows #> # #> # Node data: 22 × 2 #> geometry .tidygraph_node_index #> #> 1 (4151782 3207612) 1 #> 2 (4151765 3207609) 2 #> 3 (4151747 3207604) 106 #> # ℹ 19 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_predicates.html","id":null,"dir":"Reference","previous_headings":"","what":"Query nodes with spatial predicates — spatial_node_predicates","title":"Query nodes with spatial predicates — spatial_node_predicates","text":"functions allow interpret spatial relations nodes geospatial features directly inside filter mutate calls. functions return logical vector length number nodes network. Element vector TRUE whenever chosen spatial predicate applies spatial relation -th node features y.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_predicates.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query nodes with spatial predicates — spatial_node_predicates","text":"","code":"node_intersects(y, ...) node_is_disjoint(y, ...) node_touches(y, ...) node_is_within(y, ...) node_equals(y, ...) node_is_covered_by(y, ...) node_is_within_distance(y, ...) node_is_nearest(y)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_predicates.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Query nodes with spatial predicates — spatial_node_predicates","text":"y geospatial features test nodes , either object class sf sfc. ... Arguments passed corresponding spatial predicate function sf. See geos_binary_pred. argument sparse set.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_predicates.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query nodes with spatial predicates — spatial_node_predicates","text":"logical vector length number nodes network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_predicates.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Query nodes with spatial predicates — spatial_node_predicates","text":"See geos_binary_pred details spatial predicate. function node_is_nearest instead wraps around st_nearest_feature returns TRUE element -th node nearest node features y. Just query functions tidygraph, functions meant called inside tidygraph verbs mutate filter, network currently worked known thus needed argument function. want use algorithm outside tidygraph framework can use with_graph set context temporarily algorithm evaluated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_predicates.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Query nodes with spatial predicates — spatial_node_predicates","text":"Note node_is_within_distance wrapper around st_is_within_distance predicate sf. Hence, based '--crow-flies' distance, distances network. distances network, use node_distance_to edge lengths weights argument.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_predicates.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Query nodes with spatial predicates — spatial_node_predicates","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) # Create a network. net = as_sfnetwork(roxel) |> st_transform(3035) # Create a geometry to test against. p1 = st_point(c(4151358, 3208045)) p2 = st_point(c(4151340, 3207520)) p3 = st_point(c(4151756, 3207506)) p4 = st_point(c(4151774, 3208031)) poly = st_multipoint(c(p1, p2, p3, p4)) |> st_cast('POLYGON') |> st_sfc(crs = 3035) # Use predicate query function in a filter call. within = net |> activate(nodes) |> filter(node_is_within(poly)) disjoint = net |> activate(nodes) |> filter(node_is_disjoint(poly)) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) plot(net) plot(within, col = \"red\", add = TRUE) plot(disjoint, col = \"blue\", add = TRUE) par(oldpar) # Use predicate query function in a mutate call. net |> activate(nodes) |> mutate(within = node_is_within(poly)) |> select(within) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150707 ymin: 3206375 xmax: 4152366 ymax: 3208564 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 987 × 2 (active) #> within geometry #> #> 1 FALSE (4151782 3207612) #> 2 FALSE (4151765 3207609) #> 3 FALSE (4151784 3208259) #> 4 FALSE (4151728 3208240) #> 5 TRUE (4151472 3207948) #> 6 TRUE (4151470 3207929) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (4151782 3207612, 4151765 3207609) #> 2 3 4 Stiegkamp residential (4151784 3208259, 4151728 3208240) #> 3 5 6 Havixbecker Straße residential (4151472 3207948, 4151474 3207941,… #> # ℹ 1,212 more rows # Use predicate query function directly. within = with_graph(net, node_is_within(poly)) head(within) #> [1] FALSE FALSE FALSE FALSE TRUE TRUE"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_types.html","id":null,"dir":"Reference","previous_headings":"","what":"Query spatial node types — spatial_node_types","title":"Query spatial node types — spatial_node_types","text":"functions collection node type queries commonly used spatial network analysis, form spatial extension node type queries tidygraph.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_types.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query spatial node types — spatial_node_types","text":"","code":"node_is_pseudo() node_is_dangling()"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_types.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query spatial node types — spatial_node_types","text":"logical vector length number nodes network, indicating node type question.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_types.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Query spatial node types — spatial_node_types","text":"Just query functions tidygraph, functions meant called inside tidygraph verbs mutate filter, network currently worked known thus needed argument function. want use algorithm outside tidygraph framework can use with_graph set context temporarily algorithm evaluated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_types.html","id":"functions","dir":"Reference","previous_headings":"","what":"Functions","title":"Query spatial node types — spatial_node_types","text":"node_is_pseudo(): Pseudo nodes directed networks nodes one incoming one outgoing edge. undirected networks pseudo nodes nodes two incident edges, .e. nodes degree 2. node_is_dangling(): Dangling nodes nodes one incident edge, .e. nodes degree 1.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_types.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Query spatial node types — spatial_node_types","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) # Create a network. net = as_sfnetwork(mozart, \"mst\", directed = FALSE) # Use query function in a filter call. pseudos = net |> activate(nodes) |> filter(node_is_pseudo()) danglers = net |> activate(nodes) |> filter(node_is_dangling()) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) plot(net, main = \"Pseudo nodes\") plot(st_geometry(pseudos), pch = 20, cex = 1.2, col = \"orange\", add = TRUE) plot(net, main = \"Dangling nodes\") plot(st_geometry(danglers), pch = 20, cex = 1.2, col = \"orange\", add = TRUE) par(oldpar) # Use query function in a mutate call. net |> activate(nodes) |> mutate(pseudo = node_is_pseudo(), dangling = node_is_dangling()) #> # A sfnetwork: 17 nodes and 16 edges #> # #> # An unrooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 6 (active) #> name type website geometry pseudo dangling #> #> 1 Mozartkino cinema https:… (4549504 2747309) FALSE TRUE #> 2 Haus für Mozart theat… NA (4549003 2747376) FALSE TRUE #> 3 Mozartsteg/Rudolfskai bus_s… NA (4549589 2747507) TRUE FALSE #> 4 Mozart Denkmal artwo… NA (4549387 2747514) TRUE FALSE #> 5 Mozartsteg/Rudolfskai bus_s… NA (4549491 2747551) FALSE FALSE #> 6 Mozartsteg bridge NA (4549473 2747624) TRUE FALSE #> # ℹ 11 more rows #> # #> # Edge data: 16 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 2 7 (4549003 2747376, 4549064 2747619) #> 3 3 5 (4549589 2747507, 4549491 2747551) #> # ℹ 13 more rows # Use query function directly. danglers = with_graph(net, node_is_dangling()) head(danglers) #> Mozartkino Haus für Mozart Mozartsteg/Rudolfskai #> TRUE TRUE FALSE #> Mozart Denkmal Mozartsteg/Rudolfskai Mozartsteg #> FALSE FALSE FALSE"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_duplicated.html","id":null,"dir":"Reference","previous_headings":"","what":"Determine duplicated geometries — st_duplicated","title":"Determine duplicated geometries — st_duplicated","text":"Determine duplicated geometries","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_duplicated.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Determine duplicated geometries — st_duplicated","text":"","code":"st_duplicated(x)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_duplicated.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Determine duplicated geometries — st_duplicated","text":"x object class sf sfc.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_duplicated.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Determine duplicated geometries — st_duplicated","text":"logical vector specifying feature x geometry equal previous feature x.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_duplicated.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Determine duplicated geometries — st_duplicated","text":"","code":"library(sf, quietly = TRUE) p1 = st_sfc(st_point(c(1, 1))) p2 = st_sfc(st_point(c(0, 0))) p3 = st_sfc(st_point(c(1, 0))) st_duplicated(c(p1, p2, p2, p3, p1)) #> [1] FALSE FALSE TRUE FALSE TRUE"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_match.html","id":null,"dir":"Reference","previous_headings":"","what":"Geometry matching — st_match","title":"Geometry matching — st_match","text":"Geometry matching","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_match.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Geometry matching — st_match","text":"","code":"st_match(x)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_match.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Geometry matching — st_match","text":"x object class sf sfc.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_match.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Geometry matching — st_match","text":"numeric vector giving feature x position first feature x equal geometry.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_match.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Geometry matching — st_match","text":"","code":"library(sf, quietly = TRUE) p1 = st_sfc(st_point(c(1, 1))) p2 = st_sfc(st_point(c(0, 0))) p3 = st_sfc(st_point(c(1, 0))) st_match(c(p1, p2, p2, p3, p1)) #> [1] 1 2 2 3 1"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_bbox.html","id":null,"dir":"Reference","previous_headings":"","what":"Compute the bounding box of a spatial network — st_network_bbox","title":"Compute the bounding box of a spatial network — st_network_bbox","text":"spatial network specific bounding box creator, returning combined bounding box nodes edges network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_bbox.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Compute the bounding box of a spatial network — st_network_bbox","text":"","code":"st_network_bbox(x, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_bbox.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Compute the bounding box of a spatial network — st_network_bbox","text":"x object class sfnetwork. ... Arguments passed st_bbox.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_bbox.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Compute the bounding box of a spatial network — st_network_bbox","text":"bounding box network object class bbox.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_bbox.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Compute the bounding box of a spatial network — st_network_bbox","text":"See st_bbox details.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_bbox.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Compute the bounding box of a spatial network — st_network_bbox","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) # Create a network. n1 = st_point(c(8, 51)) n2 = st_point(c(7, 51.5)) n3 = st_point(c(8, 52)) n4 = st_point(c(9, 51)) e1 = st_sfc(st_linestring(c(n1, n2, n3))) nodes = st_as_sf(c(st_sfc(n1), st_sfc(n3), st_sfc(n4))) edges = st_as_sf(e1) edges$from = 1 edges$to = 2 net = sfnetwork(nodes, edges) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> → Checking edge geometry types ... #> ✔ All edges have geometry type LINESTRING #> → Checking coordinate reference system equality ... #> ✔ Nodes and edges have the same crs #> → Checking coordinate precision equality ... #> ✔ Nodes and edges have the same precision #> → Checking if geometries match ... #> ✔ Node locations match edge boundaries #> ✔ Spatial network structure is valid # Create bounding boxes for nodes, edges and the whole network. node_bbox = st_bbox(activate(net, \"nodes\")) node_bbox #> xmin ymin xmax ymax #> 8 51 9 52 edge_bbox = st_bbox(activate(net, \"edges\")) edge_bbox #> xmin ymin xmax ymax #> 7 51 8 52 net_bbox = st_network_bbox(net) net_bbox #> xmin ymin xmax ymax #> 7 51 9 52 # Plot. plot(net, lwd = 2, cex = 4, main = \"Element bounding boxes\") plot(st_as_sfc(node_bbox), border = \"orange\", lty = 2, lwd = 4, add = TRUE) plot(st_as_sfc(edge_bbox), border = \"skyblue\", lty = 2, lwd = 4, add = TRUE) plot(net, lwd = 2, cex = 4, main = \"Network bounding box\") plot(st_as_sfc(net_bbox), border = \"orange\", lty = 2, lwd = 4, add = TRUE) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_blend.html","id":null,"dir":"Reference","previous_headings":"","what":"Blend spatial points into a spatial network — st_network_blend","title":"Blend spatial points into a spatial network — st_network_blend","text":"Blending point network combined process first projecting point onto nearest point nearest edge network, subdividing edge location projected point, finally adding projected point node network. location projected point equal existing node network, attributes point joined node, instead adding new node.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_blend.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Blend spatial points into a spatial network — st_network_blend","text":"","code":"st_network_blend(x, y, tolerance = Inf, ignore_duplicates = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_blend.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Blend spatial points into a spatial network — st_network_blend","text":"x object class sfnetwork. y spatial features blended, either object class sf sfc, POINT geometries. tolerance tolerance distance used. features least close network tolerance distance blended. non-negative number preferably given object class units. Otherwise, assumed unit meters. set Inf features blended. Defaults Inf. ignore_duplicates multiple points y projected location, first one blended network. happen others? argument set TRUE, ignored. argument set FALSE, added isolated nodes returned network. Nodes equal locations can merged using spatial morpher to_spatial_unique. Defaults TRUE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_blend.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Blend spatial points into a spatial network — st_network_blend","text":"blended network object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_blend.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Blend spatial points into a spatial network — st_network_blend","text":"projected location given point intersects one edge, blended first edges. Edges connected blending locations. Use spatial morpher to_spatial_subdivision . determine projected point equal existing node, determine multiple projected points equal , sfnetworks default rounds coordinates 12 decimal places. can influence behavior explicitly setting precision network using st_set_precision.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_blend.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Blend spatial points into a spatial network — st_network_blend","text":"Due internal rounding rational numbers, may occur intersection point line point evaluated actually intersecting line designated algorithm. Instead, intersection point lies tiny-bit away edge. Therefore, recommended set tolerance small number (example 1e-5) even want blend points intersect edge.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_blend.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Blend spatial points into a spatial network — st_network_blend","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) # Create a spatial network. n1 = st_point(c(0, 0)) n2 = st_point(c(1, 0)) n3 = st_point(c(2, 0)) e1 = st_sfc(st_linestring(c(n1, n2)), crs = 3857) e2 = st_sfc(st_linestring(c(n2, n3)), crs = 3857) net = as_sfnetwork(c(e1, e2)) # Create spatial points to blend in. p1 = st_sfc(st_point(c(0.5, 0.1))) p2 = st_sfc(st_point(c(0.5, -0.2))) p3 = st_sfc(st_point(c(1, 0.2))) p4 = st_sfc(st_point(c(1.75, 0.2))) p5 = st_sfc(st_point(c(1.25, 0.1))) pts = st_sf(foo = letters[1:5], geometry = c(p1, p2, p3, p4, p5), crs = 3857) # Blend all points into the network. b1 = st_network_blend(net, pts) #> Warning: `st_network_blend()` did not blend in all requested features. #> ! Some projected features have duplicated locations, of which all but the first #> one are ignored. #> ℹ If you want to add duplicated projection locations as isolated nodes instead, #> set `ignore_duplicates` to `FALSE`. b1 #> # A sfnetwork: 6 nodes and 5 edges #> # #> # A rooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 2 ymax: 0 #> # Projected CRS: WGS 84 / Pseudo-Mercator #> # #> # Node data: 6 × 2 (active) #> x foo #> #> 1 (0 0) NA #> 2 (1 0) c #> 3 (2 0) NA #> 4 (0.5 0) a #> 5 (1.25 0) e #> 6 (1.75 0) d #> # #> # Edge data: 5 × 3 #> from to x #> #> 1 1 4 (0 0, 0.5 0) #> 2 4 2 (0.5 0, 1 0) #> 3 2 5 (1 0, 1.25 0) #> # ℹ 2 more rows plot(net) plot(st_geometry(pts), pch = 20, col = \"orange\", add = TRUE) plot(b1) plot(st_geometry(pts), pch = 20, col = \"orange\", add = TRUE) # Blend points within a tolerance distance. tol = units::set_units(0.1, \"m\") b2 = st_network_blend(net, pts, tolerance = tol) b2 #> # A sfnetwork: 5 nodes and 4 edges #> # #> # A rooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 2 ymax: 0 #> # Projected CRS: WGS 84 / Pseudo-Mercator #> # #> # Node data: 5 × 2 (active) #> x foo #> #> 1 (0 0) NA #> 2 (1 0) NA #> 3 (2 0) NA #> 4 (0.5 0) a #> 5 (1.25 0) e #> # #> # Edge data: 4 × 3 #> from to x #> #> 1 1 4 (0 0, 0.5 0) #> 2 4 2 (0.5 0, 1 0) #> 3 2 5 (1 0, 1.25 0) #> # ℹ 1 more row plot(net) plot(st_geometry(pts), pch = 20, col = \"orange\", add = TRUE) plot(b2) plot(st_geometry(pts), pch = 20, col = \"orange\", add = TRUE) # Add points with duplicated projected location as isolated nodes. b3 = st_network_blend(net, pts, ignore_duplicates = FALSE) #> Warning: `st_network_blend()` created isolated nodes. #> ! Some projected features have duplicated locations, of which all but the first #> one are added as isolated nodes to the network. #> ℹ If you want to ignore duplicated projection locations instead, set #> `ignore_duplicates` to `TRUE`. b3 #> # A sfnetwork: 7 nodes and 5 edges #> # #> # A rooted forest with 2 trees and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 2 ymax: 0 #> # Projected CRS: WGS 84 / Pseudo-Mercator #> # #> # Node data: 7 × 2 (active) #> x foo #> #> 1 (0 0) NA #> 2 (1 0) c #> 3 (2 0) NA #> 4 (0.5 0) a #> 5 (1.25 0) e #> 6 (1.75 0) d #> # ℹ 1 more row #> # #> # Edge data: 5 × 3 #> from to x #> #> 1 1 4 (0 0, 0.5 0) #> 2 4 2 (0.5 0, 1 0) #> 3 2 5 (1 0, 1.25 0) #> # ℹ 2 more rows par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_cost.html","id":null,"dir":"Reference","previous_headings":"","what":"Compute a cost matrix of a spatial network — st_network_cost","title":"Compute a cost matrix of a spatial network — st_network_cost","text":"Compute total travel costs shortest paths nodes spatial network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_cost.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Compute a cost matrix of a spatial network — st_network_cost","text":"","code":"st_network_cost( x, from = node_ids(x), to = node_ids(x), weights = edge_length(), direction = \"out\", Inf_as_NaN = FALSE, router = getOption(\"sfn_default_router\", \"igraph\"), use_names = FALSE, ... ) st_network_distance( x, from = node_ids(x), to = node_ids(x), direction = \"out\", Inf_as_NaN = FALSE, router = getOption(\"sfn_default_router\", \"igraph\"), use_names = FALSE, ... )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_cost.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Compute a cost matrix of a spatial network — st_network_cost","text":"x object class sfnetwork. nodes paths start. Evaluated evaluate_node_query. default, nodes network included. nodes paths end. Evaluated evaluate_node_query. default, nodes network included. weights edge weights used shortest path calculation. Evaluated evaluate_weight_spec. default edge_length, computes geographic lengths edges. direction direction travel. Defaults '', meaning direction given network followed costs computed points given argument . May set '', meaning opposite direction followed costs computed towards points given argument . May also set '', meaning network considered undirected. argument ignored undirected networks. Inf_as_NaN cost values unconnected nodes stored NaN instead Inf? Defaults FALSE. router routing backend use cost matrix computation. Currently supported options 'igraph' 'dodgr'. See Details. use_names column named name present nodes table, names used row column names matrix, instead node indices? Defaults FALSE. Ignored nodes table column named name. ... Additional arguments passed underlying function chosen routing backend. See Details.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_cost.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Compute a cost matrix of a spatial network — st_network_cost","text":"n times m numeric matrix n length argument, m length argument.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_cost.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Compute a cost matrix of a spatial network — st_network_cost","text":"sfnetworks package implement routing algorithms compute cost matrices. Instead, relies \"routing backends\", .e. R packages implemented algorithms. Currently two different routing backends supported. default igraph. package supports many--many cost matrix computation distances function. igraph router support dual-weighted routing. second supported routing backend dodgr. package supports many--many cost matrix computation dodgr_dists function. also supports dual-weighted routing. dodgr package conditional dependency sfnetworks. Using dodgr router requires dodgr package installed. default router can changed setting sfn_default_router option.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_cost.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Compute a cost matrix of a spatial network — st_network_cost","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) net = as_sfnetwork(roxel, directed = FALSE) |> st_transform(3035) # Compute the network cost matrix between node pairs. # Note that geographic edge length is used as edge weights by default. st_network_cost(net, from = c(495, 121), to = c(495, 121)) #> Units: [m] #> 495 121 #> 495 0.0000 669.8584 #> 121 669.8584 0.0000 # st_network_distance is a synonym for st_network_cost with default weights. st_network_distance(net, from = c(495, 121), to = c(495, 121)) #> Units: [m] #> 495 121 #> 495 0.0000 669.8584 #> 121 669.8584 0.0000 # Compute the network cost matrix between spatial point features. # These are snapped to their nearest node before computing costs. p1 = st_geometry(net, \"nodes\")[495] + st_sfc(st_point(c(50, -50))) st_crs(p1) = st_crs(net) p2 = st_geometry(net, \"nodes\")[121] + st_sfc(st_point(c(-10, 100))) st_crs(p2) = st_crs(net) st_network_cost(net, from = c(p1, p2), to = c(p1, p2)) #> Units: [m] #> 477 216 #> 477 0.0000 586.0027 #> 216 586.0027 0.0000 # Use a node type query function to specify origins and/or destinations. st_network_cost(net, from = 499, to = node_is_connected(499)) #> Units: [m] #> 1 2 3 4 5 6 7 8 #> 499 873.5359 890.7781 454.4463 395.7263 370.4559 390.7588 1026.71 1069.539 #> 9 10 11 12 13 14 15 16 #> 499 351.2491 315.9345 1725.54 1714.639 546.2603 586.0429 1199.573 1264.65 #> 17 18 19 20 21 22 23 24 #> 499 229.0913 146.2307 501.4977 436.5051 1504.114 1547.867 1062.55 1110.435 #> 25 26 27 28 29 30 31 32 #> 499 1685.448 1783.653 1070.348 999.1489 1393.529 1413.081 1463.669 1467.738 #> 33 34 35 36 37 38 39 40 #> 499 1718.225 1114.448 1155.142 350.4034 286.7882 565.7165 504.8286 1073.319 #> 41 42 43 44 45 46 47 48 #> 499 1133.801 1112.113 1094.508 1295.444 1305.242 95.07722 76.55244 609.2674 #> 49 50 51 52 53 54 55 56 #> 499 649.819 1930.735 1975.236 1017.045 1005.434 619.4744 701.2313 1317.5 #> 57 58 59 60 61 62 63 64 #> 499 1279.314 1177.133 1090.709 769.5344 776.8791 2091.375 2107.009 1120.121 #> 65 66 67 68 69 70 71 72 #> 499 1219.012 708.9491 695.864 624.1239 1333.874 1319.891 1431.409 1392.694 #> 73 74 75 76 77 78 79 80 #> 499 666.0641 657.6485 792.224 808.1169 811.165 802.1964 1867.797 1920.723 #> 81 82 83 84 85 86 87 88 #> 499 1098.61 783.9091 774.7897 302.3767 323.6855 935.1098 949.0832 494.1647 #> 89 90 91 92 93 94 95 96 #> 499 504.297 1293.018 1322.872 275.5442 236.9272 1601.008 1614.451 1500.923 #> 97 98 99 100 101 102 103 104 #> 499 1595.084 1207.889 1262.779 226.1544 216.135 1966.568 1933.414 756.4774 #> 105 106 107 108 109 110 111 112 #> 499 803.9649 879.5799 220.5792 1304.358 1390.99 265.8059 811.4966 796.2788 #> 113 114 115 116 117 118 119 120 #> 499 559.156 583.344 700.3703 685.7695 805.7022 942.5596 794.1741 724.5884 #> 121 122 123 124 125 126 127 128 #> 499 1566.494 1599.482 718.8359 712.5437 1790.244 1748.59 2085.279 2197.803 #> 129 130 131 132 133 134 135 136 #> 499 395.7898 448.1837 1825.287 1833.432 1491.258 1661.668 1614.675 1282.273 #> 137 138 139 140 141 142 143 144 #> 499 1218.446 468.3246 528.289 926.9009 986.05 1102.083 997.9613 1179.76 #> 145 146 147 148 149 150 151 152 #> 499 1147.025 1195.977 1468.043 1502.416 787.5854 785.1026 1056.22 1042.937 #> 153 154 155 156 157 158 159 160 #> 499 729.0523 742.5479 1897.167 1978.351 1807.294 1811.299 401.87 902.3921 #> 161 162 163 164 165 166 167 168 #> 499 898.7296 734.3901 728.0375 839.2339 859.1539 172.8241 78.90951 1102.744 #> 169 170 171 172 173 174 175 176 #> 499 1137.421 1023.595 1050.153 847.2224 843.043 786.3771 716.9932 762.0341 #> 177 178 179 180 181 182 183 184 #> 499 774.468 871.3191 863.3708 1362.292 743.014 751.3349 695.3414 1242.037 #> 185 186 187 188 189 190 191 192 #> 499 1150.204 1033.579 1995.184 2092.136 1414.947 1329.204 771.6893 353.9481 #> 193 194 195 196 197 198 199 200 #> 499 382.0394 1024.415 192.3578 841.323 1765.551 1696.855 1677.519 1799.113 #> 201 202 203 204 205 206 207 208 #> 499 709.3068 681.6219 1038.633 570.1891 575.9745 798.4155 963.8589 971.197 #> 209 210 211 212 213 214 215 216 #> 499 1044.179 614.7124 1118.057 1073.895 932.7385 935.7969 1415.223 1477.426 #> 217 218 219 220 221 222 223 224 #> 499 1022.83 951.6681 235.4296 812.5915 790.7162 1788.932 1832.053 1491.298 #> 225 226 227 228 229 230 231 232 #> 499 1546.143 1461.208 758.766 707.9535 1142.598 1163.339 185.434 278.5785 #> 233 234 235 236 237 238 239 240 #> 499 706.7727 719.7412 687.0465 1149.023 1198.325 1027.229 1100.083 675.5914 #> 241 242 243 244 245 246 247 248 #> 499 504.674 922.5865 813.5493 2064.305 2122.993 560.7615 607.6151 713.3061 #> 249 250 251 252 253 254 255 256 #> 499 1794.755 1837.644 1635.943 1694.008 1244.902 1057.333 443.0819 2183.752 #> 257 258 259 260 261 262 263 264 #> 499 1972.943 533.5964 589.8798 861.3666 802.1954 798.7234 1253.264 1227.5 #> 265 266 267 268 269 270 271 272 #> 499 1245.892 1815.611 870.1464 642.7876 683.6954 572.1387 502.8064 1814.839 #> 273 274 275 276 277 278 279 280 #> 499 1663.84 1712.093 1228.727 400.3016 1137.473 1094.758 1215.157 1272.686 #> 281 282 283 284 285 286 287 288 #> 499 1789.487 716.7609 725.8832 411.8817 353.359 730.4308 745.1619 756.7788 #> 289 290 291 292 293 294 295 296 #> 499 708.4335 927.7335 1182.694 1218.035 161.0607 142.751 601.652 595.1236 #> 297 298 299 300 301 302 303 304 #> 499 634.4614 750.1124 417.9026 689.744 624.7566 333.4458 1394.947 1291.632 #> 305 306 307 308 309 310 311 312 #> 499 1315.717 1265.51 297.5152 283.5637 179.4085 554.4512 705.5108 732.8085 #> 313 314 315 316 317 318 319 320 #> 499 589.1681 1949.918 1992.497 750.6381 886.0768 261.8298 492.9583 816.1173 #> 321 322 323 324 325 326 327 328 #> 499 834.3017 1410.342 1035.057 1085.489 721.3834 731.3224 805.1009 1180.76 #> 329 330 331 332 333 334 335 336 #> 499 1207.386 1167.683 1248.034 1340.535 970.5099 956.9948 624.8838 674.8888 #> 337 338 339 340 341 342 343 344 #> 499 1911.344 1163.983 447.6591 733.1545 1343.526 1977.468 1006.863 1024.421 #> 345 346 347 348 349 350 351 352 #> 499 945.6122 975.5134 1118.792 1432.043 2019.305 2080.727 820.2956 264.9639 #> 353 354 355 356 357 358 359 360 #> 499 1818.028 1805.63 502.6757 465.9777 1988.397 1998.708 1564.662 525.9751 #> 361 362 363 364 365 366 367 368 #> 499 1429.724 1440.644 755.268 664.929 789.7645 771.3454 1359.269 1297.26 #> 369 370 371 372 373 374 375 376 #> 499 682.0728 691.9732 1010.824 989.3609 1146.893 1183.224 590.5177 697.0859 #> 377 378 379 380 381 382 383 384 #> 499 674.318 739.3548 1109.368 1118.758 921.091 2018.192 1074.6 1019.425 #> 385 386 387 388 389 390 391 392 #> 499 1204.666 1206.25 398.1214 338.4697 1389.573 1420.275 1259.403 1219.991 #> 393 394 395 396 397 398 399 400 #> 499 754.4252 1113.349 892.7151 1050.228 1010.697 778.4496 1207.405 1177.858 #> 401 402 403 404 405 406 407 408 #> 499 1639.966 1621.967 2014.519 1980.016 918.1276 213.4413 1323.652 1397.072 #> 409 410 413 414 415 416 417 418 #> 499 857.6601 810.1723 1610.574 1601.54 1477.911 1489.697 572.2393 555.5383 #> 419 420 421 422 423 424 425 426 #> 499 868.4021 731.1656 985.5966 538.034 1372.061 1426.185 428.6591 443.7392 #> 427 428 429 430 431 432 433 434 #> 499 661.5626 701.5294 1049.618 1077.23 70.89328 1015.033 1021.803 799.7069 #> 435 436 437 438 439 440 441 442 #> 499 751.6018 883.5399 863.6545 1162.006 256.1853 1357.605 1320.362 768.7192 #> 443 444 445 446 447 448 449 450 #> 499 995.7929 877.1031 963.6314 1268.604 1884.311 1948.057 790.2483 1079.821 #> 451 452 453 454 455 456 457 458 459 #> 499 614.3545 1037.168 1069.597 1891.7 1846.564 783.111 437.0745 760.5347 726.57 #> 460 461 462 463 464 465 466 467 #> 499 778.6045 541.5726 443.7159 952.8758 931.6692 912.2639 882.1958 787.7835 #> 468 469 470 471 472 473 474 475 #> 499 802.1098 688.9575 895.6581 411.3635 466.1645 950.23 990.4158 1014.519 #> 476 477 478 479 480 481 482 483 #> 499 1112.34 1143.153 1028.215 989.123 677.9555 735.1794 797.7426 765.1309 #> 484 485 486 487 488 489 490 491 #> 499 695.5624 701.8724 1167.1 928.8087 988.4196 998.7653 1299.383 753.645 #> 492 493 494 495 496 497 498 499 500 #> 499 421.6002 1068.93 968.4631 970.601 483.8035 718.4127 26.24319 0 1520.817 #> 501 502 503 504 505 506 507 508 #> 499 1485.882 1432.847 893.7283 916.1384 1410.803 1627.004 533.9837 436.2807 #> 509 510 511 512 513 514 515 516 #> 499 1268.185 2051.565 1914.639 1871.164 959.2229 981.9011 2074.433 2027.182 #> 517 518 519 520 521 522 523 524 #> 499 1685.317 1647.46 1215.887 1156.045 881.2774 798.5854 2038.379 2108.918 #> 525 526 527 528 529 530 531 532 #> 499 1261.569 224.2117 1207.469 1399.596 1013.212 88.66324 948.022 960.0364 #> 533 534 535 536 537 538 539 540 #> 499 1191.677 1194.926 2164.223 1172.918 1034.628 556.6538 1244.016 807.5977 #> 541 542 543 544 545 546 547 548 #> 499 731.7814 947.684 196.3235 1128.433 1070.533 1140.752 1511.707 1005.075 #> 549 550 551 552 553 554 555 556 #> 499 2067.482 127.8707 109.4762 1000.702 961.5858 1484.043 1306.83 704.6871 #> 557 558 559 560 561 562 563 564 #> 499 1227.932 207.7041 699.1399 679.3837 539.6218 574.364 1106.416 230.8235 #> 565 566 567 568 569 570 571 572 #> 499 800.7528 884.0467 675.1501 1207.369 1259.219 723.0045 767.3387 1068.846 #> 573 574 575 576 577 578 579 580 #> 499 1122.525 1647.363 1681.341 1186.372 739.9597 1808.023 1789.649 625.6373 #> 581 582 583 584 585 586 587 588 #> 499 1385.485 1417.895 766.1218 886.6601 787.6855 1542.166 2061.891 2120.105 #> 589 590 591 592 593 594 595 596 #> 499 1291.37 1022.637 974.9281 91.80787 1130.475 1289.641 648.7288 973.0365 #> 597 598 599 600 601 602 603 604 #> 499 435.8192 1124.679 258.3585 1403.557 1382.773 1340.972 477.7011 1211.504 #> 605 606 607 608 609 610 611 612 #> 499 1223.968 850.3333 883.7363 1129.332 2079.183 2016.091 812.6261 1244.609 #> 613 614 615 616 617 618 619 620 #> 499 1407.618 1346.475 2065.414 1288.791 1055.392 1046.531 2117.588 2124.025 #> 621 622 623 624 625 626 627 628 #> 499 1532.199 462.9961 910.2988 876.4129 1193.128 1227.285 1327.896 1816.52 #> 629 630 631 632 633 634 635 636 #> 499 882.195 1687.382 1095.329 1047.081 1158.213 1795.897 1857.86 766.2416 #> 637 638 639 640 641 642 643 644 #> 499 213.0037 203.3805 1934.558 2034.374 1695.136 1909.915 1341.518 1023.916 #> 645 646 647 648 649 650 651 652 #> 499 1030.418 234.2636 965.4015 1313.324 1307.588 933.0533 700.2591 1024.032 #> 653 654 655 656 657 658 659 660 #> 499 978.7125 584.0124 567.3972 508.6142 1508.389 794.7913 751.6468 430.5427 #> 661 662 663 664 665 666 667 668 #> 499 804.8805 773.2935 1463.782 234.5408 276.6258 674.5731 1799.23 953.4275 #> 669 670 671 672 673 674 675 676 #> 499 988.6681 878.1092 1644.942 1108.142 1996.853 504.8011 506.1029 1005.36 #> 677 678 679 680 681 682 683 684 #> 499 968.4955 1163.167 1128.56 792.1399 1027.9 731.6821 641.5734 558.6926 #> 685 686 687 688 689 690 691 692 #> 499 2021.381 1979.748 1267.286 318.0388 302.2884 481.0959 1445.202 2068.889 #> 693 694 695 696 697 698 699 700 #> 499 1840.76 605.962 1277.076 175.2124 1068.836 1101.401 1378.351 704.8933 #> 701 702 703 704 705 706 707 708 #> 499 260.6005 950.3017 2071.935 1158.668 1218.141 1635.553 1047.712 992.2682 #> 709 710 711 712 713 714 715 716 #> 499 877.1812 1114.472 634.1746 732.0683 1226.632 1787.411 1747.728 277.7143 #> 717 718 719 720 721 722 725 726 #> 499 241.2495 1782.547 1823.278 1454.134 1113.028 1320.655 2240.015 818.1879 #> 727 728 729 730 731 732 733 734 #> 499 1948.993 1966.811 1550.956 585.9248 426.6295 1265.835 821.7813 829.7346 #> 735 736 737 738 739 740 741 742 #> 499 1319.394 1274.719 64.04235 757.7018 897.6014 820.0067 1187.91 496.563 #> 743 744 745 746 747 748 749 750 #> 499 1394.653 795.5651 815.0034 1462.494 1239.723 1025 1539.497 432.6431 #> 751 752 753 754 755 756 757 758 #> 499 977.7647 1005.843 953.2313 954.8321 986.1761 1641.337 1563.292 874.2878 #> 759 760 761 762 763 764 765 766 #> 499 219.6254 281.1079 1161.28 910.5567 1445.753 784.7109 764.9534 1046.16 #> 767 768 769 770 771 772 773 774 #> 499 1060.537 1130.048 107.5825 128.8957 1510.703 1208.487 1842.702 671.6482 #> 775 776 777 778 779 780 781 782 #> 499 223.2587 1503.52 868.2117 1552.216 1708.253 1114.04 1823.167 1848.869 #> 783 784 785 786 787 788 789 792 #> 499 1534.451 1018.834 1491.916 488.2741 1226.831 808.946 1374.314 1454.677 #> 793 794 795 796 797 798 799 800 #> 499 307.4676 531.0321 754.7953 1168.374 1295.403 1347.812 1258.33 976.7465 #> 801 802 803 804 805 806 807 808 #> 499 900.8321 1322.963 1346.695 634.8554 694.3095 2002.157 2087.135 949.9061 #> 809 810 811 812 813 814 815 816 #> 499 905.9081 951.311 1277.412 382.5939 1330.126 2069.033 479.8494 473.9061 #> 817 818 819 820 821 822 823 824 #> 499 1639.596 954.6902 1169.867 1682.054 1515.118 1120.421 1250.853 1361.224 #> 825 826 827 828 829 830 831 832 #> 499 1890.399 1672.262 1957.889 70.50971 34.52996 969.0309 822.0138 306.983 #> 833 834 835 836 837 838 839 840 #> 499 1531.468 205.9225 1568.601 443.9537 1910.284 1915.773 527.5518 518.4602 #> 841 842 843 844 845 846 847 848 #> 499 606.6241 2040.418 1013.449 791.2585 381.9352 435.689 506.122 790.6733 #> 849 850 851 852 853 854 855 856 #> 499 207.035 2122.036 263.0604 509.8525 1510.887 319.9886 527.4409 591.1522 #> 857 858 859 860 861 862 863 864 #> 499 530.1348 747.5255 2083.59 736.9322 1332.059 514.678 1369.265 756.3091 #> 865 866 867 868 869 870 871 874 #> 499 919.6888 1763.417 1246.848 1188.992 1066.707 1247.632 889.2161 1191.559 #> 875 876 877 878 879 882 883 884 #> 499 542.3983 928.7408 1277.937 1339.039 1351.035 1557.681 1200.119 1230.94 #> 885 886 887 888 889 890 891 892 #> 499 2016.176 1900.649 2066.189 1119.22 930.375 944.732 915.9002 739.707 #> 893 894 895 896 897 898 899 900 #> 499 2001.624 527.5662 667.6359 2194.16 1292.515 1405.212 1460.603 462.576 #> 901 902 903 904 905 906 907 908 #> 499 137.348 1466.772 2065.266 1379.913 1416.664 1087.82 545.728 903.406 #> 909 910 911 912 913 914 917 918 #> 499 719.0583 805.8947 1817.649 1817.592 1817.655 1413.654 1161.006 2193.013 #> 919 920 921 922 923 924 925 926 #> 499 302.8186 1979.013 532.8349 1128.923 55.19123 1056.032 1537.776 1865.731 #> 927 928 929 930 931 932 933 934 #> 499 355.7311 831.0173 1807.189 1611.983 1150.719 378.8421 344.6649 930.014 #> 935 936 937 938 939 940 941 942 #> 499 973.2863 1221.223 1225.44 1407.8 235.7138 1194.315 778.1079 1162.499 #> 943 944 945 946 947 948 949 950 #> 499 1722.817 1235.034 320.6124 1844.805 599.1794 316.4717 704.0765 2062.273 #> 951 952 953 954 955 956 957 958 #> 499 733.9683 994.0074 1948.294 1482.403 794.4001 1080.372 304.5142 2184.952 #> 959 960 961 962 963 968 969 970 #> 499 511.2051 486.254 1056.011 868.6776 1355.249 249.6424 831.5113 1632.802 #> 971 972 973 974 975 976 977 978 #> 499 1491.589 1880.007 1285.894 839.9045 1510.393 931.8767 742.3722 394.0489 #> 979 980 981 982 983 984 985 986 #> 499 847.7391 90.92951 748.3793 1992.011 1293.83 512.1374 1552.246 1315.151 #> 987 #> 499 1196.929 # Use a spatial edge measure to specify edge weights. # By default edge_length() is used. st_network_cost(net, c(p1, p2), c(p1, p2), weights = edge_displacement()) #> Units: [m] #> 477 216 #> 477 0.0000 583.9299 #> 216 583.9299 0.0000 # Use a column in the edges table to specify edge weights. # This uses tidy evaluation. net |> activate(\"edges\") |> mutate(foo = runif(n(), min = 0, max = 1)) |> st_network_cost(c(p1, p2), c(p1, p2), weights = foo) #> 477 216 #> 477 0.000000 4.625577 #> 216 4.625577 0.000000 # Compute the cost matrix without edge weights. # Here the cost is defined by the number of edges, ignoring space. st_network_cost(net, c(p1, p2), c(p1, p2), weights = NA) #> 477 216 #> 477 0 10 #> 216 10 0 # Use the dodgr router for dual-weighted routing. paths = st_network_cost(net, from = c(p1, p2), to = c(p1, p2), weights = dual_weights(edge_segment_count(), edge_length()), router = \"dodgr\" ) # Not providing any from or to points includes all nodes by default. with_graph(net, graph_order()) # Our network has 701 nodes. #> [1] 987 cost_matrix = st_network_cost(net) dim(cost_matrix) #> [1] 987 987"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_faces.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract the faces of a spatial network — st_network_faces","title":"Extract the faces of a spatial network — st_network_faces","text":"faces spatial network areas bounded edges, without edge crossing . special face outer face, area bounded set edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_faces.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract the faces of a spatial network — st_network_faces","text":"","code":"st_network_faces(x, boundary = NULL)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_faces.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract the faces of a spatial network — st_network_faces","text":"x object class sfnetwork. boundary boundary used outer face, object class sf sfc containing single POLYGON geometry. Note boundary always larger bounding box network. NULL (default) network bounding box extended 0.1 times diameter used.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_faces.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract the faces of a spatial network — st_network_faces","text":"object class sfc POLYGON geometries, feature represents one face network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_faces.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Extract the faces of a spatial network — st_network_faces","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) pts = st_transform(mozart, 3035) net = as_sfnetwork(pts, \"delaunay\") faces = st_network_faces(net) plot(faces, col = sf.colors(length(faces), categorical = TRUE)) plot(net, add = TRUE) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_iso.html","id":null,"dir":"Reference","previous_headings":"","what":"Compute isolines around nodes in a spatial network — st_network_iso","title":"Compute isolines around nodes in a spatial network — st_network_iso","text":"Isolines curves along function constant value. spatial networks, used delineate areas reachable given node within given travel cost. travel cost distance, known isodistances, travel cost time, known isochrones. function finds network nodes lie inside isoline around specified node.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_iso.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Compute isolines around nodes in a spatial network — st_network_iso","text":"","code":"st_network_iso( x, node, cost, weights = edge_length(), ..., delineate = TRUE, ratio = 1, allow_holes = FALSE )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_iso.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Compute isolines around nodes in a spatial network — st_network_iso","text":"x object class sfnetwork. node node around isolines drawn. Evaluated evaluate_node_query. multiple nodes given, first one used. cost constant cost value isoline. numeric value units given edge weights. Alternatively, units can specified explicitly providing units object. Multiple values may given, result multiple isolines drawn. weights edge weights used shortest path calculation. Evaluated evaluate_weight_spec. default edge_length, computes geographic lengths edges. ... Additional arguments passed st_network_cost compute cost matrix specified node nodes network. delineate nodes inside isoline delineated? FALSE, nodes inside isoline returned MULTIPOINT geometry. TRUE, concave hull geometry returned instead. Defaults TRUE. ratio ratio concave hull. Defaults 1, meaning convex hull computed. See st_concave_hull details. Ignored delineate = FALSE. Setting value smaller 1 requires GEOS version least 3.11. allow_holes May concave hull holes? Defaults FALSE. Ignored delineate = FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_iso.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Compute isolines around nodes in a spatial network — st_network_iso","text":"object class sf one row per requested isoline. object contains following columns: cost: constant cost value isoline. geometry: delineate = TRUE, concave hull nodes lie inside isoline. Otherwise, nodes combined single MULTIPOINT geometry.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_iso.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Compute isolines around nodes in a spatial network — st_network_iso","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) center = st_centroid(st_combine(st_geometry(roxel))) net = as_sfnetwork(roxel, directed = FALSE) iso = net |> st_network_iso(node_is_nearest(center), c(1000, 500, 250)) colors = c(\"#fee6ce90\", \"#fdae6b90\", \"#e6550d90\") plot(net) plot(st_geometry(iso), col = colors, add = TRUE) # The level of detail can be increased with the ratio argument. # This requires GEOS >= 3.11. if (compareVersion(sf_extSoftVersion()[[\"GEOS\"]], \"3.11.0\") > -1) { iso = net |> st_network_iso(node_is_nearest(center), c(1000, 500, 250), ratio = 0.3) colors = c(\"#fee6ce90\", \"#fdae6b90\", \"#e6550d90\") plot(net) plot(st_geometry(iso), col = colors, add = TRUE) } par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_join.html","id":null,"dir":"Reference","previous_headings":"","what":"Join two spatial networks based on equality of node geometries — st_network_join","title":"Join two spatial networks based on equality of node geometries — st_network_join","text":"spatial network specific join function makes spatial full join geometries nodes data. Edge data combined using bind_rows semantic, meaning data matched column name values filled NA missing either networks. columns edge data updated match new node indices resulting network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_join.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Join two spatial networks based on equality of node geometries — st_network_join","text":"","code":"st_network_join(x, y, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_join.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Join two spatial networks based on equality of node geometries — st_network_join","text":"x object class sfnetwork. y object class sfnetwork, directly convertible using as_sfnetwork. ... Arguments passed graph_join.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_join.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Join two spatial networks based on equality of node geometries — st_network_join","text":"joined networks object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_join.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Join two spatial networks based on equality of node geometries — st_network_join","text":"default sfnetworks rounds coordinates 12 decimal places determine spatial equality. can influence behavior explicitly setting precision networks using st_set_precision.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_join.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Join two spatial networks based on equality of node geometries — st_network_join","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) # Create two networks. n1 = st_point(c(0, 0)) n2 = st_point(c(1, 0)) n3 = st_point(c(1,1)) n4 = st_point(c(0,1)) e1 = st_sfc(st_linestring(c(n1, n2))) e2 = st_sfc(st_linestring(c(n2, n3))) e3 = st_sfc(st_linestring(c(n3, n4))) neta = as_sfnetwork(c(e1, e2)) netb = as_sfnetwork(c(e2, e3)) # Join the networks based on spatial equality of nodes. net = st_network_join(neta, netb) net #> # A sfnetwork: 4 nodes and 4 edges #> # #> # A directed acyclic multigraph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 1 ymax: 1 #> # CRS: NA #> # #> # Node data: 4 × 1 (active) #> x #> #> 1 (0 0) #> 2 (1 0) #> 3 (1 1) #> 4 (0 1) #> # #> # Edge data: 4 × 3 #> from to x #> #> 1 1 2 (0 0, 1 0) #> 2 2 3 (1 0, 1 1) #> 3 2 3 (1 0, 1 1) #> # ℹ 1 more row # Plot. plot(neta, pch = 15, cex = 2, lwd = 4) plot(netb, col = \"orange\", pch = 18, cex = 2, lty = 3, lwd = 4, add = TRUE) plot(net, cex = 2, lwd = 4) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_paths.html","id":null,"dir":"Reference","previous_headings":"","what":"Find shortest paths between nodes in a spatial network — st_network_paths","title":"Find shortest paths between nodes in a spatial network — st_network_paths","text":"Find shortest paths nodes spatial network","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_paths.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Find shortest paths between nodes in a spatial network — st_network_paths","text":"","code":"st_network_paths( x, from, to = node_ids(x), weights = edge_length(), all = FALSE, k = 1, direction = \"out\", router = getOption(\"sfn_default_router\", \"igraph\"), use_names = FALSE, return_cost = TRUE, return_geometry = TRUE, ... )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_paths.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Find shortest paths between nodes in a spatial network — st_network_paths","text":"x object class sfnetwork. node paths start. Evaluated evaluate_node_query. nodes paths end. Evaluated evaluate_node_query. default, nodes network included. weights edge weights used shortest path calculation. Evaluated evaluate_weight_spec. default edge_length, computes geographic lengths edges. shortest paths returned pair nodes? set FALSE, one shortest path returned pair nodes, even multiple shortest paths exist. Defaults FALSE. k number paths find. Setting integer higher 1 returns shortest path, also next k - 1 loopless shortest paths, may longer shortest path. Currently, supported one--one routing, meaning argument length 1. argument ignored set TRUE. direction direction travel. Defaults '', meaning direction given network followed paths found node given argument . May set '', meaning opposite direction followed paths found towards node given argument . May also set '', meaning network considered undirected. argument ignored undirected networks. router routing backend use shortest path computation. Currently supported options 'igraph' 'dodgr'. See Details. use_names column named name present nodes table, names used encode nodes path, instead node indices? Defaults FALSE. Ignored nodes table column named name. return_cost total cost path computed? Defaults TRUE. return_geometry linestring geometry constructed path? Defaults TRUE. geometries constructed calling st_line_merge linestring geometries edges path. Ignored networks spatially implicit edges. ... Additional arguments passed underlying function chosen routing backend. See Details.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_paths.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Find shortest paths between nodes in a spatial network — st_network_paths","text":"object class sf one row per requested path. return_geometry = FALSE edges spatially implicit, tbl_df returned instead. requested path found, included output empty path. Depending argument settings, output may include following columns: : index node start path. : index node end path. node_path: vector containing indices nodes path, order visit. edge_path: vector containing indices edges path, order visit. path_found: boolean describing requested path exists. cost: total cost path, obtained summing weights visited edges. Included return_cost = TRUE. geometry: geometry path, obtained merging geometries visited edges. Included return_geometry = TRUE network spatially explicit edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_paths.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Find shortest paths between nodes in a spatial network — st_network_paths","text":"sfnetworks package implement routing algorithms find shortest paths. Instead, relies \"routing backends\", .e. R packages implemented algorithms. Currently two different routing backends supported. default igraph. package supports one--many shortest path calculation shortest_paths function. Note multiple nodes supported. multiple nodes given, first one taken. igraph router also supports computation shortest path (see argument) all_shortest_paths function k shortest paths (see k argument) k_shortest_paths function. latter case, one--one routing supported, meaning also one node provided. igraph router support dual-weighted routing. second supported routing backend dodgr. package supports many--many shortest path calculation dodgr_paths function. also supports dual-weighted routing. computation shortest paths k shortest paths currently supported dodgr router. dodgr package conditional dependency sfnetworks. Using dodgr router requires dodgr package installed. default router can changed setting sfn_default_router option.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_paths.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Find shortest paths between nodes in a spatial network — st_network_paths","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) net = as_sfnetwork(roxel, directed = FALSE) |> st_transform(3035) # Compute the shortest path between two nodes. # Note that geographic edge length is used as edge weights by default. paths = st_network_paths(net, from = 495, to = 121) paths #> Simple feature collection with 1 feature and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4152025 ymin: 3207259 xmax: 4152176 ymax: 3207843 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 495 121 TRUE 670. (4152096 3207259, 4152130 3… plot(net, col = \"grey\") plot(st_geometry(net)[paths$from], pch = 20, cex = 2, add = TRUE) plot(st_geometry(paths), col = \"orange\", lwd = 3, add = TRUE) # Compute the shortest paths from one to multiple nodes. # This will return a tibble with one row per path. paths = st_network_paths(net, from = 495, to = c(121, 131, 141)) paths #> Simple feature collection with 3 features and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4151719 ymin: 3206620 xmax: 4152176 ymax: 3207957 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 3 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 495 121 TRUE 670. (4152096 3207259, 4152130 … #> 2 495 131 TRUE 1496. (4151720 3206620, 4151719 … #> 3 495 141 TRUE 214. (4152055 3207957, 4151998 … plot(net, col = \"grey\") plot(st_geometry(net)[paths$from], pch = 20, cex = 2, add = TRUE) plot(st_geometry(paths), col = \"orange\", lwd = 3, add = TRUE) # Compute the shortest path between two spatial point features. # These are snapped to their nearest node before finding the path. p1 = st_geometry(net, \"nodes\")[495] + st_sfc(st_point(c(50, -50))) st_crs(p1) = st_crs(net) p2 = st_geometry(net, \"nodes\")[121] + st_sfc(st_point(c(-10, 100))) st_crs(p2) = st_crs(net) paths = st_network_paths(net, from = p1, to = p2) paths #> Simple feature collection with 1 feature and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4152060 ymin: 3207348 xmax: 4152221 ymax: 3207784 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 477 216 TRUE 586. (4152060 3207348, 4152122 3… plot(net, col = \"grey\") plot(c(p1, p2), pch = 20, cex = 2, add = TRUE) plot(st_geometry(net)[paths$from], pch = 4, cex = 2, add = TRUE) plot(st_geometry(paths), col = \"orange\", lwd = 3, add = TRUE) # Use a node type query function to specify destinations. st_network_paths(net, 1, node_is_adjacent(1)) #> Simple feature collection with 4 features and 6 fields (with 1 geometry empty) #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4151754 ymin: 3207609 xmax: 4151785 ymax: 3207727 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 4 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 1 1 TRUE 0 EMPTY #> 2 1 2 TRUE 17.2 (4151782 3207612, 4151765 3… #> 3 1 393 TRUE 119. (4151757 3207727, 4151754 3… #> 4 1 624 TRUE 2.88 (4151785 3207613, 4151782 3… # Use a spatial edge measure to specify edge weights. # By default edge_length() is used. st_network_paths(net, p1, p2, weights = edge_displacement()) #> Simple feature collection with 1 feature and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4152060 ymin: 3207348 xmax: 4152221 ymax: 3207784 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 477 216 TRUE 584. (4152060 3207348, 4152122 3… # Use a column in the edges table to specify edge weights. # This uses tidy evaluation. net |> activate(\"edges\") |> mutate(foo = runif(n(), min = 0, max = 1)) |> st_network_paths(p1, p2, weights = foo) #> Simple feature collection with 1 feature and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4152060 ymin: 3207348 xmax: 4152244 ymax: 3207784 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 7 #> from to node_path edge_path path_found cost geometry #> #> 1 477 216 TRUE 4.57 (4152060 3207348, 4152122 … # Compute the shortest paths without edge weights. # This is the path with the fewest number of edges, ignoring space. st_network_paths(net, p1, p2, weights = NA) #> Simple feature collection with 1 feature and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4152060 ymin: 3207348 xmax: 4152180 ymax: 3207784 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 7 #> from to node_path edge_path path_found cost geometry #> #> 1 477 216 TRUE 10 (4152060 3207348, 4152122 … # Use the dodgr router for many-to-many routing. paths = st_network_paths(net, from = c(1, 2), to = c(10, 11), router = \"dodgr\" ) # Use the dodgr router for dual-weighted routing. paths = st_network_paths(net, from = c(1, 2), to = c(10, 11), weights = dual_weights(edge_segment_count(), edge_length()), router = \"dodgr\" ) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_travel.html","id":null,"dir":"Reference","previous_headings":"","what":"Find the optimal route through a set of nodes in a spatial network — st_network_travel","title":"Find the optimal route through a set of nodes in a spatial network — st_network_travel","text":"Solve travelling salesman problem finding shortest route set nodes visits nodes .","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_travel.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Find the optimal route through a set of nodes in a spatial network — st_network_travel","text":"","code":"st_network_travel( x, nodes, weights = edge_length(), optimizer = \"TSP\", router = getOption(\"sfn_default_router\", \"igraph\"), return_paths = TRUE, use_names = FALSE, return_cost = TRUE, return_geometry = TRUE, ... )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_travel.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Find the optimal route through a set of nodes in a spatial network — st_network_travel","text":"x object class sfnetwork. nodes Nodes visited. Evaluated evaluate_node_query. weights edge weights used shortest path calculation. Evaluated evaluate_weight_spec. default edge_length, computes geographic lengths edges. optimizer optimization backend use defining optimal visiting order given nodes. Currently supported option 'TSP'. See Details. router routing backend use cost matrix computation path computation. Currently supported options 'igraph' 'dodgr'. See Details. return_paths defining optimal visiting order nodes, actual paths connecting nodes computed returned? Defaults TRUE. set FALSE, vector indices visiting order returned instead, index specifying position visited node argument. use_names column named name present nodes table, names used encode nodes route, instead node indices? Defaults FALSE. Ignored nodes table column named name return_paths = FALSE. return_cost total cost path two subsequent nodes computed? Defaults TRUE. Ignored return_paths = FALSE. return_geometry linestring geometry constructed path two subsequent nodes? Defaults TRUE. geometries constructed calling st_line_merge linestring geometries edges path. Ignored return_paths = FALSE networks spatially implicit edges. ... Additional arguments passed underlying function chosen optimization backend. See Details.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_travel.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Find the optimal route through a set of nodes in a spatial network — st_network_travel","text":"object class sf one row per leg optimal route, containing path leg. return_geometry = FALSE edges spatially implicit, tbl_df returned instead. See documentation st_network_paths details. return_paths = FALSE, vector indices visiting order returned, index specifying position visited node argument.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_travel.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Find the optimal route through a set of nodes in a spatial network — st_network_travel","text":"sfnetworks package implement route optimization algorithms. Instead, relies \"optimization backends\", .e. R packages implemented algorithms. Currently supported optimization backend solve travelling salesman problem TSP package, provides solve_TSP function task. input route optimization algorithms matrix containing travel costs nodes visited. computed using st_network_cost. output route optimization algorithms optimal order given nodes visited. compute actual paths connect nodes order, st_network_paths function used. cost matrix computation shortest paths computation allow specify \"routing backend\", .e. R package implements algorithms solve tasks. See documentation corresponding functions details.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_travel.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Find the optimal route through a set of nodes in a spatial network — st_network_travel","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) net = as_sfnetwork(roxel, directed = FALSE) |> st_transform(3035) # Compute the optimal route through three nodes. # Note that geographic edge length is used as edge weights by default. route = st_network_travel(net, c(1, 10, 100)) route #> Simple feature collection with 3 features and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4151359 ymin: 3207582 xmax: 4151782 ymax: 3208051 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 3 × 7 #> from to node_path edge_path path_found cost geometry #> * [m] #> 1 100 10 TRUE 89.8 (4151383 3207963, 4151368 … #> 2 10 1 TRUE 667. (4151383 3207963, 4151413 … #> 3 1 100 TRUE 728. (4151359 3208049, 4151364 … plot(net, col = \"grey\") plot(st_geometry(net)[route$from], pch = 20, cex = 2, add = TRUE) plot(st_geometry(route), col = \"orange\", lwd = 3, add = TRUE) # Instead of returning a path we can return a vector of visiting order. st_network_travel(net, c(1, 10, 100), return_paths = FALSE) #> [1] 3 2 1 # Use spatial point features to specify the visiting locations. # These are snapped to their nearest node before finding the path. p1 = st_geometry(net, \"nodes\")[1] + st_sfc(st_point(c(50, -50))) p2 = st_geometry(net, \"nodes\")[10] + st_sfc(st_point(c(-10, 100))) p3 = st_geometry(net, \"nodes\")[100] + st_sfc(st_point(c(-10, 100))) pts = c(p1, p2, p3) st_crs(pts) = st_crs(net) route = st_network_travel(net, pts) route #> Simple feature collection with 3 features and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4151325 ymin: 3207456 xmax: 4151850 ymax: 3208205 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 3 × 7 #> from to node_path edge_path path_found cost geometry #> * [m] #> 1 544 107 TRUE 936. (4151364 3208051, 4151370 … #> 2 107 737 TRUE 232. (4151364 3208051, 4151359 … #> 3 737 544 TRUE 1168. (4151378 3208168, 4151369 … plot(net, col = \"grey\") plot(pts, pch = 20, cex = 2, add = TRUE) plot(st_geometry(net)[route$from], pch = 4, cex = 2, add = TRUE) plot(st_geometry(route), col = \"orange\", lwd = 3, add = TRUE) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_project_on_network.html","id":null,"dir":"Reference","previous_headings":"","what":"Project spatial points on a spatial network — st_project_on_network","title":"Project spatial points on a spatial network — st_project_on_network","text":"Project spatial points spatial network","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_project_on_network.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Project spatial points on a spatial network — st_project_on_network","text":"","code":"st_project_on_network(x, network, on = \"edges\")"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_project_on_network.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Project spatial points on a spatial network — st_project_on_network","text":"x spatial features projected, either object class sf sfc, POINT geometries. network object class sfnetwork. component network points projected? Setting 'edges' (default) find nearest point nearest edge point x. Setting 'nodes' find nearest node point x.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_project_on_network.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Project spatial points on a spatial network — st_project_on_network","text":"object x geometries replaced projections.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_project_on_network.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Project spatial points on a spatial network — st_project_on_network","text":"function uses st_nearest_feature find nearest edge node feature x. projecting edges, finds nearest point nearest edge calling st_nearest_points pairwise manner.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_project_on_network.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Project spatial points on a spatial network — st_project_on_network","text":"Due internal rounding rational numbers, even point projected edge may evaluated actually intersecting edge calling st_intersects.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_project_on_network.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Project spatial points on a spatial network — st_project_on_network","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) # Create a spatial network. n1 = st_point(c(0, 0)) n2 = st_point(c(1, 0)) n3 = st_point(c(2, 0)) e1 = st_sfc(st_linestring(c(n1, n2)), crs = 3857) e2 = st_sfc(st_linestring(c(n2, n3)), crs = 3857) net = as_sfnetwork(c(e1, e2)) # Create spatial points to project in. p1 = st_sfc(st_point(c(0.25, 0.1))) p2 = st_sfc(st_point(c(1, 0.2))) p3 = st_sfc(st_point(c(1.75, 0.15))) pts = st_sf(foo = letters[1:3], geometry = c(p1, p2, p3), crs = 3857) # Project points to the edges of the network. p1 = st_project_on_network(pts, net) plot(net) plot(st_geometry(pts), pch = 20, col = \"orange\", add = TRUE) plot(st_geometry(p1), pch = 4, col = \"orange\", add = TRUE) # Project points to the nodes of the network. p2 = st_project_on_network(pts, net, on = \"nodes\") plot(net) plot(st_geometry(pts), pch = 20, col = \"orange\", add = TRUE) plot(st_geometry(p2), pch = 4, col = \"orange\", add = TRUE) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_round.html","id":null,"dir":"Reference","previous_headings":"","what":"Rounding of geometry coordinates — st_round","title":"Rounding of geometry coordinates — st_round","text":"Rounding geometry coordinates","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_round.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Rounding of geometry coordinates — st_round","text":"","code":"st_round(x, digits = 0)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_round.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Rounding of geometry coordinates — st_round","text":"x object class sf sfc. digits Integer indicating number decimal places used.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_round.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Rounding of geometry coordinates — st_round","text":"object class sf sfc rounded coordinates.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_round.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Rounding of geometry coordinates — st_round","text":"","code":"library(sf, quietly = TRUE) p1 = st_sfc(st_point(c(1.123, 1.123))) p2 = st_sfc(st_point(c(0.789, 0.789))) p3 = st_sfc(st_point(c(1.123, 0.789))) st_round(st_as_sf(c(p1, p2, p2, p3, p1)), digits = 1) #> Simple feature collection with 5 features and 0 fields #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 0.8 ymin: 0.8 xmax: 1.1 ymax: 1.1 #> CRS: NA #> x #> 1 POINT (1.1 1.1) #> 2 POINT (0.8 0.8) #> 3 POINT (0.8 0.8) #> 4 POINT (1.1 0.8) #> 5 POINT (1.1 1.1)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/subdivide_edges.html","id":null,"dir":"Reference","previous_headings":"","what":"Subdivide edges at interior points — subdivide_edges","title":"Subdivide edges at interior points — subdivide_edges","text":"Construct subdivision network subdividing edges interior points. Subdividing means new node added edge, edge split two location. Interior points points shape linestring geometry feature endpoints .","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/subdivide_edges.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Subdivide edges at interior points — subdivide_edges","text":"","code":"subdivide_edges(x, protect = NULL, all = FALSE, merge = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/subdivide_edges.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Subdivide edges at interior points — subdivide_edges","text":"x object class sfnetwork spatially explicit edges. protect integer vector edge indices specifying edges protected subdivided. Defaults NULL, meaning none edges protected. edges subdivided interior points? set FALSE, edges subdivided interior points share location interior boundary point (node) edges table. Defaults FALSE. merge multiple subdivision points location merged single node, subdivision points location existing node merged node? Defaults TRUE. set FALSE, subdivision point added separately new node network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/subdivide_edges.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Subdivide edges at interior points — subdivide_edges","text":"subdivision x object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/subdivide_edges.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Subdivide edges at interior points — subdivide_edges","text":"default sfnetworks rounds coordinates 12 decimal places determine spatial equality. can influence behavior explicitly setting precision network using st_set_precision.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/tidygraph_methods.html","id":null,"dir":"Reference","previous_headings":"","what":"tidygraph methods for sfnetworks — tidygraph_methods","title":"tidygraph methods for sfnetworks — tidygraph_methods","text":"Normally tidygraph functions work box sfnetwork objects, cases special treatment needed especially geometry column, requiring specific method.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/tidygraph_methods.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"tidygraph methods for sfnetworks — tidygraph_methods","text":"","code":"# S3 method for class 'sfnetwork' as_tbl_graph(x, ...) # S3 method for class 'sfnetwork' reroute(.data, ...) # S3 method for class 'sfnetwork' morph(.data, ...) # S3 method for class 'morphed_sfnetwork' unmorph(.data, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/tidygraph_methods.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"tidygraph methods for sfnetworks — tidygraph_methods","text":"x object class sfnetwork. ... Arguments passed corresponding tidygraph function. .data object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/tidygraph_methods.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"tidygraph methods for sfnetworks — tidygraph_methods","text":"method as_tbl_graph returns object class tbl_graph. method morph returns morphed_sfnetwork morphed network still spatial, morphed_tbl_graph otherwise. methods return object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/tidygraph_methods.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"tidygraph methods for sfnetworks — tidygraph_methods","text":"See tidygraph documentation. following methods special behavior: reroute: preserve valid spatial network structure, method replace boundaries edge geometries location node edges rerouted . Note goal reverse edges spatial network, reroute simply reverse edge geometries. case recommended use sfnetwork method st_reverse instead. morph: method checks morphed network still spatially embedded nodes. case morphed_sfnetwork returned. , morphed_tbl_graph returned instead. unmorph: method makes sure geometry list column correctly handled unmorphing process.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/validate_network.html","id":null,"dir":"Reference","previous_headings":"","what":"Validate the structure of a sfnetwork — validate_network","title":"Validate the structure of a sfnetwork — validate_network","text":"Validate structure sfnetwork","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/validate_network.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Validate the structure of a sfnetwork — validate_network","text":"","code":"validate_network(x, message = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/validate_network.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Validate the structure of a sfnetwork — validate_network","text":"x object class sfnetwork. message messages printed validation? Defaults TRUE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/validate_network.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Validate the structure of a sfnetwork — validate_network","text":"Nothing network valid. Otherwise, error thrown.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/validate_network.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Validate the structure of a sfnetwork — validate_network","text":"valid sfnetwork structure means nodes POINT geometries, - edges spatially explicit - edges LINESTRING geometries, nodes edges coordinate reference system coordinate precision, coordinates edge boundaries match coordinates corresponding nodes.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/wrap_igraph.html","id":null,"dir":"Reference","previous_headings":"","what":"Run an igraph function on an sfnetwork object — wrap_igraph","title":"Run an igraph function on an sfnetwork object — wrap_igraph","text":"Since sfnetwork objects inherit igraph objects, igraph function can called sfnetwork. However, function returns network, igraph object rather sfnetwork object. wrap_igraph, function preserve sfnetwork class, checking network returned igraph still valid spatial network structure.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/wrap_igraph.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Run an igraph function on an sfnetwork object — wrap_igraph","text":"","code":"wrap_igraph(.data, .f, ..., .force = FALSE, .message = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/wrap_igraph.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Run an igraph function on an sfnetwork object — wrap_igraph","text":".data object class sfnetwork. .f function igraph package accepts graph first argument, returns graph. ... Arguments passed .f. .force network validity checks skipped? Defaults FALSE, meaning network validity checks executed returning new network. checks guarantee valid spatial network structure. nodes, means POINT geometries. case spatially explicit edges, also checked edges LINESTRING geometries, nodes edges CRS boundary points edges match corresponding node coordinates. checks important, also time consuming. already sure input data meet requirements, checks unnecessary can turned improve performance. .message informational messages (messages neither warnings errors) printed constructing network? Defaults TRUE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/wrap_igraph.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Run an igraph function on an sfnetwork object — wrap_igraph","text":"object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/wrap_igraph.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Run an igraph function on an sfnetwork object — wrap_igraph","text":"","code":"oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) net = as_sfnetwork(mozart, \"delaunay\", directed = FALSE) mst = wrap_igraph(net, igraph::mst, .message = FALSE) mst #> # A sfnetwork: 17 nodes and 16 edges #> # #> # An unrooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 4 (active) #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> 4 Mozart Denkmal artwork NA (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) #> 6 Mozartsteg bridge NA (4549473 2747624) #> # ℹ 11 more rows #> # #> # Edge data: 16 × 3 #> from to geometry #> #> 1 1 2 (4549504 2747309, 4549003 2747376) #> 2 1 3 (4549504 2747309, 4549589 2747507) #> 3 1 4 (4549504 2747309, 4549387 2747514) #> # ℹ 13 more rows plot(net) plot(mst) par(oldpar)"},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"network-creation-1-0-0","dir":"Changelog","previous_headings":"","what":"Network creation","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"Creating networks directly linestring geometries now implemented new function create_from_spatial_lines(). as_sfnetwork() method sf objects call function geometries linestrings, forward ... arguments . now also allows already subdivide edges locations interior points shared, setting subdivide = TRUE. Creating networks directly point geometries now implemented new function create_from_spatial_points(). as_sfnetwork() method sf objects call function geometries points, forward ... arguments . now many options create spatial networks directly spatial point data. nodes connected can specified providing logical adjacency matrix addition point data. adjacency matrix can also sparse, e.g. output spatial predicate function sf. Furthermore, sfnetworks can create adjacency matrix according specified method. case, need specify name method. Supported options : complete graph, sequence, minimum spanning tree, delaunay triangulation, Gabriel graph, relative nearest neighbor graph, k nearest neighbor graph. See detailed explanation examples. new function play_geometric() can create random geometric networks. new method as_sfnetwork() create dodgr_streetnet objects {dodgr} package directly sfnetwork. internally calls dodgr_to_sfnetwork(). conversion direction, use sfnetwork_to_dodgr(). now also possible convert sfnetwork objects neighbor lists, using new functions nb_to_sfnetwork() sfnetwork_to_nb(). Neighbor lists sparse adjacency matrices can found e.g. spdep package sf package (output spatial predicate functions). Since interpretation weights argument weights = NULL changed (see ), argument length_as_weight sfnetwork() construction function deprecated. Instead, can now set compute_length = TRUE store edge lengths attribute named length. However, attribute anymore automatically recognized edge weights routing functions.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"routing-1-0-0","dir":"Changelog","previous_headings":"","what":"Routing","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"mentioned , interpretation setting weights = NULL changed routing functions. , edge attribute named weight automatically recognized edge weights, just like igraph. Although convenient, proved confusing since tidygraph, setting weights = NULL meaning. always means edge weights used, matter weight attribute present. now decided (since primarily integrating tidygraph sf) follow tidygraph design choice, meaning weights = NULL always means edge weights used. However, routing functions sfnetworks default longer weights = NULL, weights = edge_length(). Hence, geographic length default edge weight routing functions sfnetworks way edge weights can specified routing functions updated better fit tidy data analysis workflows. can now directly provide edge measure functions value weight argument. also allows provide custom edge measure functions, example ones time-dependent. Furthermore, reference column edges table, can now using tidy evaluation, .e. unquoted column names rather quoted ones. dual weighted routing, new dual_weights() function can used. See full overview possible specification formats. way nodes routing functions can specified updated better fit tidy data analysis workflows. can now directly provide node query node measure functions value arguments. Furthermore, reference column nodes table, can now using tidy evaluation, .e. unquoted column names rather quoted ones. See full overview possible specification formats. now possible choose different “routing backends” router argument routing functions. default routing backend igraph, meaning routing functions igraph package called internally. second supported routing backend now dodgr, call routing functions dodgr package instead. conversion happens internally, user can use functions arguments independent routing engine choose. See details. output returned st_network_paths() restructured. Instead tbl_df, function now return sf object, course path stored linestring geometry. also return total cost path column named cost. Columns node_paths edge_paths renamed node_path edge_path, respectively. boolean column path_found specifies requested path found. , path assigned infinite cost empty geometry. New boolean arguments return_cost return_geometry can set FALSE want cost /geometry columns returned. type argument st_network_paths() deprecated. compute shortest paths instead single shortest path, set = TRUE instead. Support computing simple paths dropped. st_network_paths() function now supports one--one k shortest paths routing. implemented new k argument, can set integer higher 1. use_names argument st_network_paths() now default value FALSE. means even nodes name column, encoded integer indices output object. use_names argument now also added st_network_cost(), letting specify want node names used column rownames returned matrix. Also , defaults FALSE. new function st_network_distance() added synonym st_network_cost() edge weights fixed geographic distance. done provide intuitive network-specific alternative sf::st_distance(). new function st_network_travel() now provides interface TSP package solve traveling salesman problems. requires TSP installed. See example. new function st_network_iso() now implements computation isodistance/isochrone polygons around given source node. first computes neighborhood node, draws concave hull around . See example. concave hulls detailed convex hull, .e. ratio smaller 1, GEOS >= 3.11 required.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"morphers-1-0-0","dir":"Changelog","previous_headings":"","what":"Morphers","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"new morpher to_spatial_unique() allows contract nodes equal spatial locations, specifying attributes combined. new morpher to_spatial_mixed() allows mimic mixed network representation (.e. network directed undirected edges) duplicating reversing edges undirected. new morpher to_spatial_reversed() reverses edges, including linestring geometries. Selected edges can protected reversion using protect argument. new morpher to_spatial_implicit() drops edge geometries. summarise_attributes argument appears several morphers renamed attribute_summary, avoid differences UK US spelling. now, summarise_attributes automatically converted attribute_summary, giving soft deprecation warning. to_spatial_subdivision() morpher now argument . set TRUE, edges subdivided interior point (.e. creating one edge per segment), instead interior points shared multiple edges. to_spatial_subdivision() morpher now argument merge_equal. set TRUE, edges subvidived, subdivision points shared multiple edges merged single node. to_spatial_subdivision() moprher now argument protect, allows protect specified edges subdivided. edges protected can specified several ways, e.g. integer index, using edge query functions, referencing column using tidy evaluation. protect argument to_spatial_smooth() morpher now updated fit better tidy data analysis workflows. Nodes protected smoothed can specified way origins destination nodes routing functions, see . require_equal argument to_spatial_smooth() morpher now updated fit better tidy data analysis workflows. Attributes check equality can now specified using tidy selection. means can also use tidy selection helpers dplyr. to_spatial_contracted() morpher now argument compute_centroid. set FALSE, contracted groups nodes centroid new geometry, simply geometry first node group. can improve performance significantly large networks. simplify argument to_spatial_contracted() morpher now TRUE default value. means default contracted network simplified. to_spatial_shortest_paths() morpher now automatically orders nodes edges returned network match order visited path. argument to_spatial_neighborhood() renamed node. now, automatically converted node, giving soft deprecation warning. to_spatial_neighborhood() morpher now internally calls st_network_cost(), forwards ... arguments . to_spatial_neighborhood() morpher now accepts multiple threshold values, returning one network per specified threshold. internal workers morphers dedicated network cleaning now exported well, make possibe perform data cleaning outside tidygraph framework. simplify_network() to_spatial_simple(), subdivide_edges() to_spatial_subdivision(), smooth_pseudo_nodes() to_spatial_smooth(), contract nodes to_spatial_contracted().","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"spatial-grouping-1-0-0","dir":"Changelog","previous_headings":"","what":"Spatial grouping","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"new function group_spatial_dbscan() provides tidy interface dbscan package group nodes spatially using DBSCAN spatial clustering algorithm, based network distances nodes.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"blending-1-0-0","dir":"Changelog","previous_headings":"","what":"Blending","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"st_network_blend() now allows blend points projected location network, setting ignore_duplicates = FALSE. first one added isolated nodes, can merged using new morpher to_spatial_unique().","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"node-specific-functions-1-0-0","dir":"Changelog","previous_headings":"","what":"Node specific functions","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"new centrality function centrality_straightness() allows compute straightness centrality nodes. new node query function node_is_pseudo() node_is_dangling() allow easily query pseudo (nodes one incoming one outgoing edges) dangling (nodes degree centrality 1) nodes. new node predicate function node_is_nearest() defines node nearest node feature given set spatial features.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"edge-specific-functions-1-0-0","dir":"Changelog","previous_headings":"","what":"Edge specific functions","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"new edge measure function edge_segment_count() returns number segments edge. new edge predicate function edge_is_nearest() defines edge nearest edge feature given set spatial features. make_edges_valid() makes edge geometries fit spatial network structure either replacing endpoints nodes referenced columns (preserve_geometries = FALSE), adding unmatched endpoints new nodes network updating columns (preserve_geometries = TRUE). make_edges_directed() turns undirected network directed network updating columns according direction given linestring geometries. internal worker morpher to_spatial_directed(). make_edges_mixed() duplicates reverses edges directed network undirected. internal worker morpher to_spatial_mixed(). make_edges_explicit() adds geometry column spatially implicit edges. internal worker morpher to_spatial_explicit(). make_edges_implicit() drops geometry column spatially explicit edges. internal worker morpher to_spatial_implicit(). make_edges_follow_indices() updates edge geometries undirected networks match node indices specified columns, case swapped.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"other-new-functions-1-0-0","dir":"Changelog","previous_headings":"","what":"Other new functions","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"new function st_network_faces() allows extract faces spatial network sf object polygons geometries. new function st_project_on_network() replaces geometries sf objects projection spatial network. new functions bind_spatial_nodes() bind_spatial_edges() allow bind additional nodes edges network. spatial alternatives tidygraph::bind_nodes() tidygraph::bind_edges(), handle geometry list columns.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"methods-for-sf-1-0-0","dir":"Changelog","previous_headings":"","what":"Methods for sf","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"now sfnetwork method sf::st_segmentize(), allowing add interior points edge geometries fixed intervals. sfnetwork methods sf::st_intersection(), sf::st_difference(), sf::st_crop() now also work expected undirected networks. st_geometry<- method sfnetwork objects now allows replace node geometries set points, edge geometries set lines. Internally, network structure kept valid replacing endpoints edge geometries (replacing nodes), adding unmatched edge endpoints new nodes network (replacing edges). sf::st_join() method sfnetwork objects now allows multiple matches node. case, node duplicated per additional match, duplicates added isolated nodes resulting network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"upkeep-with-tidygraph-1-0-0","dir":"Changelog","previous_headings":"","what":"Upkeep with tidygraph","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"Functions sfnetworks now work well new concept focused graphs, recently implemented tidygraph. See details. now sfnetwork method tidygraph::reroute(). However, want reverse edges, recommend use morpher to_spatial_reversed() instead, reroute replace endpoints edge geometries, reverse complete linestring geometries. tidygraph verbs morph(), unmorph(), crystallize(), convert() now re-exported sfnetworks, needed anymore load tidygraph explicitly order use spatial morphers. Furthermore, utility function tidygraph::with_graph() now re-exported.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"plotting-1-0-0","dir":"Changelog","previous_headings":"","what":"Plotting","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"plot() method sfnetwork objects now allows different style settings nodes edges, using new node_args edge_args arguments. plot() method sfnetwork objects now allows plot multiple networks top .","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"data-extraction-utilities-1-0-0","dir":"Changelog","previous_headings":"","what":"Data extraction utilities","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"functions node_data() edge_data() extract node edge table, respectively. Nodes always extracted sf object. Edges extracted sf object spatially explicit, regular tbl_df spatially implicit. functions node_ids() edge_ids() extract indices nodes edges, respectively. indices correspond rownumbers node edge tables. functions nearest_nodes() nearest_edges() return respectively nearest nodes nearest edges set spatial features. functions nearest_node_ids() nearest_edge_ids() return respectively indices nearest nodes nearest edges set spatial features. indices correspond rownumbers node edge tables. functions n_nodes() n_edges() return respectively number nodes edges network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"other-utilities-1-0-0","dir":"Changelog","previous_headings":"","what":"Other utilities","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"Added is_sfnetwork() alias .sfnetwork(). new function validate_network() allows validate spatial network structure sfnetwork object. new function wrap_igraph() allows wrap function igraph returns network, make return sfnetwork object instead igraph object. functions st_duplicated(), st_match() st_round() added spatial variations common base R functions, respectively determining spatial duplicates, geometry matching, coordinate rounding.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"other-updates-1-0-0","dir":"Changelog","previous_headings":"","what":"Other updates","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"determining spatial equality nodes, sfnetworks now default uses 12-digit precision. gives considerable performance improvement especially large networks. Precision can changed explicitly setting coordinate precision using sf::st_set_precision(). messages, warnings errors sfnetworks now raised using cli rlang packages.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"bug-fixes-1-0-0","dir":"Changelog","previous_headings":"","what":"Bug fixes","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"print method now works correctly aligning updates tidygraph. morpher to_spatial_contracted() now correctly handles group indices ordered. plot() method sfnetwork objects now correctly plots networks spatially implicit edges active. st_network_bbox() now also computes bounding boxes networks spatially implicit edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"dependencies-1-0-0","dir":"Changelog","previous_headings":"","what":"Dependencies","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"minimum required version sf now 1.0-11 minimum required version tidygraph now 1.3.0 minimum required version igraph now 2.1.0 crayon package dependency anymore. Base R packages {methods} {stats} added new dependencies. Additional packages cli, lifecycle, pillar tidyselect added new dependencies.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v064","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.6.4","title":"sfnetworks v0.6.4","text":"CRAN release: 2024-04-09","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"new-features-0-6-4","dir":"Changelog","previous_headings":"","what":"New features","title":"sfnetworks v0.6.4","text":"sfnetwork() construction function now argument message can set FALSE network validity checks print informational messages console. Refs #261.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"maintenance-0-6-4","dir":"Changelog","previous_headings":"","what":"Maintenance","title":"sfnetworks v0.6.4","text":"Code documentation updated needed align changes base R /package dependencies. changes program logic behavior.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v063","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.6.3","title":"sfnetworks v0.6.3","text":"CRAN release: 2023-03-22","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"bug-fixes-0-6-3","dir":"Changelog","previous_headings":"","what":"Bug fixes","title":"sfnetworks v0.6.3","text":"Argument names sfnetwork S3 methods sf::st_geometry(), sf::st_bbox(), sf::st_m_range() sf::st_set_precision() updated consistent corresponding generic functions sf. Arguments active ... removed sfnetwork S3 method sf::st_precision() consistent corresponding generic function sf. Argument active removed sfnetwork S3 method sf::st_crs() consistent -mentioned change regarding sf::st_precision() (since CRS precision can differ nodes edges).","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v062","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.6.2","title":"sfnetworks v0.6.2","text":"CRAN release: 2023-02-26","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"bug-fixes-0-6-2","dir":"Changelog","previous_headings":"","what":"Bug fixes","title":"sfnetworks v0.6.2","text":"to_spatial_contracted() morpher now correctly handles cases undirected networks loop edges created contraction. Refs #237.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"refactoring-0-6-2","dir":"Changelog","previous_headings":"","what":"Refactoring","title":"sfnetworks v0.6.2","text":"to_spatial_contracted() morpher now directly returns original network none contraction groups contain one node.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"other-0-6-2","dir":"Changelog","previous_headings":"","what":"Other","title":"sfnetworks v0.6.2","text":"Umbrella packages tidyverse spatstat longer suggested packages. individual members packages now suggested packages. Updated unit tests.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v061","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.6.1","title":"sfnetworks v0.6.1","text":"CRAN release: 2022-10-27","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"bug-fixes-0-6-1","dir":"Changelog","previous_headings":"","what":"Bug fixes","title":"sfnetworks v0.6.1","text":"Unit tests test_join.R now successfully run also R-devel.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"refactoring-0-6-1","dir":"Changelog","previous_headings":"","what":"Refactoring","title":"sfnetworks v0.6.1","text":"Updated plot algorithm faster efficient. Refs #226.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v060-coerde","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.6.0 “Coerde”","title":"sfnetworks v0.6.0 “Coerde”","text":"CRAN release: 2022-08-19","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"new-features-0-6-0","dir":"Changelog","previous_headings":"","what":"New features","title":"sfnetworks v0.6.0 “Coerde”","text":"Argument summarise_attributes added summarise attribute values concatenated edges. Refs #120. Argument require_equal added specify attributes checked equality removing pseudo node. Refs #124. Argument protect added specify nodes never removed, even pseudo node. Refs #177. Concatenated edges smoothing now allowed cross . Refs #117. Duplicated nodes now accepted argument. Refs #183. Cost matrix output now contains units. Refs #119. Argument direction added specify outbound, inbound edges considered. replaces argument mode igraph::distances(). default “”, “”. undirected networks argument ignored. Edge measure function edge_azimuth() gained argument degrees can set TRUE return angles degrees instead radians. default st_network_paths() now encodes nodes name, whenever name attribute present nodes table. can disabled setting use_names = FALSE. Refs #154. Functions sf::st_precision() sf::st_set_precision() now method sfnetwork objects, coordinate precision can queried set. Refs #209. Functions sf::st_intersection() sf::st_difference() now method sfnetwork objects, networks can spatially clipped. method sf::st_crop() now uses workflow. functions work yet edges undirected networks. Refs #133. Function sf::st_drop_geometry() now generic therefore got sfnetwork method. Several sf functions got sfnetwork method, merely consistent type functions provide method . functions mutate geometry column sf object way break valid spatial network structure supported. Methods sf::st_coordinates(), sf::st_bbox() sf::st_crs() gained active argument information can extracted network element without first activating . Refs #215.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"bug-fixes-0-6-0","dir":"Changelog","previous_headings":"","what":"Bug fixes","title":"sfnetworks v0.6.0 “Coerde”","text":"Rd files contain code anymore incompatible HTML5. Refs #221. Print methods now return x invisibly. Refs #217.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"refactoring-0-6-0","dir":"Changelog","previous_headings":"","what":"Refactoring","title":"sfnetworks v0.6.0 “Coerde”","text":"Error messages edge measure query functions applied network active nodes, node measure query functions applied network active edges, now informative. Refs #216. Calculating straight-line distances edges now performant. Refs #180. Edge measure function edge_circuity() return units objects anymore, since circuity unitless.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"community-0-6-0","dir":"Changelog","previous_headings":"","what":"Community","title":"sfnetworks v0.6.0 “Coerde”","text":"Vignettes updated showcase new features. Code conduct updated according newer template. Contributing guidelines extended templates commit messages. Master branch renamed main, protected directed pushes.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v055","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.5.5","title":"sfnetworks v0.5.5","text":"CRAN release: 2022-02-16 Adjusted code used check version PROJ attach. particular, new approach tests sf::sf_extSoftVersion()[\"proj.4\"] since sf::sf_extSoftVersion()[\"PROJ\"] might defined sf < 1.0. Refs #198 #200. Adjusted one vignettes following changes dplyr 1.0.8. Ref #202. Thanks @romainfrancois. Removed conflicting URL package documentation spatial_edge_measures","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v054","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.5.4","title":"sfnetworks v0.5.4","text":"CRAN release: 2021-12-17 startup message included urge users PROJ <= 6 recreate CRS Roxel dataset. Refs #190 fixed #193. Example using GraphML vignette 1 removed provisionally address #194.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v053","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.5.3","title":"sfnetworks v0.5.3","text":"CRAN release: 2021-11-26 Addition n_active n_inactive arguments print method sfnetwork object. arguments define many rows printed respectively active inactive network element. values arguments can also set globally running e.g. options(sfn_max_print_active = 1, sfn_max_print_inactive = 2). Refs #157 example dataset Roxel updated comply recent updates way CRS specified sf object. Refs #167 GitHub Actions workflows updated comply new developments. Vignette file names updated appear correct order CRAN. Refs #162 Example section plot method sfnetwork objects now includes example add graticules axes. Refs #159","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v052","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.5.2","title":"sfnetworks v0.5.2","text":"CRAN release: 2021-05-13 Compatibility s2 adding s2::as_s2_geography() method sfnetwork objects. new version sf, s2 package used geometric operations involving longitude-latitude coordinates, see . setting length_as_weight = TRUE sfnetwork construction function, added weight column now preserves specification units. st_network_blend() now internally uses sf::st_cast() instead sfheaders::sfc_cast() avoid errors CRS specifications. Extended documentation shortest paths functions. Clear mention vignettes tidygraph behavior regarding weight attribute settings sometimes differing igraph.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v051","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.5.1","title":"sfnetworks v0.5.1","text":"CRAN release: 2021-03-28 Compatibility spatstat v2, now splitted multiple sub-packages. See details. sfnetworks, affected functions as_sfnetwork.linnet(), as_sfnetwork.psp() .linnet.sfnetwork(). Using functions now requires spatstat >= 2.0.0 sf >= 0.9.8. Usage match checking coordinate equality replaced new st_match function specifically designed task. fixes bugs related numeric approximations detailed coordinates. See #130 now clearly documented using sf::st_reverse() reverse edge linestrings possible GEOS versions >= 3.7.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v050-nienberge","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.5.0 “Nienberge”","title":"sfnetworks v0.5.0 “Nienberge”","text":"CRAN release: 2021-03-11 Addition to_spatial_contracted() morpher, contract groups nodes based given grouping variables. Refs #104 Addition to_spatial_neighborhood() morpher, limit network neighborhood given node, based given cost threshold. Refs #90 New implementation st_network_blend(), faster reliable. sort argument deprecated, since returned network now always sorted. Addition summarise_attributes argument to_spatial_simple() morpher, allowing specify per-attribute basis attribute values merged multiple edges inferred original ones. Refs #113. argument also part new to_spatial_contracted() morpher, can used specify per-attribute basis attribute values contracted groups nodes inferred original ones. argument remove_parallels to_spatial_simple() morpher renamed remove_multiples better fit naming conventions igraph. argument store_orig_data to_spatial_smooth() morpher renamed store_original_data better interpretable. argument also added morphers to_spatial_simple() to_spatial_contracted(), allowing store original node edge data .orig_data column, matching design standards tidygraph. Addition Inf_as_NaN argument st_network_cost(), store cost values paths unconnected edges NaN instead Inf. default value argument FALSE. Refs #111 default Inf_as_NaN argument edge_circuity() changed TRUE FALSE, better fit change mentioned , make sure changes R defaults made without user explicitly specifying . Whenever multiple matches spatially joining information nodes network sf::st_join(), information first match now joined. , used throw error. Refs #108 Removal morphed_sfnetwork method sf::st_geometry<-, since geometries replaced morphed state. warning ‘.. assumes attributes constant geometries’ now raised attribute-geometry relationships set ‘constant’. Refs #123 attribute-geometry relationships edge attributes now preserved network construction. Fixes #123 st_network_blend() now correctly blends points close network. Fixes #98 st_network_blend() now preserves directedness input network. Fixes #127 st_network_blend() now runs even network contains edges length 0. Fixes #125 sfnetwork method sf::st_crop() now correctly updates nodes table cropping edges. Fixes #109 to_spatial_smooth() now returns original network pseudo nodes present. Fixes #112 to_spatial_subdivision() now returns original network locations subdivision. to_spatial_subdivision() now returns correct node indices undirected networks. Several new examples applications added vignettes.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v041","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.4.1","title":"sfnetworks v0.4.1","text":"Addition edge measure function edge_azimuth(), calculate azimuth (.e. bearing) edges. Refs #107 Addition to_spatial_transformed() morpher, temporarily transform sfnetwork different CRS. Addition sfnetwork methods linnet objects, enhance interoperability sfnetworks spatstat package spatial point patterns linear networks. Addition Inf_as_NaN argument edge_circuity() function, store circuity values loop edges NaN instead Inf. default value argument TRUE. Addition new argument type, lets set type paths calculation performed. calculate shortest paths nodes, now set type = 'all_shortest' instead = TRUE. latter argument deprecated. Besides shortest paths, now also possibility calculate simple paths nodes, setting type = 'all_simple'. aware computation time gets high providing lot ‘’ nodes, network large dense. Refs #105 Whenever weights = NULL column named ‘weight’ edges table, geographic edge length calculated internally used weights shortest path calculation. , paths calculated without edge weights case. Refs #106 Whenever given ‘’ /‘’ nodes contain NA values /empty point geometries, igraph behaviour now replicated throwing error. , values simply ignored. Performance improvement to_spatial_smooth() morpher. result store original edge data anymore ‘.orig_data’ column. Instead, non-merged edges keep attributes, merged edges loose attributes. ‘.orig_data’ column can still added setting store_orig_data = TRUE, default. st_network_paths() now correctly handles cases unexisting column passed weights argument, throwing error. Fixes #99 sfnetwork method sf::st_join() now correctly handles inner joins (.e. joins left = FALSE). Addition extra examples routing spatial morphers vignettes. Test coverage increased +/- 86%.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v040-hiltrup","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.4.0 “Hiltrup”","title":"sfnetworks v0.4.0 “Hiltrup”","text":"Function st_shortest_paths() st_all_shortest_paths() now merged single function st_network_paths(). default call igraph::shortest_paths() internally. Setting = TRUE make call igraph::all_shortest_paths() instead. output format st_network_paths() function different predecessors. returns tibble instead list, fit better tidyverse workflows. See #77 snap argument removed shortest paths related functions, now always snap geospatial points provides locations nearest node network calculating paths. keep argument removed to_spatial_simple() morpher. now recommended first sort data dplyr::arrange() calling morpher. spatial morpher to_spatial_coordinates() deprecated. Use new node coordinate query functions instead. spatial morpher to_spatial_dense_graph() deprecated. new morpher to_spatial_subdivision(), slightly different functionality, added instead. spatial morpher to_spatial_implicit_edges() deprecated. Use sf::st_set_geometry() instead, activated edges value NULL. Functions st_network_distance(), edge_straight_length() to_spatial_explicit_edges() renamed respectively st_network_cost(), edge_displacement() to_spatial_explicit(), either reflects purpose better fits better naming conventions within package. Function arguments named graph renamed x, consistency across package. construction function sfnetwork() now argument length_as_weight , set TRUE, add lengths edges weight attribute edges data. Refs #65 now as_sfnetwork() method sfc objects. Refs #41 existing st_network_* functions sfnetwork now generic, can easily modified extensions sfnetwork objects. Refs #80 to_spatial_explicit_edges() morpher now accepts arguments forwarded directly sf::st_as_sf(). Refs #83 Functions split edges now give warning attributes assumed constant. Refs #84 edge_length() function can now also applied spatially implicit edges. sfnetwork methods sf::st_as_sf(), sf::st_geometry() sf::st_agr() now argument active directly retrieve information network element without activating . Use st_as_sf(x, active = \"nodes\"), et cetera. Character encoded node names can now provided locations shortest path functions. new function st_network_blend() implements process called ‘blending points network’. functions accepts network set points. point p set given points, finds projection p* p network, splits edges network location p*, finally adds p* along attributes p node network. Refs #27 #54 new function st_network_join() network specific join two sfnetworks. combines spatial full join nodes data bind_rows operation edges data, updates indices edges accordingly. Refs #22 new function st_network_bbox() calculates bounding box whole network combining bounding boxes nodes edges. new spatial morpher to_spatial_subdivision() subdivides edges locations interior point shared either another interior point endpoint another edge. Refs #73 new spatial morpher to_spatial_smooth() iteratively removes pseudo-nodes network. Refs #70 Several spatial predicate functions implemented node edge query functions, interpret spatial relations network elements geospatial features directly inside tidy filter mutate calls. Refs #60 Node coordinate query functions node_X(), node_Y(), node_Z() node_M() implemented query specific coordinate values nodes. now ggplot2::autoplot() method sfnetworks, allowing easily plot sfnetwork ggplot2 object. Refs #86 now print method morphed sfnetworks. Refs #88 now morphed sfnetworks method sf::st_geometry<-(), sf::st_join(), sf::st_filter() sf::st_crop(). Refs #85 Networks can now constructed providing nodes, edges. Fixes #81 print method sfnetwork objects now correctly handles networks without edges well completely empty networks. Fixes #69 #89 shortest path functions now correctly handle empty geometries. Fixes #87 Examples added function documentations. Refs #45 existing vignettes reorganized, combined lot new information five new vignettes. Refs #92 Together documentation improvements, several new units tests brought test coverage +/- 80%. internal code base completely restructured, performant easier read, debug extend.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v031","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.3.1","title":"sfnetworks v0.3.1","text":"as_sfnetwork() now handles circular linestrings. Fixes #59 Addition “node_key” argument construction functions, line recent update tidygraph. Refs #53 Better integration Z M coordinates adding coordinate columns calling spatial morpher to_spatial_coordinates(). Refs #62 Improved pkgdown structure. Refs #44 First implementation continuous benchmarking. Refs #6","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v030-gievenbeck","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.3.0 “Gievenbeck”","title":"sfnetworks v0.3.0 “Gievenbeck”","text":"Spatial wrappers around igraph shortest paths functions. Refs #28 Various spatial morpher functions. Refs #19 Various edge measure algorithms, including edge circuity. Refs #51 Support sfNetwork stplanr Support linnet psp spatstat Preserving sf attributes nodes edges inside sfnetwork object. Refs #24 Construction checks run needed, adding force argument skip validity tests. Allowing choose spatially explicit implicit edges construction, adding edges_as_lines argument. Refs #47 Using st_boundary find line endpoints increases performance sfnetwork construction sf objects. Refs #30 Cleaning sf methods sfnetwork objects. Relying internally stored attributes rather first extracting sf objects. Option plot without making edges explicit. Improved function documentation. additional vignette “Extensions” included.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v020-neutor","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.2.0 “Neutor”","title":"sfnetworks v0.2.0 “Neutor”","text":"Major stable release Basic construction function initial foreign objects conversion. Refs #9 Methods sf functions Roxel data lazyData Internal checks construction ghactions sf pkgdown Basic print plot methods First vignette Code conduct, contribution license files","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v010-altstadt","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.1.0 “Altstadt”","title":"sfnetworks v0.1.0 “Altstadt”","text":"Initial release","code":""}] +[{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"our-pledge","dir":"","previous_headings":"","what":"Our Pledge","title":"Contributor Covenant Code of Conduct","text":"members, contributors, leaders pledge make participation community harassment-free experience everyone, regardless age, body size, visible invisible disability, ethnicity, sex characteristics, gender identity expression, level experience, education, socio-economic status, nationality, personal appearance, race, caste, color, religion, sexual identity orientation. pledge act interact ways contribute open, welcoming, diverse, inclusive, healthy community.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"our-standards","dir":"","previous_headings":"","what":"Our Standards","title":"Contributor Covenant Code of Conduct","text":"Examples behavior contributes positive environment community include: Demonstrating empathy kindness toward people respectful differing opinions, viewpoints, experiences Giving gracefully accepting constructive feedback Accepting responsibility apologizing affected mistakes, learning experience Focusing best just us individuals, overall community Examples unacceptable behavior include: use sexualized language imagery, sexual attention advances kind Trolling, insulting derogatory comments, personal political attacks Public private harassment Publishing others’ private information, physical email address, without explicit permission conduct reasonably considered inappropriate professional setting","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"enforcement-responsibilities","dir":"","previous_headings":"","what":"Enforcement Responsibilities","title":"Contributor Covenant Code of Conduct","text":"Community leaders responsible clarifying enforcing standards acceptable behavior take appropriate fair corrective action response behavior deem inappropriate, threatening, offensive, harmful. Community leaders right responsibility remove, edit, reject comments, commits, code, wiki edits, issues, contributions aligned Code Conduct, communicate reasons moderation decisions appropriate.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"scope","dir":"","previous_headings":"","what":"Scope","title":"Contributor Covenant Code of Conduct","text":"Code Conduct applies within community spaces, also applies individual officially representing community public spaces. Examples representing community include using official e-mail address, posting via official social media account, acting appointed representative online offline event.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"enforcement","dir":"","previous_headings":"","what":"Enforcement","title":"Contributor Covenant Code of Conduct","text":"Instances abusive, harassing, otherwise unacceptable behavior may reported community leaders responsible enforcement lucas.vandermeer@sbg.ac.. complaints reviewed investigated promptly fairly. community leaders obligated respect privacy security reporter incident.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"enforcement-guidelines","dir":"","previous_headings":"","what":"Enforcement Guidelines","title":"Contributor Covenant Code of Conduct","text":"Community leaders follow Community Impact Guidelines determining consequences action deem violation Code Conduct:","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"id_1-correction","dir":"","previous_headings":"Enforcement Guidelines","what":"1. Correction","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Use inappropriate language behavior deemed unprofessional unwelcome community. Consequence: private, written warning community leaders, providing clarity around nature violation explanation behavior inappropriate. public apology may requested.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"id_2-warning","dir":"","previous_headings":"Enforcement Guidelines","what":"2. Warning","title":"Contributor Covenant Code of Conduct","text":"Community Impact: violation single incident series actions. Consequence: warning consequences continued behavior. interaction people involved, including unsolicited interaction enforcing Code Conduct, specified period time. includes avoiding interactions community spaces well external channels like social media. Violating terms may lead temporary permanent ban.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"id_3-temporary-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"3. Temporary Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: serious violation community standards, including sustained inappropriate behavior. Consequence: temporary ban sort interaction public communication community specified period time. public private interaction people involved, including unsolicited interaction enforcing Code Conduct, allowed period. Violating terms may lead permanent ban.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"id_4-permanent-ban","dir":"","previous_headings":"Enforcement Guidelines","what":"4. Permanent Ban","title":"Contributor Covenant Code of Conduct","text":"Community Impact: Demonstrating pattern violation community standards, including sustained inappropriate behavior, harassment individual, aggression toward disparagement classes individuals. Consequence: permanent ban sort public interaction within community.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CODE_OF_CONDUCT.html","id":"attribution","dir":"","previous_headings":"","what":"Attribution","title":"Contributor Covenant Code of Conduct","text":"Code Conduct adapted Contributor Covenant, version 2.1, available https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. Community Impact Guidelines inspired Mozilla’s code conduct enforcement ladder. answers common questions code conduct, see FAQ https://www.contributor-covenant.org/faq. Translations available https://www.contributor-covenant.org/translations.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CONTRIBUTING.html","id":null,"dir":"","previous_headings":"","what":"How to contribute?","title":"How to contribute?","text":"look much forward contributions package. can done several ways: Create pull request specific feature implementation bug fix. Please direct develop branch. Open issue issue tracker request specific feature report bug. Please use respective issue templates . Share general ideas package starting new discussion discussion room, using ideas category. Share experiences using package work starting new discussion discussion room, using show tell category. Sharing help package developers see package used improve things accordingly, users learn package get inspiration work! Ask questions starting new discussion discussion room, using Q&category, StackOverflow sfnetwork tag. Asking questions openly helps users struggle problems!","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CONTRIBUTING.html","id":"code-style","dir":"","previous_headings":"","what":"Code style","title":"How to contribute?","text":"strive follow tidyverse styleguide source code package. exception assignment operator: use = instead <- (see reasons ).","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/CONTRIBUTING.html","id":"structured-commit-messages","dir":"","previous_headings":"","what":"Structured commit messages","title":"How to contribute?","text":"commiting changes git commit try use structured commit messages, adapted https://www.conventionalcommits.org/. first line commit message following format: summary short (preferably < 50 characters), starting upper case, written present tense. commit references specific issue, include Refs # summary. issue bug report, may also use Fix # issue gets closed automatically. type one defined types listed . feel artistic, can end commit message emoji belonging type 😎. feat: Implementation new feature. :gift: 🎁 fix: bug fix. :wrench: 🔧 style: Changes code formatting. change program logic. :art: 🎨 refactor: Changes existing functionality change behaviour. :construction: 🚧 breaking: Changes existing functionality backwards compatible. :warning: ⚠️ docs: Adding, removing updating user documentation. :books: 📚 logs: Adding, removing updating log messages. :sound: 🔉 test: Adding, removing updating tests. changes user code. :test_tube: 🧪 cicd: Adding, removing updating CI/CD workflows. changes user code. :robot: 🤖 deps: Adding, removing updating dependencies. :couple: 👫 release: Preparing release, e.g. updating version numbers. :bookmark: 🔖 repo: Changes repository involve code/documentation, e.g. adding templates community files. :package: 📦 Example commit messages :","code":": git commit -m 'feat: Add bar parameter to foo(). Refs #10 :gift:' git commit -m 'fix: Include type checking in foo(). Fix #12 :wrench:'"},{"path":"https://luukvdmeer.github.io/sfnetworks/CONTRIBUTING.html","id":"code-of-conduct","dir":"","previous_headings":"","what":"Code of conduct","title":"How to contribute?","text":"project released Contributor Code Conduct. participating project agree abide terms.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":null,"dir":"","previous_headings":"","what":"Apache License","title":"Apache License","text":"Version 2.0, January 2004 ","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_1-definitions","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"1. Definitions","title":"Apache License","text":"“License” shall mean terms conditions use, reproduction, distribution defined Sections 1 9 document. “Licensor” shall mean copyright owner entity authorized copyright owner granting License. “Legal Entity” shall mean union acting entity entities control, controlled , common control entity. purposes definition, “control” means () power, direct indirect, cause direction management entity, whether contract otherwise, (ii) ownership fifty percent (50%) outstanding shares, (iii) beneficial ownership entity. “” (“”) shall mean individual Legal Entity exercising permissions granted License. “Source” form shall mean preferred form making modifications, including limited software source code, documentation source, configuration files. “Object” form shall mean form resulting mechanical transformation translation Source form, including limited compiled object code, generated documentation, conversions media types. “Work” shall mean work authorship, whether Source Object form, made available License, indicated copyright notice included attached work (example provided Appendix ). “Derivative Works” shall mean work, whether Source Object form, based (derived ) Work editorial revisions, annotations, elaborations, modifications represent, whole, original work authorship. purposes License, Derivative Works shall include works remain separable , merely link (bind name) interfaces , Work Derivative Works thereof. “Contribution” shall mean work authorship, including original version Work modifications additions Work Derivative Works thereof, intentionally submitted Licensor inclusion Work copyright owner individual Legal Entity authorized submit behalf copyright owner. purposes definition, “submitted” means form electronic, verbal, written communication sent Licensor representatives, including limited communication electronic mailing lists, source code control systems, issue tracking systems managed , behalf , Licensor purpose discussing improving Work, excluding communication conspicuously marked otherwise designated writing copyright owner “Contribution.” “Contributor” shall mean Licensor individual Legal Entity behalf Contribution received Licensor subsequently incorporated within Work.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_2-grant-of-copyright-license","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"2. Grant of Copyright License","title":"Apache License","text":"Subject terms conditions License, Contributor hereby grants perpetual, worldwide, non-exclusive, -charge, royalty-free, irrevocable copyright license reproduce, prepare Derivative Works , publicly display, publicly perform, sublicense, distribute Work Derivative Works Source Object form.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_3-grant-of-patent-license","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"3. Grant of Patent License","title":"Apache License","text":"Subject terms conditions License, Contributor hereby grants perpetual, worldwide, non-exclusive, -charge, royalty-free, irrevocable (except stated section) patent license make, made, use, offer sell, sell, import, otherwise transfer Work, license applies patent claims licensable Contributor necessarily infringed Contribution(s) alone combination Contribution(s) Work Contribution(s) submitted. institute patent litigation entity (including cross-claim counterclaim lawsuit) alleging Work Contribution incorporated within Work constitutes direct contributory patent infringement, patent licenses granted License Work shall terminate date litigation filed.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_4-redistribution","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"4. Redistribution","title":"Apache License","text":"may reproduce distribute copies Work Derivative Works thereof medium, without modifications, Source Object form, provided meet following conditions: () must give recipients Work Derivative Works copy License; (b) must cause modified files carry prominent notices stating changed files; (c) must retain, Source form Derivative Works distribute, copyright, patent, trademark, attribution notices Source form Work, excluding notices pertain part Derivative Works; (d) Work includes “NOTICE” text file part distribution, Derivative Works distribute must include readable copy attribution notices contained within NOTICE file, excluding notices pertain part Derivative Works, least one following places: within NOTICE text file distributed part Derivative Works; within Source form documentation, provided along Derivative Works; , within display generated Derivative Works, wherever third-party notices normally appear. contents NOTICE file informational purposes modify License. may add attribution notices within Derivative Works distribute, alongside addendum NOTICE text Work, provided additional attribution notices construed modifying License. may add copyright statement modifications may provide additional different license terms conditions use, reproduction, distribution modifications, Derivative Works whole, provided use, reproduction, distribution Work otherwise complies conditions stated License.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_5-submission-of-contributions","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"5. Submission of Contributions","title":"Apache License","text":"Unless explicitly state otherwise, Contribution intentionally submitted inclusion Work Licensor shall terms conditions License, without additional terms conditions. Notwithstanding , nothing herein shall supersede modify terms separate license agreement may executed Licensor regarding Contributions.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_6-trademarks","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"6. Trademarks","title":"Apache License","text":"License grant permission use trade names, trademarks, service marks, product names Licensor, except required reasonable customary use describing origin Work reproducing content NOTICE file.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_7-disclaimer-of-warranty","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"7. Disclaimer of Warranty","title":"Apache License","text":"Unless required applicable law agreed writing, Licensor provides Work (Contributor provides Contributions) “” BASIS, WITHOUT WARRANTIES CONDITIONS KIND, either express implied, including, without limitation, warranties conditions TITLE, NON-INFRINGEMENT, MERCHANTABILITY, FITNESS PARTICULAR PURPOSE. solely responsible determining appropriateness using redistributing Work assume risks associated exercise permissions License.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_8-limitation-of-liability","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"8. Limitation of Liability","title":"Apache License","text":"event legal theory, whether tort (including negligence), contract, otherwise, unless required applicable law (deliberate grossly negligent acts) agreed writing, shall Contributor liable damages, including direct, indirect, special, incidental, consequential damages character arising result License use inability use Work (including limited damages loss goodwill, work stoppage, computer failure malfunction, commercial damages losses), even Contributor advised possibility damages.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"id_9-accepting-warranty-or-additional-liability","dir":"","previous_headings":"Terms and Conditions for use, reproduction, and distribution","what":"9. Accepting Warranty or Additional Liability","title":"Apache License","text":"redistributing Work Derivative Works thereof, may choose offer, charge fee , acceptance support, warranty, indemnity, liability obligations /rights consistent License. However, accepting obligations, may act behalf sole responsibility, behalf Contributor, agree indemnify, defend, hold Contributor harmless liability incurred , claims asserted , Contributor reason accepting warranty additional liability. END TERMS CONDITIONS","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/LICENSE.html","id":"appendix-how-to-apply-the-apache-license-to-your-work","dir":"","previous_headings":"","what":"APPENDIX: How to apply the Apache License to your work","title":"Apache License","text":"apply Apache License work, attach following boilerplate notice, fields enclosed brackets [] replaced identifying information. (Don’t include brackets!) text enclosed appropriate comment syntax file format. also recommend file class name description purpose included “printed page” copyright notice easier identification within third-party archives.","code":"Copyright 2020 sfnetworks authors Licensed under the Apache License, Version 2.0 (the \"License\"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License."},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"rationale","dir":"Articles","previous_headings":"","what":"Rationale","title":"Introduction to sfnetworks","text":"R good packages respectively geospatial analysis standard network analysis: sf package brings simple features standard R provides interface low-level geospatial system libraries GDAL, GEOS, s2, allowing represent analyze spatial vector data points, lines polygons. tidygraph package provides tidy interface large network analysis library igraph, written C also R API. packages great purposes. However, sf know networks, tidygraph know space. combining forces, sfnetworks enables integrated workflows connecting network analysis spatial analysis. addition, offers functions specific spatial network analysis, found either two “parent packages”. , often utilizes additional building blocks within R world.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"representing-spatial-networks","dir":"Articles","previous_headings":"","what":"Representing spatial networks","title":"Introduction to sfnetworks","text":"Spatial networks sfnetworks represented objects class sfnetwork. objects inherit tbl_graph class tidygraph, turn inherit igraph class igraph. means core designed store graph structures. However, thanks design tidygraph, look like collection two flat tables: one nodes, one edges. tidygraph tables can treated tibbles, sfnetworks sf data frames list column containing geometry feature. sfnetworks, edges can either directed (default) undirected. Mixed networks contain types edges, e.g. road networks oneway streets, can represented duplicating reversing edges can traveled ways. nodes spatial networks need explicitly store geometries, edges always required. edges straight lines, spatial embedding can also inferred spatial locations nodes connect. sfnetworks refer two approaches spatially explicit edges spatially implicit edges, respectively. details representation spatial networks sfnetwork class can found vignette Creating representing spatial networks. many different ways create sfnetwork object, explained detail vignette Creating representing spatial networks. commonly start set spatial features, stored object class sf. features linestrings, considered edges network, nodes created endpoints. multiple linestrings share endpoint, becomes single node network, hence, edges adjacent. features points, considered nodes network, connected edges according given adjacency matrix. adjacency matrix can also created internally according specified method.","code":"net = as_sfnetwork(roxel) net #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows plot(net) net = as_sfnetwork(mozart, connections = \"gabriel\", directed = FALSE) net #> # A sfnetwork: 17 nodes and 25 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 4 (active) #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> 4 Mozart Denkmal artwork NA (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) #> 6 Mozartsteg bridge NA (4549473 2747624) #> # ℹ 11 more rows #> # #> # Edge data: 25 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 1 4 (4549504 2747309, 4549387 2747514) #> 3 2 4 (4549003 2747376, 4549387 2747514) #> # ℹ 22 more rows plot(net)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"analyzing-spatial-networks","dir":"Articles","previous_headings":"","what":"Analyzing spatial networks","title":"Introduction to sfnetworks","text":"Thanks design sf tidygraph, spatial network analysis sfnetworks can fitted seamlessly tidy data analysis workflows using tidyverse family packages. Since sfnetwork object can treated collection two tables, rather one, just need specify want apply function. , tidygraph invented activate() verb, allowing set either nodes edges target analysis. done , can apply favorite tidyverse verb just ’re used . can see activation network element also changes order printed. Obviously network just list two distinct elements. Nodes edges related . Therefore, operations applied nodes may also affect edges, vice versa. good example filtering. Whenever nodes removed network, edges terminating nodes removed . behavior symmetric: removing edges, endpoints edges remain, even endpoint edge. definition edges can never exist without nodes ends, nodes can peacefully exist isolation. Another consequence working relational data operations defined single tables applicable networks. example, common groupby-apply-combine workflows supported, since break relational structure. cases, however, can always extract active element network either sf object tibble, proceed analysis single table. allow performing common network analysis tasks, sfnetworks builds upon tidygraph. Since sfnetwork objects inherit tbl_graph class, analytical functions tidygraph can directly used. lot functions available, tidy wrappers around functions igraph library. complete overview, check tidygraph documentation. important note case spatial networks often makes sense use geographic length edge weight. Since tidygraph know space, never set automatically, explicitly specify every time call function can consider edge weights. Read specifying edge weights vignette Routing spatial networks. large set functions tidygraph dedicated computation quantitative measures nodes, edges, network whole. known centrality measures, define importance node network. names implemented centrality measure functions formatted centrality_*. implemented measure functions names formatted node_* (node measures) edge_* (edge measures) graph_* (network measures). special group measure functions logical measures, return either TRUE FALSE, indicating node, edge network specified type. None functions meant called directly, used inside tidyverse-verbs dplyr::mutate() dplyr::filter(), analyzed network know thus needed input function. tidygraph::with_graph() can used evaluate measure context specific network, outside tidyverse framework. Another set functions tidygraph deals community detection networks. functions group nodes edges based clustering algorithm. names formatted group_*, always return vector group indices, one feature. implemented algorithms try create groups nodes number edges within groups relatively high compared number edges groups, example . note algorithms generally designed account spatial factors, may limited use working spatial networks. Finally, tidygraph introduced new set network analysis functions call morphers. Morphers change structure input graph, example subsetting splitting , combining multiple features one, converting nodes edges vice versa. different struture needed computations, can set temporarily providing morphers subsequently tidygraph::morph() tidygraph::unmorph() verbs. different structure meant last, morpher can provided tidygraph::convert() verb instead. example convert network minimum spanning tree, contains minimum set edges need nodes still connected like . writing methods many spatial analytical functions sf package, sfnetworks allows functions called directly sfnetwork objects, without need conversion. See overview sf functions method sfnetwork objects. complete overview functionalities sf, check sf documentation. One many tasks sf covers specification coordinate reference systems, CRS short, transformation spatial coordinates systems. sfnetwork object nodes edges always CRS, matter elements active retrieve CRS, transform coordinates different CRS. sf also multiple functions implement evaluation spatial predicate. spatial predicate describes spatial relation two geometries. example, point may located within polygon B. example show evaluate node spatial network located within one two given polygons. using spatial predicates, sf offers ability perform spatial joins spatial filters. Spatial joins join information spatial feature features specified spatial relation . Spatial filters keep features specified spatial relation, removes . details spatial joins filters spatial networks, see vignette Spatial joins filters. Finally, sf contains group functions known geometric unary operations. functions change structure individual geometries. usage context spatial networks limited, since many break network structure endpoints edges spatially equal respective nodes. Hence, geometric unary operations change type, shape, position geometries method sfnetwork objects. include sf::st_reverse() reverse edge geometries, sf::st_segmentize() add interior points edge geometries. However, just unsupported tidyverse-verbs, can still apply unsupported geometric unary operations first extracting active element sf object, proceed analysis single table. mentioned, sfnetworks extends functionalities tidygraph sf offering functions specific spatial network analysis, well functions allow smoother integration sf design tidygraph workflows. contradiction tidygraph, functions sfnetworks consider edge weights always use geographic edge length default weight. first family functions sfnetworks names formatted st_network_*, adopting naming conventions sf. functions take spatial network first input implement analysis task involves network set regular spatial simple features (points, lines, polygons). returned object can either set spatial simple features computed network, network spatial features merged , another object (e.g., matrix) result computation relating network spatial features. covers large range use-cases. Examples include drawing isochrone isodistance polygons around nodes, finding geographic shortest paths pairs nodes, computing cost matrices travel nodes, extracting faces network, adding external point data new nodes network. vignettes find details functions. also functions sfnetworks start st_*, end *_network. contradiction st_network_* functions, functions take set spatial features first input, network additional argument. example st_project_on_network, projects points onto network. Shortest path Isodistance polygon Network faces Blended points extension measure functions tidygraph, several spatial measure functions nodes edges found sfnetworks. Just tidygraph, functions named style node_* edge_*, centrality measure, centrality_*. Edge measures can computed include example geographic length edge, azimuth, circuity (.e. ratio geographic length shortest euclidean distance source target node). nodes, example possible compute straightness centrality (.e. average ratio euclidean distance network distance node nodes network). better integrate spatial predicate functions sf design tidygraph, applicable predicates also implemented node edge measure function. functions return TRUE node edge specified spatial relation least one given spatial features, FALSE otherwise. makes easy use predicates directly inside functions dplyr::filter() dplyr::mutate(). extension community detection functions tidygraph, sfnetworks contains group_spatial_dbscan() function find spatial clusters nodes. idea offer multiple spatial clustering algorithms choose , currently one implemented DBSCAN algorithm (require dbscan package installed). algorithm executed network distance matrix nodes, euclidean distance matrix. extension morpher functions tidygraph, many different spatial morpher functions implemented sfnetworks. Just tidygraph, function change structure input network, example subsetting splitting , combining multiple features one, splitting single features. Common examples include subdividing network interior points edge geometries, smoothing pseudo nodes degree 2, contracting multiple nodes one preserving network connectivity. vignettes find details functions. Many morphers used network cleaning operations, described detail vignette Cleaning spatial networks. Smooth network Subdivision smooth network Contracted groups nodes single path Finally, sfnetworks exports kind utility functions make working spatial networks less cumbersome. example finding nearest node nearest edge given spatial feature. overview exported functions package, see function reference. Nearest node Nearest edge Also fan tidyverse style data analysis, sfnetworks can . Since sfnetwork objects inherit igraph class, can apply functions large igraph package . means, example, instead using dplyr::mutate() dplyr::filter(), proceed follows (note igraph, term vertex used instead node). can see, returns igraph object instead sfnetwork object. preserve class, can use wrap_igraph() function sfnetworks igraph function accepts network first input returns another network. function check returned network still spatial. spatial measure functions can evaluated outside tidygraph framework using with_graph(), works similar base R’s () function. spatial morpher functions implement larger workflow internal workers exported, meaning can called directly outside tidygraph::morph() tidygraph::convert() verbs. morphers easy replicate using sf sfnetworks functions directly.","code":"net |> activate(nodes) |> mutate(label = letters[1:n()]) |> select(name, label) |> activate(edges) |> filter(sample(c(TRUE, FALSE), n(), replace = TRUE)) #> # A sfnetwork: 17 nodes and 9 edges #> # #> # An unrooted forest with 8 trees and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 9 × 3 (active) #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 2 7 (4549003 2747376, 4549064 2747619) #> 3 4 5 (4549387 2747514, 4549491 2747551) #> 4 8 12 (4548994 2747632, 4548664 2747868) #> 5 9 10 (4549120 2747654, 4549418 2747723) #> 6 10 11 (4549418 2747723, 4549119 2747790) #> # ℹ 3 more rows #> # #> # Node data: 17 × 3 #> name label geometry #> #> 1 Mozartkino a (4549504 2747309) #> 2 Haus für Mozart b (4549003 2747376) #> 3 Mozartsteg/Rudolfskai c (4549589 2747507) #> # ℹ 14 more rows # Filtering nodes also reduces the number of edges. net |> activate(nodes) |> filter(type == \"artwork\") #> # A sfnetwork: 3 nodes and 0 edges #> # #> # An unrooted forest with 3 trees and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747514 xmax: 4549387 ymax: 2747868 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 3 × 4 (active) #> name type website geometry #> #> 1 Mozart Denkmal artwork NA (4549387 2747514) #> 2 Spirit of Mozart artwork https://salzburgfoundat… (4549119 2747790) #> 3 Mozart-Eine Hommage artwork https://salzburgfoundat… (4548664 2747868) #> # #> # Edge data: 0 × 3 #> # ℹ 3 variables: from , to , geometry net |> activate(nodes) |> st_as_sf() |> group_by(type) |> summarize(n = n()) #> Simple feature collection with 13 features and 2 fields #> Geometry type: GEOMETRY #> Dimension: XY #> Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 13 × 3 #> type n geometry #> #> 1 apartments 1 POINT (4549073 2747916) #> 2 artwork 3 MULTIPOINT ((4548664 2747868), (4549119 2747790), (45493… #> 3 bridge 1 POINT (4549473 2747624) #> 4 bus_stop 3 MULTIPOINT ((4549418 2747723), (4549491 2747551), (45495… #> 5 cafe 1 POINT (4548994 2747632) #> 6 cinema 1 POINT (4549504 2747309) #> 7 concert_hall 1 POINT (4548897 2748037) #> 8 confectionery 1 POINT (4549120 2747654) #> 9 dormitory 1 POINT (4548984 2748537) #> 10 hotel 1 POINT (4549378 2748391) #> 11 museum 1 POINT (4549064 2747619) #> 12 theatre 1 POINT (4549003 2747376) #> 13 university 1 POINT (4549059 2748042) net = net |> activate(edges) |> mutate(length = edge_length()) net #> # A sfnetwork: 17 nodes and 25 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 25 × 4 (active) #> from to geometry length #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. #> 4 2 7 (4549003 2747376, 4549064 2747619) 250. #> 5 2 8 (4549003 2747376, 4548994 2747632) 256. #> 6 3 5 (4549589 2747507, 4549491 2747551) 107. #> # ℹ 19 more rows #> # #> # Node data: 17 × 4 #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> # ℹ 14 more rows new_net = net |> activate(edges) |> filter(!edge_is_incident(13)) |> activate(nodes) |> mutate(bc = centrality_betweenness(weights = length)) new_net #> # A sfnetwork: 17 nodes and 23 edges #> # #> # A bipartite simple graph with 2 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 5 (active) #> name type website geometry bc #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) 0 #> 2 Haus für Mozart theatre NA (4549003 2747376) 0 #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 5 #> 4 Mozart Denkmal artwork NA (4549387 2747514) 21 #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 22 #> 6 Mozartsteg bridge NA (4549473 2747624) 16 #> # ℹ 11 more rows #> # #> # Edge data: 23 × 4 #> from to geometry length #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. #> # ℹ 20 more rows ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(size = bc)) + theme_void() with_graph(net, centrality_degree()) |> setNames(NULL) #> [1] 2 3 2 4 3 2 3 3 4 4 3 2 2 4 3 3 3 new_net = net |> activate(nodes) |> mutate(group = group_optimal()) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(group)), size = 4) + scale_colour_discrete(\"group\") + theme_void() new_net = net |> convert(to_minimum_spanning_tree, weights = length) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() st_crs(net)$epsg #> [1] 3035 st_transform(net, 4326) #> # A sfnetwork: 17 nodes and 25 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 13.03835 ymin: 47.79698 xmax: 13.05049 ymax: 47.80822 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 25 × 4 (active) #> from to geometry length #> [m] #> 1 1 3 (13.04925 47.79698, 13.05049 47.79874) 216. #> 2 1 4 (13.04925 47.79698, 13.04781 47.79887) 236. #> 3 2 4 (13.0426 47.79778, 13.04781 47.79887) 409. #> 4 2 7 (13.0426 47.79778, 13.04355 47.79993) 250. #> 5 2 8 (13.0426 47.79778, 13.04263 47.80008) 256. #> 6 3 5 (13.05049 47.79874, 13.04921 47.79917) 107. #> # ℹ 19 more rows #> # #> # Node data: 17 × 4 #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (13.04925 47.79698) #> 2 Haus für Mozart theatre NA (13.0426 47.79778) #> 3 Mozartsteg/Rudolfskai bus_stop NA (13.05049 47.79874) #> # ℹ 14 more rows polys = mozart |> slice(4, 15) |> st_buffer(325) |> mutate(label = c(\"A\", \"B\")) |> select(label) ggraph(net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() net |> activate(nodes) |> st_within(polys) #> Sparse geometry binary predicate list of length 17, where the predicate #> was `within' #> first 10 elements: #> 1: 1 #> 2: (empty) #> 3: 1 #> 4: 1 #> 5: 1 #> 6: 1 #> 7: (empty) #> 8: (empty) #> 9: 1 #> 10: 1 new_net = net |> activate(nodes) |> st_join(polys, join = st_within) ggraph(new_net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(label)), size = 4) + scale_colour_discrete(\"label\") + theme_void() new_net = net |> activate(nodes) |> st_filter(polys, .predicate = st_within) ggraph(new_net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() net |> activate(nodes) |> st_as_sf() |> st_buffer(250) #> Simple feature collection with 17 features and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POLYGON #> Dimension: XY #> Bounding box: xmin: 4548414 ymin: 2747059 xmax: 4549839 ymax: 2748787 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 17 × 4 #> name type website geometry #> * #> 1 Mozartkino cinema https://www.… ((4549754 2747309, 45497… #> 2 Haus für Mozart theatre NA ((4549253 2747376, 45492… #> 3 Mozartsteg/Rudolfskai bus_stop NA ((4549839 2747507, 45498… #> 4 Mozart Denkmal artwork NA ((4549637 2747514, 45496… #> 5 Mozartsteg/Rudolfskai bus_stop NA ((4549741 2747551, 45497… #> 6 Mozartsteg bridge NA ((4549723 2747624, 45497… #> 7 Mozarts Geburtshaus museum http://www.m… ((4549314 2747619, 45493… #> 8 Café Mozart cafe https://www.… ((4549244 2747632, 45492… #> 9 Mozartkugel confectionery NA ((4549370 2747654, 45493… #> 10 Mozartsteg/Imbergstraße bus_stop NA ((4549668 2747723, 45496… #> 11 Spirit of Mozart artwork https://salz… ((4549369 2747790, 45493… #> 12 Mozart-Eine Hommage artwork https://salz… ((4548914 2747868, 45489… #> 13 Mozarts Wohnhaus apartments NA ((4549323 2747916, 45493… #> 14 Universität Mozarteum university NA ((4549309 2748042, 45493… #> 15 Stiftung Mozarteum concert_hall NA ((4549147 2748037, 45491… #> 16 Hotel Mozart hotel http://www.h… ((4549628 2748391, 45496… #> 17 Mozart Studentenheim dormitory NA ((4549234 2748537, 45492… # Find shortest path between node 1 and node 17. path = st_network_paths(net, 1, 17) # Draw an isodistance polygon with 500m threshold around node 13. iso = st_network_iso(net, 13, 500) # Extract the faces of the network. faces = st_network_faces(net) # Blend external points as new nodes into the network. feats = st_sample(st_bbox(mozart), 10) blend = st_network_blend(net, feats) ggraph(net, \"sf\") + geom_edge_sf() + geom_sf(data = path, color = \"orange\", linewidth = 2) + geom_node_sf(size = 4) + geom_sf(data = st_geometry(net, \"nodes\")[c(1, 17)], size = 6) + theme_void() ggraph(net, \"sf\") + geom_sf(data = iso, fill = \"orange\", alpha = 0.7) + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = st_geometry(net, \"nodes\")[13], size = 6) + theme_void() faces_sf = st_sf(id = c(1:length(faces)), geometry = faces) ggraph(net, \"sf\") + geom_sf(data = faces_sf, aes(fill = as.factor(id)), show.legend = FALSE) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(blend, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = feats, color = \"orange\", size = 4) + geom_sf( data = st_nearest_points(feats, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + theme_void() new_net = net |> activate(edges) |> filter(edge_intersects(polys)) |> mutate(circuity = edge_circuity()) |> activate(nodes) |> mutate( sc = centrality_straightness(), in_poly = node_is_within(polys) ) new_net #> # A sfnetwork: 17 nodes and 21 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 6 (active) #> name type website geometry sc in_poly #> #> 1 Mozartkino cinema https:… (4549504 2747309) 0.847 TRUE #> 2 Haus für Mozart theatre NA (4549003 2747376) 0.648 FALSE #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 0.878 TRUE #> 4 Mozart Denkmal artwork NA (4549387 2747514) 0.850 TRUE #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 0.874 TRUE #> 6 Mozartsteg bridge NA (4549473 2747624) 0.843 TRUE #> # ℹ 11 more rows #> # #> # Edge data: 21 × 5 #> from to geometry length circuity #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. 1 #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. 1 #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. 1 #> # ℹ 18 more rows new_net = net |> activate(nodes) |> mutate(group = group_spatial_dbscan(300)) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(group)), size = 4) + scale_colour_discrete(\"group\") + theme_void() # Smooth nodes of degree 2. smooth = convert(net, to_spatial_smooth) # Subdivide edges at each interior point in the smoothed network. # In this case this is the opposite of smoothing, it adds back the degree 2 nodes. division = convert(smooth, to_spatial_subdivision, all = TRUE) # Contract nodes that are in the same spatial cluster. contraction = net |> activate(nodes) |> mutate(group = group_spatial_dbscan(300)) |> convert(to_spatial_contracted, group) # Subset the graph to only those edges in a shortest path. path = convert(net, to_spatial_shortest_paths, 1, 17) ggraph(smooth, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(division, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(contraction, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(path, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() p = st_centroid(st_combine(mozart)) nn = nearest_nodes(net, p) nn #> Simple feature collection with 1 feature and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 4549119 ymin: 2747790 xmax: 4549119 ymax: 2747790 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 4 #> name type website geometry #> #> 1 Spirit of Mozart artwork https://salzburgfoundation… (4549119 2747790) ne = nearest_edges(net, p) ne #> Simple feature collection with 1 feature and 3 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4549119 ymin: 2747723 xmax: 4549418 ymax: 2747790 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 4 #> from to geometry length #> [m] #> 1 10 11 (4549418 2747723, 4549119 2747790) 306. ggraph(net, \"sf\") + geom_sf(data = p, size = 6, pch = 8) + geom_edge_sf(color = \"grey\") + geom_node_sf(color = \"grey\", size = 4) + geom_sf(data = nn, color = \"orange\", size = 6) + theme_void() ggraph(net, \"sf\") + geom_sf(data = p, size = 6, pch = 8) + geom_edge_sf(color = \"grey\") + geom_sf(data = ne, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"grey\", size = 4) + theme_void() # Mutate. vertex_attr(net, \"label\") = letters[1:vcount(net)] # Filter. drop = which(!sample(c(TRUE, FALSE), ecount(net), replace = TRUE)) new_net = delete_edges(net, drop) new_net #> IGRAPH 66e2aa1 UN-B 17 14 -- #> + attr: name (v/c), type (v/c), website (v/c), geometry (v/x), label #> | (v/c), geometry (e/x), length (e/n) #> + edges from 66e2aa1 (vertex names): #> [1] Mozartkino --Mozartsteg/Rudolfskai #> [2] Haus für Mozart --Mozart Denkmal #> [3] Haus für Mozart --Mozarts Geburtshaus #> [4] Mozartsteg/Rudolfskai --Mozartsteg/Rudolfskai #> [5] Mozart Denkmal --Mozartsteg/Rudolfskai #> [6] Mozart Denkmal --Mozartkugel #> [7] Mozarts Geburtshaus --Café Mozart #> + ... omitted several edges wrap_igraph(net, delete_edges, drop) #> # A sfnetwork: 17 nodes and 14 edges #> # #> # An unrooted forest with 3 trees and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 14 × 4 (active) #> from to geometry length #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. #> 2 2 4 (4549003 2747376, 4549387 2747514) 409. #> 3 2 7 (4549003 2747376, 4549064 2747619) 250. #> 4 3 5 (4549589 2747507, 4549491 2747551) 107. #> 5 4 5 (4549387 2747514, 4549491 2747551) 110. #> 6 4 9 (4549387 2747514, 4549120 2747654) 301. #> # ℹ 8 more rows #> # #> # Node data: 17 × 5 #> name type website geometry label #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) a #> 2 Haus für Mozart theatre NA (4549003 2747376) b #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) c #> # ℹ 14 more rows mst = wrap_igraph(net, mst, weights = edge_attr(net, \"length\")) ggraph(mst, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() with_graph(net, edge_circuity()) #> [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"network-analysis-with-tidygraph","dir":"Articles","previous_headings":"","what":"Network analysis with tidygraph","title":"Introduction to sfnetworks","text":"allow performing common network analysis tasks, sfnetworks builds upon tidygraph. Since sfnetwork objects inherit tbl_graph class, analytical functions tidygraph can directly used. lot functions available, tidy wrappers around functions igraph library. complete overview, check tidygraph documentation. important note case spatial networks often makes sense use geographic length edge weight. Since tidygraph know space, never set automatically, explicitly specify every time call function can consider edge weights. Read specifying edge weights vignette Routing spatial networks. large set functions tidygraph dedicated computation quantitative measures nodes, edges, network whole. known centrality measures, define importance node network. names implemented centrality measure functions formatted centrality_*. implemented measure functions names formatted node_* (node measures) edge_* (edge measures) graph_* (network measures). special group measure functions logical measures, return either TRUE FALSE, indicating node, edge network specified type. None functions meant called directly, used inside tidyverse-verbs dplyr::mutate() dplyr::filter(), analyzed network know thus needed input function. tidygraph::with_graph() can used evaluate measure context specific network, outside tidyverse framework. Another set functions tidygraph deals community detection networks. functions group nodes edges based clustering algorithm. names formatted group_*, always return vector group indices, one feature. implemented algorithms try create groups nodes number edges within groups relatively high compared number edges groups, example . note algorithms generally designed account spatial factors, may limited use working spatial networks. Finally, tidygraph introduced new set network analysis functions call morphers. Morphers change structure input graph, example subsetting splitting , combining multiple features one, converting nodes edges vice versa. different struture needed computations, can set temporarily providing morphers subsequently tidygraph::morph() tidygraph::unmorph() verbs. different structure meant last, morpher can provided tidygraph::convert() verb instead. example convert network minimum spanning tree, contains minimum set edges need nodes still connected like .","code":"net = net |> activate(edges) |> mutate(length = edge_length()) net #> # A sfnetwork: 17 nodes and 25 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 25 × 4 (active) #> from to geometry length #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. #> 4 2 7 (4549003 2747376, 4549064 2747619) 250. #> 5 2 8 (4549003 2747376, 4548994 2747632) 256. #> 6 3 5 (4549589 2747507, 4549491 2747551) 107. #> # ℹ 19 more rows #> # #> # Node data: 17 × 4 #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> # ℹ 14 more rows new_net = net |> activate(edges) |> filter(!edge_is_incident(13)) |> activate(nodes) |> mutate(bc = centrality_betweenness(weights = length)) new_net #> # A sfnetwork: 17 nodes and 23 edges #> # #> # A bipartite simple graph with 2 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 5 (active) #> name type website geometry bc #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) 0 #> 2 Haus für Mozart theatre NA (4549003 2747376) 0 #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 5 #> 4 Mozart Denkmal artwork NA (4549387 2747514) 21 #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 22 #> 6 Mozartsteg bridge NA (4549473 2747624) 16 #> # ℹ 11 more rows #> # #> # Edge data: 23 × 4 #> from to geometry length #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. #> # ℹ 20 more rows ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(size = bc)) + theme_void() with_graph(net, centrality_degree()) |> setNames(NULL) #> [1] 2 3 2 4 3 2 3 3 4 4 3 2 2 4 3 3 3 new_net = net |> activate(nodes) |> mutate(group = group_optimal()) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(group)), size = 4) + scale_colour_discrete(\"group\") + theme_void() new_net = net |> convert(to_minimum_spanning_tree, weights = length) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"measures","dir":"Articles","previous_headings":"","what":"Measures","title":"Introduction to sfnetworks","text":"large set functions tidygraph dedicated computation quantitative measures nodes, edges, network whole. known centrality measures, define importance node network. names implemented centrality measure functions formatted centrality_*. implemented measure functions names formatted node_* (node measures) edge_* (edge measures) graph_* (network measures). special group measure functions logical measures, return either TRUE FALSE, indicating node, edge network specified type. None functions meant called directly, used inside tidyverse-verbs dplyr::mutate() dplyr::filter(), analyzed network know thus needed input function. tidygraph::with_graph() can used evaluate measure context specific network, outside tidyverse framework.","code":"new_net = net |> activate(edges) |> filter(!edge_is_incident(13)) |> activate(nodes) |> mutate(bc = centrality_betweenness(weights = length)) new_net #> # A sfnetwork: 17 nodes and 23 edges #> # #> # A bipartite simple graph with 2 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 5 (active) #> name type website geometry bc #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) 0 #> 2 Haus für Mozart theatre NA (4549003 2747376) 0 #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 5 #> 4 Mozart Denkmal artwork NA (4549387 2747514) 21 #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 22 #> 6 Mozartsteg bridge NA (4549473 2747624) 16 #> # ℹ 11 more rows #> # #> # Edge data: 23 × 4 #> from to geometry length #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. #> # ℹ 20 more rows ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(size = bc)) + theme_void() with_graph(net, centrality_degree()) |> setNames(NULL) #> [1] 2 3 2 4 3 2 3 3 4 4 3 2 2 4 3 3 3"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"community-detection","dir":"Articles","previous_headings":"","what":"Community detection","title":"Introduction to sfnetworks","text":"Another set functions tidygraph deals community detection networks. functions group nodes edges based clustering algorithm. names formatted group_*, always return vector group indices, one feature. implemented algorithms try create groups nodes number edges within groups relatively high compared number edges groups, example . note algorithms generally designed account spatial factors, may limited use working spatial networks.","code":"new_net = net |> activate(nodes) |> mutate(group = group_optimal()) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(group)), size = 4) + scale_colour_discrete(\"group\") + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"morphers","dir":"Articles","previous_headings":"","what":"Morphers","title":"Introduction to sfnetworks","text":"Finally, tidygraph introduced new set network analysis functions call morphers. Morphers change structure input graph, example subsetting splitting , combining multiple features one, converting nodes edges vice versa. different struture needed computations, can set temporarily providing morphers subsequently tidygraph::morph() tidygraph::unmorph() verbs. different structure meant last, morpher can provided tidygraph::convert() verb instead. example convert network minimum spanning tree, contains minimum set edges need nodes still connected like .","code":"new_net = net |> convert(to_minimum_spanning_tree, weights = length) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"spatial-analysis-with-sf","dir":"Articles","previous_headings":"","what":"Spatial analysis with sf","title":"Introduction to sfnetworks","text":"writing methods many spatial analytical functions sf package, sfnetworks allows functions called directly sfnetwork objects, without need conversion. See overview sf functions method sfnetwork objects. complete overview functionalities sf, check sf documentation. One many tasks sf covers specification coordinate reference systems, CRS short, transformation spatial coordinates systems. sfnetwork object nodes edges always CRS, matter elements active retrieve CRS, transform coordinates different CRS. sf also multiple functions implement evaluation spatial predicate. spatial predicate describes spatial relation two geometries. example, point may located within polygon B. example show evaluate node spatial network located within one two given polygons. using spatial predicates, sf offers ability perform spatial joins spatial filters. Spatial joins join information spatial feature features specified spatial relation . Spatial filters keep features specified spatial relation, removes . details spatial joins filters spatial networks, see vignette Spatial joins filters. Finally, sf contains group functions known geometric unary operations. functions change structure individual geometries. usage context spatial networks limited, since many break network structure endpoints edges spatially equal respective nodes. Hence, geometric unary operations change type, shape, position geometries method sfnetwork objects. include sf::st_reverse() reverse edge geometries, sf::st_segmentize() add interior points edge geometries. However, just unsupported tidyverse-verbs, can still apply unsupported geometric unary operations first extracting active element sf object, proceed analysis single table.","code":"st_crs(net)$epsg #> [1] 3035 st_transform(net, 4326) #> # A sfnetwork: 17 nodes and 25 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 13.03835 ymin: 47.79698 xmax: 13.05049 ymax: 47.80822 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 25 × 4 (active) #> from to geometry length #> [m] #> 1 1 3 (13.04925 47.79698, 13.05049 47.79874) 216. #> 2 1 4 (13.04925 47.79698, 13.04781 47.79887) 236. #> 3 2 4 (13.0426 47.79778, 13.04781 47.79887) 409. #> 4 2 7 (13.0426 47.79778, 13.04355 47.79993) 250. #> 5 2 8 (13.0426 47.79778, 13.04263 47.80008) 256. #> 6 3 5 (13.05049 47.79874, 13.04921 47.79917) 107. #> # ℹ 19 more rows #> # #> # Node data: 17 × 4 #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (13.04925 47.79698) #> 2 Haus für Mozart theatre NA (13.0426 47.79778) #> 3 Mozartsteg/Rudolfskai bus_stop NA (13.05049 47.79874) #> # ℹ 14 more rows polys = mozart |> slice(4, 15) |> st_buffer(325) |> mutate(label = c(\"A\", \"B\")) |> select(label) ggraph(net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() net |> activate(nodes) |> st_within(polys) #> Sparse geometry binary predicate list of length 17, where the predicate #> was `within' #> first 10 elements: #> 1: 1 #> 2: (empty) #> 3: 1 #> 4: 1 #> 5: 1 #> 6: 1 #> 7: (empty) #> 8: (empty) #> 9: 1 #> 10: 1 new_net = net |> activate(nodes) |> st_join(polys, join = st_within) ggraph(new_net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(label)), size = 4) + scale_colour_discrete(\"label\") + theme_void() new_net = net |> activate(nodes) |> st_filter(polys, .predicate = st_within) ggraph(new_net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() net |> activate(nodes) |> st_as_sf() |> st_buffer(250) #> Simple feature collection with 17 features and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POLYGON #> Dimension: XY #> Bounding box: xmin: 4548414 ymin: 2747059 xmax: 4549839 ymax: 2748787 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 17 × 4 #> name type website geometry #> * #> 1 Mozartkino cinema https://www.… ((4549754 2747309, 45497… #> 2 Haus für Mozart theatre NA ((4549253 2747376, 45492… #> 3 Mozartsteg/Rudolfskai bus_stop NA ((4549839 2747507, 45498… #> 4 Mozart Denkmal artwork NA ((4549637 2747514, 45496… #> 5 Mozartsteg/Rudolfskai bus_stop NA ((4549741 2747551, 45497… #> 6 Mozartsteg bridge NA ((4549723 2747624, 45497… #> 7 Mozarts Geburtshaus museum http://www.m… ((4549314 2747619, 45493… #> 8 Café Mozart cafe https://www.… ((4549244 2747632, 45492… #> 9 Mozartkugel confectionery NA ((4549370 2747654, 45493… #> 10 Mozartsteg/Imbergstraße bus_stop NA ((4549668 2747723, 45496… #> 11 Spirit of Mozart artwork https://salz… ((4549369 2747790, 45493… #> 12 Mozart-Eine Hommage artwork https://salz… ((4548914 2747868, 45489… #> 13 Mozarts Wohnhaus apartments NA ((4549323 2747916, 45493… #> 14 Universität Mozarteum university NA ((4549309 2748042, 45493… #> 15 Stiftung Mozarteum concert_hall NA ((4549147 2748037, 45491… #> 16 Hotel Mozart hotel http://www.h… ((4549628 2748391, 45496… #> 17 Mozart Studentenheim dormitory NA ((4549234 2748537, 45492…"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"coordinate-reference-systems","dir":"Articles","previous_headings":"","what":"Coordinate reference systems","title":"Introduction to sfnetworks","text":"One many tasks sf covers specification coordinate reference systems, CRS short, transformation spatial coordinates systems. sfnetwork object nodes edges always CRS, matter elements active retrieve CRS, transform coordinates different CRS.","code":"st_crs(net)$epsg #> [1] 3035 st_transform(net, 4326) #> # A sfnetwork: 17 nodes and 25 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 13.03835 ymin: 47.79698 xmax: 13.05049 ymax: 47.80822 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 25 × 4 (active) #> from to geometry length #> [m] #> 1 1 3 (13.04925 47.79698, 13.05049 47.79874) 216. #> 2 1 4 (13.04925 47.79698, 13.04781 47.79887) 236. #> 3 2 4 (13.0426 47.79778, 13.04781 47.79887) 409. #> 4 2 7 (13.0426 47.79778, 13.04355 47.79993) 250. #> 5 2 8 (13.0426 47.79778, 13.04263 47.80008) 256. #> 6 3 5 (13.05049 47.79874, 13.04921 47.79917) 107. #> # ℹ 19 more rows #> # #> # Node data: 17 × 4 #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (13.04925 47.79698) #> 2 Haus für Mozart theatre NA (13.0426 47.79778) #> 3 Mozartsteg/Rudolfskai bus_stop NA (13.05049 47.79874) #> # ℹ 14 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"spatial-predicates","dir":"Articles","previous_headings":"","what":"Spatial predicates","title":"Introduction to sfnetworks","text":"sf also multiple functions implement evaluation spatial predicate. spatial predicate describes spatial relation two geometries. example, point may located within polygon B. example show evaluate node spatial network located within one two given polygons.","code":"polys = mozart |> slice(4, 15) |> st_buffer(325) |> mutate(label = c(\"A\", \"B\")) |> select(label) ggraph(net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() net |> activate(nodes) |> st_within(polys) #> Sparse geometry binary predicate list of length 17, where the predicate #> was `within' #> first 10 elements: #> 1: 1 #> 2: (empty) #> 3: 1 #> 4: 1 #> 5: 1 #> 6: 1 #> 7: (empty) #> 8: (empty) #> 9: 1 #> 10: 1"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"spatial-joins-and-filters","dir":"Articles","previous_headings":"","what":"Spatial joins and filters","title":"Introduction to sfnetworks","text":"using spatial predicates, sf offers ability perform spatial joins spatial filters. Spatial joins join information spatial feature features specified spatial relation . Spatial filters keep features specified spatial relation, removes . details spatial joins filters spatial networks, see vignette Spatial joins filters.","code":"new_net = net |> activate(nodes) |> st_join(polys, join = st_within) ggraph(new_net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(label)), size = 4) + scale_colour_discrete(\"label\") + theme_void() new_net = net |> activate(nodes) |> st_filter(polys, .predicate = st_within) ggraph(new_net, \"sf\") + geom_sf(data = polys, linewidth = 1, color = \"orange\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"geometric-unary-operations","dir":"Articles","previous_headings":"","what":"Geometric unary operations","title":"Introduction to sfnetworks","text":"Finally, sf contains group functions known geometric unary operations. functions change structure individual geometries. usage context spatial networks limited, since many break network structure endpoints edges spatially equal respective nodes. Hence, geometric unary operations change type, shape, position geometries method sfnetwork objects. include sf::st_reverse() reverse edge geometries, sf::st_segmentize() add interior points edge geometries. However, just unsupported tidyverse-verbs, can still apply unsupported geometric unary operations first extracting active element sf object, proceed analysis single table.","code":"net |> activate(nodes) |> st_as_sf() |> st_buffer(250) #> Simple feature collection with 17 features and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POLYGON #> Dimension: XY #> Bounding box: xmin: 4548414 ymin: 2747059 xmax: 4549839 ymax: 2748787 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 17 × 4 #> name type website geometry #> * #> 1 Mozartkino cinema https://www.… ((4549754 2747309, 45497… #> 2 Haus für Mozart theatre NA ((4549253 2747376, 45492… #> 3 Mozartsteg/Rudolfskai bus_stop NA ((4549839 2747507, 45498… #> 4 Mozart Denkmal artwork NA ((4549637 2747514, 45496… #> 5 Mozartsteg/Rudolfskai bus_stop NA ((4549741 2747551, 45497… #> 6 Mozartsteg bridge NA ((4549723 2747624, 45497… #> 7 Mozarts Geburtshaus museum http://www.m… ((4549314 2747619, 45493… #> 8 Café Mozart cafe https://www.… ((4549244 2747632, 45492… #> 9 Mozartkugel confectionery NA ((4549370 2747654, 45493… #> 10 Mozartsteg/Imbergstraße bus_stop NA ((4549668 2747723, 45496… #> 11 Spirit of Mozart artwork https://salz… ((4549369 2747790, 45493… #> 12 Mozart-Eine Hommage artwork https://salz… ((4548914 2747868, 45489… #> 13 Mozarts Wohnhaus apartments NA ((4549323 2747916, 45493… #> 14 Universität Mozarteum university NA ((4549309 2748042, 45493… #> 15 Stiftung Mozarteum concert_hall NA ((4549147 2748037, 45491… #> 16 Hotel Mozart hotel http://www.h… ((4549628 2748391, 45496… #> 17 Mozart Studentenheim dormitory NA ((4549234 2748537, 45492…"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"spatial-network-specific-additions","dir":"Articles","previous_headings":"","what":"Spatial network specific additions","title":"Introduction to sfnetworks","text":"mentioned, sfnetworks extends functionalities tidygraph sf offering functions specific spatial network analysis, well functions allow smoother integration sf design tidygraph workflows. contradiction tidygraph, functions sfnetworks consider edge weights always use geographic edge length default weight. first family functions sfnetworks names formatted st_network_*, adopting naming conventions sf. functions take spatial network first input implement analysis task involves network set regular spatial simple features (points, lines, polygons). returned object can either set spatial simple features computed network, network spatial features merged , another object (e.g., matrix) result computation relating network spatial features. covers large range use-cases. Examples include drawing isochrone isodistance polygons around nodes, finding geographic shortest paths pairs nodes, computing cost matrices travel nodes, extracting faces network, adding external point data new nodes network. vignettes find details functions. also functions sfnetworks start st_*, end *_network. contradiction st_network_* functions, functions take set spatial features first input, network additional argument. example st_project_on_network, projects points onto network. Shortest path Isodistance polygon Network faces Blended points extension measure functions tidygraph, several spatial measure functions nodes edges found sfnetworks. Just tidygraph, functions named style node_* edge_*, centrality measure, centrality_*. Edge measures can computed include example geographic length edge, azimuth, circuity (.e. ratio geographic length shortest euclidean distance source target node). nodes, example possible compute straightness centrality (.e. average ratio euclidean distance network distance node nodes network). better integrate spatial predicate functions sf design tidygraph, applicable predicates also implemented node edge measure function. functions return TRUE node edge specified spatial relation least one given spatial features, FALSE otherwise. makes easy use predicates directly inside functions dplyr::filter() dplyr::mutate(). extension community detection functions tidygraph, sfnetworks contains group_spatial_dbscan() function find spatial clusters nodes. idea offer multiple spatial clustering algorithms choose , currently one implemented DBSCAN algorithm (require dbscan package installed). algorithm executed network distance matrix nodes, euclidean distance matrix. extension morpher functions tidygraph, many different spatial morpher functions implemented sfnetworks. Just tidygraph, function change structure input network, example subsetting splitting , combining multiple features one, splitting single features. Common examples include subdividing network interior points edge geometries, smoothing pseudo nodes degree 2, contracting multiple nodes one preserving network connectivity. vignettes find details functions. Many morphers used network cleaning operations, described detail vignette Cleaning spatial networks. Smooth network Subdivision smooth network Contracted groups nodes single path Finally, sfnetworks exports kind utility functions make working spatial networks less cumbersome. example finding nearest node nearest edge given spatial feature. overview exported functions package, see function reference. Nearest node Nearest edge","code":"# Find shortest path between node 1 and node 17. path = st_network_paths(net, 1, 17) # Draw an isodistance polygon with 500m threshold around node 13. iso = st_network_iso(net, 13, 500) # Extract the faces of the network. faces = st_network_faces(net) # Blend external points as new nodes into the network. feats = st_sample(st_bbox(mozart), 10) blend = st_network_blend(net, feats) ggraph(net, \"sf\") + geom_edge_sf() + geom_sf(data = path, color = \"orange\", linewidth = 2) + geom_node_sf(size = 4) + geom_sf(data = st_geometry(net, \"nodes\")[c(1, 17)], size = 6) + theme_void() ggraph(net, \"sf\") + geom_sf(data = iso, fill = \"orange\", alpha = 0.7) + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = st_geometry(net, \"nodes\")[13], size = 6) + theme_void() faces_sf = st_sf(id = c(1:length(faces)), geometry = faces) ggraph(net, \"sf\") + geom_sf(data = faces_sf, aes(fill = as.factor(id)), show.legend = FALSE) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(blend, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = feats, color = \"orange\", size = 4) + geom_sf( data = st_nearest_points(feats, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + theme_void() new_net = net |> activate(edges) |> filter(edge_intersects(polys)) |> mutate(circuity = edge_circuity()) |> activate(nodes) |> mutate( sc = centrality_straightness(), in_poly = node_is_within(polys) ) new_net #> # A sfnetwork: 17 nodes and 21 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 6 (active) #> name type website geometry sc in_poly #> #> 1 Mozartkino cinema https:… (4549504 2747309) 0.847 TRUE #> 2 Haus für Mozart theatre NA (4549003 2747376) 0.648 FALSE #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 0.878 TRUE #> 4 Mozart Denkmal artwork NA (4549387 2747514) 0.850 TRUE #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 0.874 TRUE #> 6 Mozartsteg bridge NA (4549473 2747624) 0.843 TRUE #> # ℹ 11 more rows #> # #> # Edge data: 21 × 5 #> from to geometry length circuity #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. 1 #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. 1 #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. 1 #> # ℹ 18 more rows new_net = net |> activate(nodes) |> mutate(group = group_spatial_dbscan(300)) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(group)), size = 4) + scale_colour_discrete(\"group\") + theme_void() # Smooth nodes of degree 2. smooth = convert(net, to_spatial_smooth) # Subdivide edges at each interior point in the smoothed network. # In this case this is the opposite of smoothing, it adds back the degree 2 nodes. division = convert(smooth, to_spatial_subdivision, all = TRUE) # Contract nodes that are in the same spatial cluster. contraction = net |> activate(nodes) |> mutate(group = group_spatial_dbscan(300)) |> convert(to_spatial_contracted, group) # Subset the graph to only those edges in a shortest path. path = convert(net, to_spatial_shortest_paths, 1, 17) ggraph(smooth, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(division, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(contraction, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(path, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() p = st_centroid(st_combine(mozart)) nn = nearest_nodes(net, p) nn #> Simple feature collection with 1 feature and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 4549119 ymin: 2747790 xmax: 4549119 ymax: 2747790 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 4 #> name type website geometry #> #> 1 Spirit of Mozart artwork https://salzburgfoundation… (4549119 2747790) ne = nearest_edges(net, p) ne #> Simple feature collection with 1 feature and 3 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4549119 ymin: 2747723 xmax: 4549418 ymax: 2747790 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 4 #> from to geometry length #> [m] #> 1 10 11 (4549418 2747723, 4549119 2747790) 306. ggraph(net, \"sf\") + geom_sf(data = p, size = 6, pch = 8) + geom_edge_sf(color = \"grey\") + geom_node_sf(color = \"grey\", size = 4) + geom_sf(data = nn, color = \"orange\", size = 6) + theme_void() ggraph(net, \"sf\") + geom_sf(data = p, size = 6, pch = 8) + geom_edge_sf(color = \"grey\") + geom_sf(data = ne, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"grey\", size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"relating-networks-and-spatial-simple-features","dir":"Articles","previous_headings":"","what":"Relating networks and spatial simple features","title":"Introduction to sfnetworks","text":"first family functions sfnetworks names formatted st_network_*, adopting naming conventions sf. functions take spatial network first input implement analysis task involves network set regular spatial simple features (points, lines, polygons). returned object can either set spatial simple features computed network, network spatial features merged , another object (e.g., matrix) result computation relating network spatial features. covers large range use-cases. Examples include drawing isochrone isodistance polygons around nodes, finding geographic shortest paths pairs nodes, computing cost matrices travel nodes, extracting faces network, adding external point data new nodes network. vignettes find details functions. also functions sfnetworks start st_*, end *_network. contradiction st_network_* functions, functions take set spatial features first input, network additional argument. example st_project_on_network, projects points onto network. Shortest path Isodistance polygon Network faces Blended points","code":"# Find shortest path between node 1 and node 17. path = st_network_paths(net, 1, 17) # Draw an isodistance polygon with 500m threshold around node 13. iso = st_network_iso(net, 13, 500) # Extract the faces of the network. faces = st_network_faces(net) # Blend external points as new nodes into the network. feats = st_sample(st_bbox(mozart), 10) blend = st_network_blend(net, feats) ggraph(net, \"sf\") + geom_edge_sf() + geom_sf(data = path, color = \"orange\", linewidth = 2) + geom_node_sf(size = 4) + geom_sf(data = st_geometry(net, \"nodes\")[c(1, 17)], size = 6) + theme_void() ggraph(net, \"sf\") + geom_sf(data = iso, fill = \"orange\", alpha = 0.7) + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = st_geometry(net, \"nodes\")[13], size = 6) + theme_void() faces_sf = st_sf(id = c(1:length(faces)), geometry = faces) ggraph(net, \"sf\") + geom_sf(data = faces_sf, aes(fill = as.factor(id)), show.legend = FALSE) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(blend, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = feats, color = \"orange\", size = 4) + geom_sf( data = st_nearest_points(feats, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"spatial-measures","dir":"Articles","previous_headings":"","what":"Spatial measures","title":"Introduction to sfnetworks","text":"extension measure functions tidygraph, several spatial measure functions nodes edges found sfnetworks. Just tidygraph, functions named style node_* edge_*, centrality measure, centrality_*. Edge measures can computed include example geographic length edge, azimuth, circuity (.e. ratio geographic length shortest euclidean distance source target node). nodes, example possible compute straightness centrality (.e. average ratio euclidean distance network distance node nodes network). better integrate spatial predicate functions sf design tidygraph, applicable predicates also implemented node edge measure function. functions return TRUE node edge specified spatial relation least one given spatial features, FALSE otherwise. makes easy use predicates directly inside functions dplyr::filter() dplyr::mutate().","code":"new_net = net |> activate(edges) |> filter(edge_intersects(polys)) |> mutate(circuity = edge_circuity()) |> activate(nodes) |> mutate( sc = centrality_straightness(), in_poly = node_is_within(polys) ) new_net #> # A sfnetwork: 17 nodes and 21 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 6 (active) #> name type website geometry sc in_poly #> #> 1 Mozartkino cinema https:… (4549504 2747309) 0.847 TRUE #> 2 Haus für Mozart theatre NA (4549003 2747376) 0.648 FALSE #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 0.878 TRUE #> 4 Mozart Denkmal artwork NA (4549387 2747514) 0.850 TRUE #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 0.874 TRUE #> 6 Mozartsteg bridge NA (4549473 2747624) 0.843 TRUE #> # ℹ 11 more rows #> # #> # Edge data: 21 × 5 #> from to geometry length circuity #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. 1 #> 2 1 4 (4549504 2747309, 4549387 2747514) 236. 1 #> 3 2 4 (4549003 2747376, 4549387 2747514) 409. 1 #> # ℹ 18 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"spatial-clustering","dir":"Articles","previous_headings":"","what":"Spatial clustering","title":"Introduction to sfnetworks","text":"extension community detection functions tidygraph, sfnetworks contains group_spatial_dbscan() function find spatial clusters nodes. idea offer multiple spatial clustering algorithms choose , currently one implemented DBSCAN algorithm (require dbscan package installed). algorithm executed network distance matrix nodes, euclidean distance matrix.","code":"new_net = net |> activate(nodes) |> mutate(group = group_spatial_dbscan(300)) ggraph(new_net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(group)), size = 4) + scale_colour_discrete(\"group\") + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"spatial-morphers","dir":"Articles","previous_headings":"","what":"Spatial morphers","title":"Introduction to sfnetworks","text":"extension morpher functions tidygraph, many different spatial morpher functions implemented sfnetworks. Just tidygraph, function change structure input network, example subsetting splitting , combining multiple features one, splitting single features. Common examples include subdividing network interior points edge geometries, smoothing pseudo nodes degree 2, contracting multiple nodes one preserving network connectivity. vignettes find details functions. Many morphers used network cleaning operations, described detail vignette Cleaning spatial networks. Smooth network Subdivision smooth network Contracted groups nodes single path","code":"# Smooth nodes of degree 2. smooth = convert(net, to_spatial_smooth) # Subdivide edges at each interior point in the smoothed network. # In this case this is the opposite of smoothing, it adds back the degree 2 nodes. division = convert(smooth, to_spatial_subdivision, all = TRUE) # Contract nodes that are in the same spatial cluster. contraction = net |> activate(nodes) |> mutate(group = group_spatial_dbscan(300)) |> convert(to_spatial_contracted, group) # Subset the graph to only those edges in a shortest path. path = convert(net, to_spatial_shortest_paths, 1, 17) ggraph(smooth, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(division, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(contraction, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(path, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"utilities","dir":"Articles","previous_headings":"","what":"Utilities","title":"Introduction to sfnetworks","text":"Finally, sfnetworks exports kind utility functions make working spatial networks less cumbersome. example finding nearest node nearest edge given spatial feature. overview exported functions package, see function reference. Nearest node Nearest edge","code":"p = st_centroid(st_combine(mozart)) nn = nearest_nodes(net, p) nn #> Simple feature collection with 1 feature and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 4549119 ymin: 2747790 xmax: 4549119 ymax: 2747790 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 4 #> name type website geometry #> #> 1 Spirit of Mozart artwork https://salzburgfoundation… (4549119 2747790) ne = nearest_edges(net, p) ne #> Simple feature collection with 1 feature and 3 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4549119 ymin: 2747723 xmax: 4549418 ymax: 2747790 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 4 #> from to geometry length #> [m] #> 1 10 11 (4549418 2747723, 4549119 2747790) 306. ggraph(net, \"sf\") + geom_sf(data = p, size = 6, pch = 8) + geom_edge_sf(color = \"grey\") + geom_node_sf(color = \"grey\", size = 4) + geom_sf(data = nn, color = \"orange\", size = 6) + theme_void() ggraph(net, \"sf\") + geom_sf(data = p, size = 6, pch = 8) + geom_edge_sf(color = \"grey\") + geom_sf(data = ne, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"grey\", size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"non-tidyverse-workflows","dir":"Articles","previous_headings":"","what":"Non-tidyverse workflows","title":"Introduction to sfnetworks","text":"Also fan tidyverse style data analysis, sfnetworks can . Since sfnetwork objects inherit igraph class, can apply functions large igraph package . means, example, instead using dplyr::mutate() dplyr::filter(), proceed follows (note igraph, term vertex used instead node). can see, returns igraph object instead sfnetwork object. preserve class, can use wrap_igraph() function sfnetworks igraph function accepts network first input returns another network. function check returned network still spatial. spatial measure functions can evaluated outside tidygraph framework using with_graph(), works similar base R’s () function. spatial morpher functions implement larger workflow internal workers exported, meaning can called directly outside tidygraph::morph() tidygraph::convert() verbs. morphers easy replicate using sf sfnetworks functions directly.","code":"# Mutate. vertex_attr(net, \"label\") = letters[1:vcount(net)] # Filter. drop = which(!sample(c(TRUE, FALSE), ecount(net), replace = TRUE)) new_net = delete_edges(net, drop) new_net #> IGRAPH 66e2aa1 UN-B 17 14 -- #> + attr: name (v/c), type (v/c), website (v/c), geometry (v/x), label #> | (v/c), geometry (e/x), length (e/n) #> + edges from 66e2aa1 (vertex names): #> [1] Mozartkino --Mozartsteg/Rudolfskai #> [2] Haus für Mozart --Mozart Denkmal #> [3] Haus für Mozart --Mozarts Geburtshaus #> [4] Mozartsteg/Rudolfskai --Mozartsteg/Rudolfskai #> [5] Mozart Denkmal --Mozartsteg/Rudolfskai #> [6] Mozart Denkmal --Mozartkugel #> [7] Mozarts Geburtshaus --Café Mozart #> + ... omitted several edges wrap_igraph(net, delete_edges, drop) #> # A sfnetwork: 17 nodes and 14 edges #> # #> # An unrooted forest with 3 trees and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 14 × 4 (active) #> from to geometry length #> [m] #> 1 1 3 (4549504 2747309, 4549589 2747507) 216. #> 2 2 4 (4549003 2747376, 4549387 2747514) 409. #> 3 2 7 (4549003 2747376, 4549064 2747619) 250. #> 4 3 5 (4549589 2747507, 4549491 2747551) 107. #> 5 4 5 (4549387 2747514, 4549491 2747551) 110. #> 6 4 9 (4549387 2747514, 4549120 2747654) 301. #> # ℹ 8 more rows #> # #> # Node data: 17 × 5 #> name type website geometry label #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) a #> 2 Haus für Mozart theatre NA (4549003 2747376) b #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) c #> # ℹ 14 more rows mst = wrap_igraph(net, mst, weights = edge_attr(net, \"length\")) ggraph(mst, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() with_graph(net, edge_circuity()) #> [1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"visualizing-spatial-networks","dir":"Articles","previous_headings":"","what":"Visualizing spatial networks","title":"Introduction to sfnetworks","text":"quickly visualize network can use plot() method sfnetwork objects. use sf plot geometries nodes edges one view. Using regular arguments plot(), can change style plot whole. Arguments node_args edge_args added can also provide style settings nodes edges separately, list-format. Default settings Custom settings Custom settings advanced visualizations, recommend use ggraph. extension {ggplot} network data works seamlessly tbl_graph data structures. fact, tidygraph initially developed idea provide suitable data structure ggraph visualizations. now also native support sfnetworks sf layout ggraph::geom_node_sf() ggraph::geom_edge_sf() geoms aware spatial nature data. Edges can also plotted without spatial embedding, using one many geoms offerend ggraph. plot additional spatial layers networks, can simply use ggplot::geom_sf(). details, check ggraph documentation. Default settings Custom settings Custom settings Additional layers want create Leaflet-based interactive maps, take look packages mapview tmap. well integrated sf, can extract nodes edges network, plot two separate layers.","code":"plot(mst) plot(mst, col = \"orange\", pch = 8, cex = 4) plot( mst, node_args = list(col = \"orange\", cex = 3), edge_args = list(col = \"grey\", lwd = 2) ) ggraph(mst, \"sf\") + geom_edge_sf() + geom_node_sf() + theme_void() ggraph(mst, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(type)), size = 4) + scale_color_discrete(\"type\") + theme_void() ggraph(mst, \"sf\") + geom_edge_fan(aes(alpha = after_stat(index)), show.legend = FALSE) + geom_node_sf(aes(size = centrality_degree()), color = \"orange\") + theme_void() ggraph(mst, \"sf\") + geom_edge_sf(color = \"grey\") + geom_node_sf(color = \"orange\", size = 4) + geom_sf( data = st_buffer(st_centroid(st_combine(mozart)), 300), fill = \"skyblue\", alpha = 0.5, linewidth = 0.8 ) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn01_intro.html","id":"learning-more","dir":"Articles","previous_headings":"","what":"Learning more","title":"Introduction to sfnetworks","text":"vignette provided introduction sfnetworks. documentation contains several vignettes dive detail: Creating representing spatial networks Cleaning spatial networks Spatial joins filters Routing spatial networks","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"the-sfnetwork-class","dir":"Articles","previous_headings":"","what":"The sfnetwork class","title":"Creating and representing spatial networks","text":"Spatial networks sfnetworks represented objects class sfnetwork. objects inherit tbl_graph class tidygraph, turn inherit igraph class igraph. means core designed store graph structures. However, thanks design tidygraph, look like collection two flat tables: one nodes, one edges. documentation tidygraph, design choice explained follows. Relational data meaningful way encoded single tidy data frame. hand, node edge data fits well within tidy concept node edge , sense, single observation. Thus, close approximation tidyness relational data two tidy data frames, one describing node data one describing edge data. Since sfnetwork class inherits tbl_graph class, shares philosophy. However, extends domain geospatial data analysis, observation location geographical space. , brings sf game. object class sf stores geographical coordinates observation standardized format geometry list-column, coordinate reference system (CRS) associated . Thus, sfnetworks, re-formulate last sentence paragraph following. close approximation tidyness relational geospatial data two sf objects, one describing node data one describing edge data. Obviously network just list two distinct elements. Nodes edges related . first two columns edges table always named contain integer indices source target node edge. integer indices correspond rownumbers nodes table. , nodes filtered, order changes, indices updated. geometries nodes edges also match. sfnetworks, following requirements specified valid geospatial network: Nodes geometries type POINT. Edges geometries type LINESTRING. endpoints edge geometries spatially equal corresponding node geometries. Nodes edge geometries coordinate reference system coordinate precision. need make note . geospatial network, nodes always coordinates geographic space, thus, can always described sf object. edges, however, can also described indices nodes ends. still makes geospatial, connect two specific points space, spatial information explicitly attached . representations can useful. geolocated social networks, example, often explicit spatial embedding edges. road networks, however, edges usually straight lines, geometries stored explicitly. sfnetworks variants supported: edges can described sf object geometries, also regular tibble without geometry column. refer spatially explicit edges spatially implicit edges, respectively. documentation, however, focus first type. figure summarizes structure sfnetwork objects. Just like tbl_graph objects, always one element (nodes edges) sfnetwork object active. means element main target analysis. default, nodes active element creating network. active element can changed using activate() verb, also change order elements printed. practice, looks follows. Note create network set spatial lines, creating nodes endpoints. See section Creating sfnetwork objects many examples create spatial network. Spatially explicit edges Spatially implicit edges sfnetwork objects possible represent networks directed edges, undirected edges. also possible mimic mixed representations edge types exist. default instance sfnetwork class initialized directed network. means edge can traveled source node target node, vice versa. case, geometry edge always matches direction, startpoint line location source node, endpoint line location target node. sfnetwork data structure also supports undirected networks. networks edge can traveled directions. Since clear source target, node lowest index referenced column, node highest index column. linestring geometry, however, remains unchanged. , undirected networks specified source node may always correspond startpoint edge geometry, instead endpoint. behavior ordering indices comes igraph might confusing, remember undirected networks terms meaning can thus used interchangeably. computation really need edge geometries match specified node indices, can use utility function make_edges_follow_indices(). function reverse edge geometries needed. sfnetworks native support represent mixed networks, .e. networks edges can traveled ways, others one way. However, type networks quite common applications spatial network analysis. example, road networks streets oneway streets. creating directed network, duplicating reversing edges undirected, can mimic mixed network structure. morpher to_spatial_mixed() exactly . Since network cleaning functions work well duplicated reversed edges, usually good idea first create directed network, clean , mimic mixed representation. makes sfnetwork objects different tbl_graph objects nodes (optionally) edges geometries. geometries stored geometry list-column, following design sf. also means just sf, columns “sticky”, survive column subsetting operations. Like sf, can always extract geometries active network element using sf::st_geometry(). shortcuts st_geometry(x, \"nodes\") st_geometry(net, \"edges\") can used extract geometries network element, regardless active . way around, can also replace geometries using setter function sf::set_set_geometry() (alternatively: st_geometry(x) = new). New node geometries required geometry type POINT, new edge geometries geometry type LINESTRING. preserve valid spatial network structure, following done: replacing node geometries, endpoints edge geometries replaced well match new node geometries. replacing edge geometries, endpoints geometries added new nodes network whenever don’t equal original location. original nodes remain network even now isolated. Original network New network can drop geometries using sf::st_drop_geometry() (alternatively: st_geometry(x) = NULL). already shown previous section, dropping edge geometries still return sfnetwork object, now spatially implicit instead spatially explicit edges. Dropping node geometries, however, return tbl_graph. area geometries occupy bounded bounding box. can use sf::st_bbox() compute bounding box active element sfnetwork object. compute bounding box full network, use st_network_bbox(). cases, network bounding box may different bounding box nodes . Element bounding boxes Network bounding box coordinates geometries always expressed specified coordinate reference system (CRS). sfnetwork object, CRS node edge geometries required equal. can extract CRS using sf::st_crs(). transform coordinates different CRS, use sf::st_transform(), specifying example EPSG code new CRS (ways specifying possible well, see documentation sf). Geometries also coordinate precision associated . precision round coordinate values, applied spatial operations. Just CRS, nodes edges sfnetwork object required precision. can extract precision using sf::st_precision(), set using sf::st_set_precision(). Precision values specified scale factor. example, specify 3 decimal places precision, use scale factor 1000. precision specified, defaults machine precision. However, sfnetworks, functions assess spatial equality nodes use default precision 1e12 (.e. 12 decimal places) speed processing. Thanks sf, also possible explicitly specify attribute-geometry relations. define attribute column attribute constant, aggregate, identity. See information. can get set attribute-geometry relations active network element function sf::st_agr(). setter, can also use pipe-friendly version sf::st_set_agr(). Note columns really attributes edges seen network analysis perspective, included attribute-geometry relation specification ensure smooth interaction sf.","code":"# Spatially explicit edges. net = as_sfnetwork(roxel) net #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows # Make edges spatially implicit. inet = net |> activate(edges) |> st_drop_geometry() inet #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 4 (active) #> from to name type #> #> 1 1 2 Hagemanns Kämpken residential #> 2 3 4 Stiegkamp residential #> 3 5 6 Havixbecker Straße residential #> 4 7 8 Holzschuhmacherweg residential #> 5 9 10 Annette-von-Droste-Hülshoff-Straße secondary #> 6 11 12 NA footway #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf() + theme_void() ggraph(inet, \"sf\") + geom_edge_link(linetype = 2) + geom_node_sf() + theme_void() as_sfnetwork(roxel, directed = FALSE) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # An undirected multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows # First we mark some streets as oneway. streets = roxel |> mutate(oneway = sample(c(TRUE, FALSE), n(), replace = TRUE, prob = c(0.8, 0.2))) # Check the distribution of oneway vs twoway streets. streets |> st_drop_geometry() |> count(oneway) #> # A tibble: 2 × 2 #> oneway n #> #> 1 FALSE 236 #> 2 TRUE 979 # Create a directed network. dnet = as_sfnetwork(streets) # Check the number of edges in the directed network. # This equals the total number of streets. n_edges(dnet) #> [1] 1215 # Convert it into a mixed network. # Oneway streets remain directed. # Twoway streets are duplicated and reversed. mnet = dnet |> convert(to_spatial_mixed, directed = oneway) # Check number of edges in the mixed network. # This equals the number of oneway streets ... # ... plus twice the number of twoway streets. n_edges(mnet) #> [1] 1451 net |> activate(edges) |> st_geometry() #> Geometry set for 1215 features #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> First 5 geometries: #> LINESTRING (7.538109 51.95286, 7.537867 51.95282) #> LINESTRING (7.537815 51.95867, 7.537015 51.95848) #> LINESTRING (7.533441 51.95578, 7.533467 51.9557... #> LINESTRING (7.525977 51.95283, 7.526581 51.95293) #> LINESTRING (7.532301 51.95559, 7.532214 51.9557... orig_net = as_sfnetwork(mozart, \"gabriel\") orig_nodes = st_geometry(orig_net, \"nodes\") new_nodes = st_jitter(orig_nodes, 250) new_net = orig_net |> st_set_geometry(new_nodes) ggraph(orig_net, \"sf\") + geom_sf(data = new_nodes, color = \"orange\") + geom_edge_sf() + geom_node_sf(color = \"darkgrey\", size = 4) + theme_void() ggraph(new_net, \"sf\") + geom_sf(data = orig_nodes, color = \"darkgrey\") + geom_edge_sf() + geom_node_sf(color = \"orange\", size = 4) + theme_void() net |> activate(nodes) |> st_drop_geometry() #> # A tbl_graph: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components #> # #> # Node Data: 987 × 0 (active) #> # #> # Edge Data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows p1 = st_point(c(1, 0)) p2 = st_point(c(0, 0.5)) p3 = st_point(c(1, 1)) p4 = st_point(c(2, 0.5)) nodes = st_sf(geometry = c(st_sfc(p1), st_sfc(p3), st_sfc(p4))) edges = st_sf(geometry = st_sfc(st_linestring(c(p1, p2, p3)))) edges$from = 1 edges$to = 2 G = sfnetwork(nodes, edges) node_bbox = G |> st_bbox() |> st_as_sfc() edge_bbox = G |> activate(edges) |> st_bbox() |> st_as_sfc() net_bbox = G |> st_network_bbox() |> st_as_sfc() ggraph(G, \"sf\") + geom_sf( data = node_bbox, color = \"#F8766D\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_sf( data = edge_bbox, color = \"#619CFF\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(G, \"sf\") + geom_sf( data = net_bbox, color = \"orange\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() st_transform(net, 3035) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150707 ymin: 3206375 xmax: 4152366 ymax: 3208564 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (4151782 3207612) #> 2 (4151765 3207609) #> 3 (4151784 3208259) #> 4 (4151728 3208240) #> 5 (4151472 3207948) #> 6 (4151470 3207929) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (4151782 3207612, 4151765 3207609) #> 2 3 4 Stiegkamp residential (4151784 3208259, 4151728 3208240) #> 3 5 6 Havixbecker Straße residential (4151472 3207948, 4151474 3207941,… #> # ℹ 1,212 more rows # With unspecified precision, no node is equal to another node. any(lengths(st_equals(net)) > 1) #> [1] FALSE # With an extremely low precision, all nodes are equal to each other. all(lengths(st_equals(st_set_precision(net, 1))) == n_nodes(net)) #> [1] TRUE net |> activate(edges) |> st_agr() #> from to name type #> constant constant #> Levels: constant aggregate identity net |> activate(edges) |> st_set_agr(c(type = \"aggregate\")) |> st_agr() #> from to name type #> constant aggregate #> Levels: constant aggregate identity"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"structure","dir":"Articles","previous_headings":"","what":"Structure","title":"Creating and representing spatial networks","text":"Obviously network just list two distinct elements. Nodes edges related . first two columns edges table always named contain integer indices source target node edge. integer indices correspond rownumbers nodes table. , nodes filtered, order changes, indices updated. geometries nodes edges also match. sfnetworks, following requirements specified valid geospatial network: Nodes geometries type POINT. Edges geometries type LINESTRING. endpoints edge geometries spatially equal corresponding node geometries. Nodes edge geometries coordinate reference system coordinate precision. need make note . geospatial network, nodes always coordinates geographic space, thus, can always described sf object. edges, however, can also described indices nodes ends. still makes geospatial, connect two specific points space, spatial information explicitly attached . representations can useful. geolocated social networks, example, often explicit spatial embedding edges. road networks, however, edges usually straight lines, geometries stored explicitly. sfnetworks variants supported: edges can described sf object geometries, also regular tibble without geometry column. refer spatially explicit edges spatially implicit edges, respectively. documentation, however, focus first type. figure summarizes structure sfnetwork objects. Just like tbl_graph objects, always one element (nodes edges) sfnetwork object active. means element main target analysis. default, nodes active element creating network. active element can changed using activate() verb, also change order elements printed. practice, looks follows. Note create network set spatial lines, creating nodes endpoints. See section Creating sfnetwork objects many examples create spatial network. Spatially explicit edges Spatially implicit edges","code":"# Spatially explicit edges. net = as_sfnetwork(roxel) net #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows # Make edges spatially implicit. inet = net |> activate(edges) |> st_drop_geometry() inet #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 4 (active) #> from to name type #> #> 1 1 2 Hagemanns Kämpken residential #> 2 3 4 Stiegkamp residential #> 3 5 6 Havixbecker Straße residential #> 4 7 8 Holzschuhmacherweg residential #> 5 9 10 Annette-von-Droste-Hülshoff-Straße secondary #> 6 11 12 NA footway #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf() + theme_void() ggraph(inet, \"sf\") + geom_edge_link(linetype = 2) + geom_node_sf() + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"directionality","dir":"Articles","previous_headings":"","what":"Directionality","title":"Creating and representing spatial networks","text":"sfnetwork objects possible represent networks directed edges, undirected edges. also possible mimic mixed representations edge types exist. default instance sfnetwork class initialized directed network. means edge can traveled source node target node, vice versa. case, geometry edge always matches direction, startpoint line location source node, endpoint line location target node. sfnetwork data structure also supports undirected networks. networks edge can traveled directions. Since clear source target, node lowest index referenced column, node highest index column. linestring geometry, however, remains unchanged. , undirected networks specified source node may always correspond startpoint edge geometry, instead endpoint. behavior ordering indices comes igraph might confusing, remember undirected networks terms meaning can thus used interchangeably. computation really need edge geometries match specified node indices, can use utility function make_edges_follow_indices(). function reverse edge geometries needed. sfnetworks native support represent mixed networks, .e. networks edges can traveled ways, others one way. However, type networks quite common applications spatial network analysis. example, road networks streets oneway streets. creating directed network, duplicating reversing edges undirected, can mimic mixed network structure. morpher to_spatial_mixed() exactly . Since network cleaning functions work well duplicated reversed edges, usually good idea first create directed network, clean , mimic mixed representation.","code":"as_sfnetwork(roxel, directed = FALSE) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # An undirected multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows # First we mark some streets as oneway. streets = roxel |> mutate(oneway = sample(c(TRUE, FALSE), n(), replace = TRUE, prob = c(0.8, 0.2))) # Check the distribution of oneway vs twoway streets. streets |> st_drop_geometry() |> count(oneway) #> # A tibble: 2 × 2 #> oneway n #> #> 1 FALSE 236 #> 2 TRUE 979 # Create a directed network. dnet = as_sfnetwork(streets) # Check the number of edges in the directed network. # This equals the total number of streets. n_edges(dnet) #> [1] 1215 # Convert it into a mixed network. # Oneway streets remain directed. # Twoway streets are duplicated and reversed. mnet = dnet |> convert(to_spatial_mixed, directed = oneway) # Check number of edges in the mixed network. # This equals the number of oneway streets ... # ... plus twice the number of twoway streets. n_edges(mnet) #> [1] 1451"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"directed-networks","dir":"Articles","previous_headings":"","what":"Directed networks","title":"Creating and representing spatial networks","text":"default instance sfnetwork class initialized directed network. means edge can traveled source node target node, vice versa. case, geometry edge always matches direction, startpoint line location source node, endpoint line location target node.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"undirected-networks","dir":"Articles","previous_headings":"","what":"Undirected networks","title":"Creating and representing spatial networks","text":"sfnetwork data structure also supports undirected networks. networks edge can traveled directions. Since clear source target, node lowest index referenced column, node highest index column. linestring geometry, however, remains unchanged. , undirected networks specified source node may always correspond startpoint edge geometry, instead endpoint. behavior ordering indices comes igraph might confusing, remember undirected networks terms meaning can thus used interchangeably. computation really need edge geometries match specified node indices, can use utility function make_edges_follow_indices(). function reverse edge geometries needed.","code":"as_sfnetwork(roxel, directed = FALSE) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # An undirected multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"mixed-networks","dir":"Articles","previous_headings":"","what":"Mixed networks","title":"Creating and representing spatial networks","text":"sfnetworks native support represent mixed networks, .e. networks edges can traveled ways, others one way. However, type networks quite common applications spatial network analysis. example, road networks streets oneway streets. creating directed network, duplicating reversing edges undirected, can mimic mixed network structure. morpher to_spatial_mixed() exactly . Since network cleaning functions work well duplicated reversed edges, usually good idea first create directed network, clean , mimic mixed representation.","code":"# First we mark some streets as oneway. streets = roxel |> mutate(oneway = sample(c(TRUE, FALSE), n(), replace = TRUE, prob = c(0.8, 0.2))) # Check the distribution of oneway vs twoway streets. streets |> st_drop_geometry() |> count(oneway) #> # A tibble: 2 × 2 #> oneway n #> #> 1 FALSE 236 #> 2 TRUE 979 # Create a directed network. dnet = as_sfnetwork(streets) # Check the number of edges in the directed network. # This equals the total number of streets. n_edges(dnet) #> [1] 1215 # Convert it into a mixed network. # Oneway streets remain directed. # Twoway streets are duplicated and reversed. mnet = dnet |> convert(to_spatial_mixed, directed = oneway) # Check number of edges in the mixed network. # This equals the number of oneway streets ... # ... plus twice the number of twoway streets. n_edges(mnet) #> [1] 1451"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"geometries","dir":"Articles","previous_headings":"","what":"Geometries","title":"Creating and representing spatial networks","text":"makes sfnetwork objects different tbl_graph objects nodes (optionally) edges geometries. geometries stored geometry list-column, following design sf. also means just sf, columns “sticky”, survive column subsetting operations. Like sf, can always extract geometries active network element using sf::st_geometry(). shortcuts st_geometry(x, \"nodes\") st_geometry(net, \"edges\") can used extract geometries network element, regardless active . way around, can also replace geometries using setter function sf::set_set_geometry() (alternatively: st_geometry(x) = new). New node geometries required geometry type POINT, new edge geometries geometry type LINESTRING. preserve valid spatial network structure, following done: replacing node geometries, endpoints edge geometries replaced well match new node geometries. replacing edge geometries, endpoints geometries added new nodes network whenever don’t equal original location. original nodes remain network even now isolated. Original network New network can drop geometries using sf::st_drop_geometry() (alternatively: st_geometry(x) = NULL). already shown previous section, dropping edge geometries still return sfnetwork object, now spatially implicit instead spatially explicit edges. Dropping node geometries, however, return tbl_graph. area geometries occupy bounded bounding box. can use sf::st_bbox() compute bounding box active element sfnetwork object. compute bounding box full network, use st_network_bbox(). cases, network bounding box may different bounding box nodes . Element bounding boxes Network bounding box coordinates geometries always expressed specified coordinate reference system (CRS). sfnetwork object, CRS node edge geometries required equal. can extract CRS using sf::st_crs(). transform coordinates different CRS, use sf::st_transform(), specifying example EPSG code new CRS (ways specifying possible well, see documentation sf). Geometries also coordinate precision associated . precision round coordinate values, applied spatial operations. Just CRS, nodes edges sfnetwork object required precision. can extract precision using sf::st_precision(), set using sf::st_set_precision(). Precision values specified scale factor. example, specify 3 decimal places precision, use scale factor 1000. precision specified, defaults machine precision. However, sfnetworks, functions assess spatial equality nodes use default precision 1e12 (.e. 12 decimal places) speed processing. Thanks sf, also possible explicitly specify attribute-geometry relations. define attribute column attribute constant, aggregate, identity. See information. can get set attribute-geometry relations active network element function sf::st_agr(). setter, can also use pipe-friendly version sf::st_set_agr(). Note columns really attributes edges seen network analysis perspective, included attribute-geometry relation specification ensure smooth interaction sf.","code":"net |> activate(edges) |> st_geometry() #> Geometry set for 1215 features #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> First 5 geometries: #> LINESTRING (7.538109 51.95286, 7.537867 51.95282) #> LINESTRING (7.537815 51.95867, 7.537015 51.95848) #> LINESTRING (7.533441 51.95578, 7.533467 51.9557... #> LINESTRING (7.525977 51.95283, 7.526581 51.95293) #> LINESTRING (7.532301 51.95559, 7.532214 51.9557... orig_net = as_sfnetwork(mozart, \"gabriel\") orig_nodes = st_geometry(orig_net, \"nodes\") new_nodes = st_jitter(orig_nodes, 250) new_net = orig_net |> st_set_geometry(new_nodes) ggraph(orig_net, \"sf\") + geom_sf(data = new_nodes, color = \"orange\") + geom_edge_sf() + geom_node_sf(color = \"darkgrey\", size = 4) + theme_void() ggraph(new_net, \"sf\") + geom_sf(data = orig_nodes, color = \"darkgrey\") + geom_edge_sf() + geom_node_sf(color = \"orange\", size = 4) + theme_void() net |> activate(nodes) |> st_drop_geometry() #> # A tbl_graph: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components #> # #> # Node Data: 987 × 0 (active) #> # #> # Edge Data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows p1 = st_point(c(1, 0)) p2 = st_point(c(0, 0.5)) p3 = st_point(c(1, 1)) p4 = st_point(c(2, 0.5)) nodes = st_sf(geometry = c(st_sfc(p1), st_sfc(p3), st_sfc(p4))) edges = st_sf(geometry = st_sfc(st_linestring(c(p1, p2, p3)))) edges$from = 1 edges$to = 2 G = sfnetwork(nodes, edges) node_bbox = G |> st_bbox() |> st_as_sfc() edge_bbox = G |> activate(edges) |> st_bbox() |> st_as_sfc() net_bbox = G |> st_network_bbox() |> st_as_sfc() ggraph(G, \"sf\") + geom_sf( data = node_bbox, color = \"#F8766D\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_sf( data = edge_bbox, color = \"#619CFF\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(G, \"sf\") + geom_sf( data = net_bbox, color = \"orange\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() st_transform(net, 3035) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150707 ymin: 3206375 xmax: 4152366 ymax: 3208564 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (4151782 3207612) #> 2 (4151765 3207609) #> 3 (4151784 3208259) #> 4 (4151728 3208240) #> 5 (4151472 3207948) #> 6 (4151470 3207929) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (4151782 3207612, 4151765 3207609) #> 2 3 4 Stiegkamp residential (4151784 3208259, 4151728 3208240) #> 3 5 6 Havixbecker Straße residential (4151472 3207948, 4151474 3207941,… #> # ℹ 1,212 more rows # With unspecified precision, no node is equal to another node. any(lengths(st_equals(net)) > 1) #> [1] FALSE # With an extremely low precision, all nodes are equal to each other. all(lengths(st_equals(st_set_precision(net, 1))) == n_nodes(net)) #> [1] TRUE net |> activate(edges) |> st_agr() #> from to name type #> constant constant #> Levels: constant aggregate identity net |> activate(edges) |> st_set_agr(c(type = \"aggregate\")) |> st_agr() #> from to name type #> constant aggregate #> Levels: constant aggregate identity"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"extract-geometries","dir":"Articles","previous_headings":"","what":"Extract geometries","title":"Creating and representing spatial networks","text":"Like sf, can always extract geometries active network element using sf::st_geometry(). shortcuts st_geometry(x, \"nodes\") st_geometry(net, \"edges\") can used extract geometries network element, regardless active .","code":"net |> activate(edges) |> st_geometry() #> Geometry set for 1215 features #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> First 5 geometries: #> LINESTRING (7.538109 51.95286, 7.537867 51.95282) #> LINESTRING (7.537815 51.95867, 7.537015 51.95848) #> LINESTRING (7.533441 51.95578, 7.533467 51.9557... #> LINESTRING (7.525977 51.95283, 7.526581 51.95293) #> LINESTRING (7.532301 51.95559, 7.532214 51.9557..."},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"replace-geometries","dir":"Articles","previous_headings":"","what":"Replace geometries","title":"Creating and representing spatial networks","text":"way around, can also replace geometries using setter function sf::set_set_geometry() (alternatively: st_geometry(x) = new). New node geometries required geometry type POINT, new edge geometries geometry type LINESTRING. preserve valid spatial network structure, following done: replacing node geometries, endpoints edge geometries replaced well match new node geometries. replacing edge geometries, endpoints geometries added new nodes network whenever don’t equal original location. original nodes remain network even now isolated. Original network New network","code":"orig_net = as_sfnetwork(mozart, \"gabriel\") orig_nodes = st_geometry(orig_net, \"nodes\") new_nodes = st_jitter(orig_nodes, 250) new_net = orig_net |> st_set_geometry(new_nodes) ggraph(orig_net, \"sf\") + geom_sf(data = new_nodes, color = \"orange\") + geom_edge_sf() + geom_node_sf(color = \"darkgrey\", size = 4) + theme_void() ggraph(new_net, \"sf\") + geom_sf(data = orig_nodes, color = \"darkgrey\") + geom_edge_sf() + geom_node_sf(color = \"orange\", size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"drop-geometries","dir":"Articles","previous_headings":"","what":"Drop geometries","title":"Creating and representing spatial networks","text":"can drop geometries using sf::st_drop_geometry() (alternatively: st_geometry(x) = NULL). already shown previous section, dropping edge geometries still return sfnetwork object, now spatially implicit instead spatially explicit edges. Dropping node geometries, however, return tbl_graph.","code":"net |> activate(nodes) |> st_drop_geometry() #> # A tbl_graph: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components #> # #> # Node Data: 987 × 0 (active) #> # #> # Edge Data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"bounding-box","dir":"Articles","previous_headings":"","what":"Bounding box","title":"Creating and representing spatial networks","text":"area geometries occupy bounded bounding box. can use sf::st_bbox() compute bounding box active element sfnetwork object. compute bounding box full network, use st_network_bbox(). cases, network bounding box may different bounding box nodes . Element bounding boxes Network bounding box","code":"p1 = st_point(c(1, 0)) p2 = st_point(c(0, 0.5)) p3 = st_point(c(1, 1)) p4 = st_point(c(2, 0.5)) nodes = st_sf(geometry = c(st_sfc(p1), st_sfc(p3), st_sfc(p4))) edges = st_sf(geometry = st_sfc(st_linestring(c(p1, p2, p3)))) edges$from = 1 edges$to = 2 G = sfnetwork(nodes, edges) node_bbox = G |> st_bbox() |> st_as_sfc() edge_bbox = G |> activate(edges) |> st_bbox() |> st_as_sfc() net_bbox = G |> st_network_bbox() |> st_as_sfc() ggraph(G, \"sf\") + geom_sf( data = node_bbox, color = \"#F8766D\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_sf( data = edge_bbox, color = \"#619CFF\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(G, \"sf\") + geom_sf( data = net_bbox, color = \"orange\", fill = NA, linewidth = 1.5, linetype = 4 ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"coordinate-reference-system","dir":"Articles","previous_headings":"","what":"Coordinate reference system","title":"Creating and representing spatial networks","text":"coordinates geometries always expressed specified coordinate reference system (CRS). sfnetwork object, CRS node edge geometries required equal. can extract CRS using sf::st_crs(). transform coordinates different CRS, use sf::st_transform(), specifying example EPSG code new CRS (ways specifying possible well, see documentation sf).","code":"st_transform(net, 3035) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150707 ymin: 3206375 xmax: 4152366 ymax: 3208564 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (4151782 3207612) #> 2 (4151765 3207609) #> 3 (4151784 3208259) #> 4 (4151728 3208240) #> 5 (4151472 3207948) #> 6 (4151470 3207929) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (4151782 3207612, 4151765 3207609) #> 2 3 4 Stiegkamp residential (4151784 3208259, 4151728 3208240) #> 3 5 6 Havixbecker Straße residential (4151472 3207948, 4151474 3207941,… #> # ℹ 1,212 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"coordinate-precision","dir":"Articles","previous_headings":"","what":"Coordinate precision","title":"Creating and representing spatial networks","text":"Geometries also coordinate precision associated . precision round coordinate values, applied spatial operations. Just CRS, nodes edges sfnetwork object required precision. can extract precision using sf::st_precision(), set using sf::st_set_precision(). Precision values specified scale factor. example, specify 3 decimal places precision, use scale factor 1000. precision specified, defaults machine precision. However, sfnetworks, functions assess spatial equality nodes use default precision 1e12 (.e. 12 decimal places) speed processing.","code":"# With unspecified precision, no node is equal to another node. any(lengths(st_equals(net)) > 1) #> [1] FALSE # With an extremely low precision, all nodes are equal to each other. all(lengths(st_equals(st_set_precision(net, 1))) == n_nodes(net)) #> [1] TRUE"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"attribute-geometry-relations","dir":"Articles","previous_headings":"","what":"Attribute-geometry relations","title":"Creating and representing spatial networks","text":"Thanks sf, also possible explicitly specify attribute-geometry relations. define attribute column attribute constant, aggregate, identity. See information. can get set attribute-geometry relations active network element function sf::st_agr(). setter, can also use pipe-friendly version sf::st_set_agr(). Note columns really attributes edges seen network analysis perspective, included attribute-geometry relation specification ensure smooth interaction sf.","code":"net |> activate(edges) |> st_agr() #> from to name type #> constant constant #> Levels: constant aggregate identity net |> activate(edges) |> st_set_agr(c(type = \"aggregate\")) |> st_agr() #> from to name type #> constant aggregate #> Levels: constant aggregate identity"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"creating-sfnetwork-objects","dir":"Articles","previous_headings":"","what":"Creating sfnetwork objects","title":"Creating and representing spatial networks","text":"several ways create sfnetwork object, discussed detail . basic way create sfnetwork object provide ready--use node edge tables sfnetwork() construction function. Remember nodes sf object POINT geometries, first two columns edges table required named contain rownumbers nodes start end edge. edges spatially explicit, hence, also geometries, type LINESTRING endpoints equal locations source target nodes. construction function check provided input meets criteria. already sure data forms valid spatial network, can set force = TRUE. also possible provide nodes sf object, can converted . example, table two coordinate columns. additional arguments provided sfnetwork() construction function forwarded sf::st_as_sf() convert provided nodes table sf object. Instead integers referring rownumbers nodes table, columns edges table can also contain characters refer values specific node attribute column. name column given argument node_key. default, assumed column named name. Internally, construction function convert character values integer indices referencing rownumbers. edges geometries, can still create network spatially explicit edges setting edges_as_lines = TRUE. create linestring geometries straight lines source target nodes. common way create spatial network start set LINESTRING geometries sf format. assumed edge network. Providing as_sfnetwork() automatically call create_from_spatial_lines(). function creates nodes endpoints lines. Endpoints shared multiple lines, become single node network. determine spatial equality endpoints, sfnetworks default uses 12-digit precision coordinates. can change either setting different precision (see ) effectively rounding coordinate values using utility function st_round(). Lines Network Besides endpoints, linestring geometries may interior points define shape. may multiple linestrings interior points location. Since endpoints, become node network. also want add nodes shared interior points, set subdivide = TRUE, call to_spatial_subdivision() morpher construction. See vignette Spatial morphers details. also possible create network set POINT geometries. assumed nodes network. Providing as_sfnetwork() automatically call create_from_spatial_points(). second input requires adjacency matrix specifies nodes connected . Adjacency matrices networks n×nn \\times n matrices nn number nodes, element AijA_{ij} holding value edge node ii node jj, value otherwise. Points Network adjacency matrix can also provided sparse form, node indices nodes connected listed. allows directly forward output binary spatial predicate. example, using sf::st_is_within_distance(), can connect nodes within given distance . Points Network Finally, sfnetworks can create adjacency matrix internally according specified method. case, just need provide name method. Supported options currently : complete: nodes directly connected . sequence: nodes sequentially connected , meaning first node connected second node, second node connected third node, etc. minimum_spanning_tree: nodes connected spatial minimum spanning tree, .e. set edges minimum total edge length required connect nodes. Can also specified mst. delaunay: nodes connected Delaunay triangulation. Requires spdep package installed, assumes planar coordinates. gabriel: nodes connected Gabriel graph. Requires spdep package installed, assumes planar coordinates. relative_neighborhood: nodes connected relative neighborhood graph. Can also specified rn. Requires spdep package installed, assumes planar coordinates. nearest_neighbors: node connected kk nearest neighbors, kk specified k argument. default, k = 1, meaning nodes connected nearest neighbor graph. Can also specified knn. Requires spdep package installed. Complete Sequential Minimum spanning tree Delaunay triangulation Gabriel Relative neighbors Nearest neighbors K nearest neighbors (k = 3) conversion function as_sfnetwork() can also used convert instances network classes sfnetwork object. includes classes also designed spatial networks, dodgr_streetnet dodgr package routing street networks, linnet spatstat.linnet package statistical point pattern analysis spatial linear networks. However, can also used convert instances non-spatial network formats, long specify way spatial location nodes. example, igraph object x y coordinates stored node attributes. case, additional arguments provided as_sfnetwork() forwarded sf::st_as_sf() convert nodes given network sf object. currently functions sfnetworks reading writing data (ideas). However, can use sf::st_read() spatial file formats read points /lines, construct network using sfnetwork() (described ) as_sfnetwork() (described lines points). network specific file types, can use igraph::read_graph() read data R, convert spatial network format using as_sfnetwork() long required spatial information present (see ). common format latter category GraphML. example file can found , containing power grid Netherlands. reading using igraph, first convert tbl_graph can easily explore data. can see spatial geometries nodes edges stored WKT strings columns named wktsrid4326. Remember additional arguments as_sfnetwork() igraph objects forwarded sf::st_as_sf() convert nodes sf object. makes conversion sfnetwork object easy : However, affect nodes table (since one required geometries). edges explicit geometries yet. Using morpher function to_spatial_explicit(), can “explicitize” edge geometries constructed network. Also , additional arguments forwarded sf::st_as_sf(). common source spatial network data OpenStreetMap.open collaborative geographic database. can used example extract geometries streets rivers anywhere world. R, two main packages allow read OpenStreetMap data: osmdata package provides interface Overpass API OpenStreetMap. osmextract package can read OpenStreetMap data osm.pbf files. small areas repeated calls, Overpass API easiest way get data. However, area interest large, want load data many times, preferred overload API read osm.pbf files instead. Geofabrik one platforms can download files many different regions world. , show small example using osmdata. can read street centerlines Anif, small village Austria, shown . details workflow, check osmdata documentation. Now, can simply create network lines using as_sfnetwork(), shown . However, need aware OpenStreetMap data created primarily network structure mind. means locations two streets connect always endpoints linestring geometries, can interior point geometry well. setting subdivide = TRUE linestring geometries subdivided places interior point shared multiple features. way, node placed locations. function play_geometric() creates random geometric graph. randomly samples nn nodes, connects edge within given distance threshold . default, sampling take place unit square. However, bounds argument can also provide spatial feature sample . use sf::st_sample() internally. Random network Random network B","code":"p1 = st_point(c(6, 52)) p2 = st_point(c(8, 53)) p3 = st_point(c(8, 51)) l1 = st_linestring(c(p1, p2)) l2 = st_linestring(c(p2, p3)) l3 = st_linestring(c(p3, p1)) edges = st_sf(geometry = st_sfc(l1, l2, l3), crs = 4326) nodes = st_sf(geometry = st_sfc(p1, p2, p3), crs = 4326) edges$from = c(1, 2, 3) edges$to = c(2, 3, 1) net = sfnetwork(nodes, edges) net #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 6 ymin: 51 xmax: 8 ymax: 53 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 1 (active) #> geometry #> #> 1 (6 52) #> 2 (8 53) #> 3 (8 51) #> # #> # Edge data: 3 × 3 #> from to geometry #> #> 1 1 2 (6 52, 8 53) #> 2 2 3 (8 53, 8 51) #> 3 3 1 (8 51, 6 52) nodes_tbl = tibble(x = c(6, 8, 8), y = c(52, 53, 51)) net = sfnetwork(nodes_tbl, edges, coords = c(\"x\", \"y\"), crs = 4326) net #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 6 ymin: 51 xmax: 8 ymax: 53 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 1 (active) #> geometry #> #> 1 (6 52) #> 2 (8 53) #> 3 (8 51) #> # #> # Edge data: 3 × 3 #> from to geometry #> #> 1 1 2 (6 52, 8 53) #> 2 2 3 (8 53, 8 51) #> 3 3 1 (8 51, 6 52) nodes$type = c(\"city\", \"village\", \"farm\") edges = st_drop_geometry(edges) edges$from = c(\"city\", \"village\", \"farm\") edges$to = c(\"village\", \"farm\", \"city\") net = sfnetwork(nodes, edges, node_key = \"type\", edges_as_lines = TRUE) net #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 6 ymin: 51 xmax: 8 ymax: 53 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 2 (active) #> geometry type #> #> 1 (6 52) city #> 2 (8 53) village #> 3 (8 51) farm #> # #> # Edge data: 3 × 3 #> from to geometry #> #> 1 1 2 (6 52, 8 53) #> 2 2 3 (8 53, 8 51) #> 3 3 1 (8 51, 6 52) ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(type)), size = 4) + scale_color_discrete(\"type\") + theme_void() # Linestring geometries. roxel #> Simple feature collection with 1215 features and 2 fields #> Attribute-geometry relationships: constant (2) #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 1,215 × 3 #> name type geometry #> #> 1 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 … #> 2 Stiegkamp residential (7.537815 51.95867, 7.537015 … #> 3 Havixbecker Straße residential (7.533441 51.95578, 7.533467 … #> 4 Holzschuhmacherweg residential (7.525977 51.95283, 7.526581 … #> 5 Annette-von-Droste-Hülshoff-Straße secondary (7.532301 51.95559, 7.532214 … #> 6 NA footway (7.543404 51.94779, 7.54358 5… #> 7 Deermannskamp residential (7.537675 51.95689, 7.537904 … #> 8 Lindenstraße residential (7.539105 51.9504, 7.540105 5… #> 9 NA NA (7.534875 51.95795, 7.534819 … #> 10 Annette-von-Droste-Hülshoff-Straße secondary (7.532465 51.95424, 7.532469 … #> # ℹ 1,205 more rows # Network. net = as_sfnetwork(roxel) net #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows ggplot(roxel) + geom_sf() + theme_void() ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf() + theme_void() # Point geometries. mozart #> Simple feature collection with 17 features and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 17 × 4 #> name type website geometry #> * #> 1 Mozartkino cinema https://www.… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> 4 Mozart Denkmal artwork NA (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) #> 6 Mozartsteg bridge NA (4549473 2747624) #> 7 Mozarts Geburtshaus museum http://www.m… (4549064 2747619) #> 8 Café Mozart cafe https://www.… (4548994 2747632) #> 9 Mozartkugel confectionery NA (4549120 2747654) #> 10 Mozartsteg/Imbergstraße bus_stop NA (4549418 2747723) #> 11 Spirit of Mozart artwork https://salz… (4549119 2747790) #> 12 Mozart-Eine Hommage artwork https://salz… (4548664 2747868) #> 13 Mozarts Wohnhaus apartments NA (4549073 2747916) #> 14 Universität Mozarteum university NA (4549059 2748042) #> 15 Stiftung Mozarteum concert_hall NA (4548897 2748037) #> 16 Hotel Mozart hotel http://www.h… (4549378 2748391) #> 17 Mozart Studentenheim dormitory NA (4548984 2748537) # Adjacency matrix. adj = matrix(c(rep(TRUE, 17), rep(rep(FALSE, 17), 16)), nrow = 17) # Network. net = as_sfnetwork(mozart, adj) net #> # A sfnetwork: 17 nodes and 17 edges #> # #> # A bipartite multigraph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 4 (active) #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> 4 Mozart Denkmal artwork NA (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) #> 6 Mozartsteg bridge NA (4549473 2747624) #> # ℹ 11 more rows #> # #> # Edge data: 17 × 3 #> from to geometry #> #> 1 1 1 (4549504 2747309, 4549504 2747309) #> 2 2 1 (4549003 2747376, 4549504 2747309) #> 3 3 1 (4549589 2747507, 4549504 2747309) #> # ℹ 14 more rows ggplot(mozart) + geom_sf(size = 4) + theme_void() ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() adj = st_is_within_distance(mozart, dist = set_units(250, \"m\")) adj #> Sparse geometry binary predicate list of length 17, where the predicate #> was `is_within_distance' #> first 10 elements: #> 1: 1, 3, 4, 5 #> 2: 2 #> 3: 1, 3, 4, 5, 6 #> 4: 1, 3, 4, 5, 6, 10 #> 5: 1, 3, 4, 5, 6, 10 #> 6: 3, 4, 5, 6, 10 #> 7: 7, 8, 9, 11 #> 8: 7, 8, 9, 11 #> 9: 7, 8, 9, 11 #> 10: 4, 5, 6, 10 net = as_sfnetwork(mozart, adj) ggplot(mozart) + geom_sf(size = 4) + theme_void() ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() make_ggraph = function(x) { ggraph(x, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() } make_ggraph(as_sfnetwork(mozart, \"complete\")) make_ggraph(as_sfnetwork(mozart, \"sequence\")) make_ggraph(as_sfnetwork(mozart, \"mst\")) make_ggraph(as_sfnetwork(mozart, \"delaunay\")) make_ggraph(as_sfnetwork(mozart, \"gabriel\")) make_ggraph(as_sfnetwork(mozart, \"rn\")) make_ggraph(as_sfnetwork(mozart, \"knn\")) #> Warning in spdep::knn2nb(spdep::knearneigh(st_geometry(x), k = k), sym = #> FALSE): neighbour object has 4 sub-graphs make_ggraph(as_sfnetwork(mozart, \"knn\", k = 3)) #> Warning in spdep::knn2nb(spdep::knearneigh(st_geometry(x), k = k), sym = #> FALSE): neighbour object has 2 sub-graphs # igraph object. inet = igraph::sample_grg(5, 0.5, coords = TRUE) inet #> IGRAPH 037109b U--- 5 2 -- Geometric random graph #> + attr: name (g/c), radius (g/n), torus (g/l), x (v/n), y (v/n) #> + edges from 037109b: #> [1] 2--3 4--5 # sfnetwork object. net = as_sfnetwork(inet, coords = c(\"x\", \"y\")) net #> # A sfnetwork: 5 nodes and 2 edges #> # #> # An unrooted forest with 3 trees and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0.111582 ymin: 0.3144644 xmax: 0.9832471 ymax: 0.9943113 #> # CRS: NA #> # #> # Node data: 5 × 1 (active) #> geometry #> #> 1 (0.111582 0.968579) #> 2 (0.3840216 0.4292271) #> 3 (0.8146119 0.3144644) #> 4 (0.8447424 0.9943113) #> 5 (0.9832471 0.9893714) #> # #> # Edge data: 2 × 2 #> from to #> #> 1 2 3 #> 2 4 5 url = \"https://raw.githubusercontent.com/ComplexNetTSP/Power_grids/v1.0.0/Countries/Netherlands/graphml/Netherlands_highvoltage.graphml\" igraph::read_graph(url, format = \"graphml\") |> as_tbl_graph() #> # A tbl_graph: 91 nodes and 101 edges #> # #> # An undirected simple graph with 2 components #> # #> # Node Data: 91 × 14 (active) #> netcapacity typ wktsrid4326 lat voltage frequency ngen operator lon #> #> 1 \"\" substat… SRID=4326;… 52.3… 110000 \"\" \"\" \"TenneT\" 6.67… #> 2 \"\" substat… SRID=4326;… 52.2… 110000 \"\" \"\" \"\" 6.83… #> 3 \"\" substat… SRID=4326;… 53.4… 220000 \"\" \"\" \"TenneT\" 6.86… #> 4 \"\" joint SRID=4326;… 53.2… 220000… \"50;50;5… \"\" \"TenneT\" 6.47… #> 5 \"\" joint SRID=4326;… 51.4… 150000… \"50;50;5… \"\" \"TenneT\" 5.62… #> 6 \"\" joint SRID=4326;… 52.4… 150000… \"50;50;5… \"\" \"TenneT\" 4.87… #> 7 \"\" joint SRID=4326;… 52.4… 380000… \"50;50;5… \"\" \"TenneT\" 4.87… #> 8 \"\" substat… SRID=4326;… 52.4… 380000… \"\" \"\" \"TenneT\" 4.87… #> 9 \"\" substat… SRID=4326;… 51.8… 380000 \"\" \"\" \"TenneT\" 4.26… #> 10 \"\" substat… SRID=4326;… 51.6… 380000… \"\" \"\" \"TenneT\" 5.91… #> # ℹ 81 more rows #> # ℹ 5 more variables: ref , source , name , capacity , #> # id #> # #> # Edge Data: 101 × 18 #> from to rohmkm cables wktsrid4326 operator type lengthm voltage frequency #> #> 1 1 52 \"\" 6;3;3… SRID=4326;… \"\" line 49125.… 380000… 50 #> 2 1 21 \"\" 3;3;3… SRID=4326;… \"TenneT\" line 7653.0… 110000… 50;50 #> 3 2 23 \"\" 6;6 SRID=4326;… \"TenneT\" line 6135.3… 380000… 50 #> # ℹ 98 more rows #> # ℹ 8 more variables: cnfkm , fromrelation , ref , name , #> # xohmkm , wires , ithmaxa , lid net = igraph::read_graph(url, format = \"graphml\") |> as_sfnetwork(wkt = \"wktsrid4326\", crs = 4326) |> rename(geometry = wktsrid4326) net #> # A sfnetwork: 91 nodes and 101 edges #> # #> # An undirected simple graph with 2 components and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 3.692428 ymin: 51.14805 xmax: 7.041048 ymax: 53.44424 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 91 × 14 (active) #> netcapacity typ geometry lat voltage frequency ngen #> #> 1 \"\" substation (6.679331 52.32104) 52.3210417… 110000 \"\" \"\" #> 2 \"\" substation (6.830673 52.2139) 52.2139014… 110000 \"\" \"\" #> 3 \"\" substation (6.869683 53.42999) 53.4299869… 220000 \"\" \"\" #> 4 \"\" joint (6.474364 53.21321) 53.2132104… 220000… \"50;50;5… \"\" #> 5 \"\" joint (5.621211 51.45516) 51.4551594… 150000… \"50;50;5… \"\" #> 6 \"\" joint (4.873691 52.42842) 52.4284153… 150000… \"50;50;5… \"\" #> # ℹ 85 more rows #> # ℹ 7 more variables: operator , lon , ref , source , #> # name , capacity , id #> # #> # Edge data: 101 × 18 #> from to rohmkm cables wktsrid4326 operator type lengthm voltage frequency #> #> 1 1 52 \"\" 6;3;3… SRID=4326;… \"\" line 49125.… 380000… 50 #> 2 1 21 \"\" 3;3;3… SRID=4326;… \"TenneT\" line 7653.0… 110000… 50;50 #> 3 2 23 \"\" 6;6 SRID=4326;… \"TenneT\" line 6135.3… 380000… 50 #> # ℹ 98 more rows #> # ℹ 8 more variables: cnfkm , fromrelation , ref , name , #> # xohmkm , wires , ithmaxa , lid net = net |> convert(to_spatial_explicit, wkt = \"wktsrid4326\", crs = 4326, .clean = TRUE) |> activate(edges) |> rename(geometry = wktsrid4326) net #> # A sfnetwork: 91 nodes and 101 edges #> # #> # An undirected simple graph with 2 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 3.692428 ymin: 51.14805 xmax: 7.041048 ymax: 53.44424 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 101 × 18 (active) #> from to rohmkm cables geometry operator type lengthm #> #> 1 1 52 \"\" 6;3;3;3;3 (6.188921 52.53048, 6.67… \"\" line 49125.… #> 2 1 21 \"\" 3;3;3;3;6… (6.768035 52.27755, 6.67… \"TenneT\" line 7653.0… #> 3 2 23 \"\" 6;6 (6.830673 52.2139, 6.760… \"TenneT\" line 6135.3… #> 4 2 13 \"\" 6;6 (6.830673 52.2139, 6.888… \"\" line 4296.2… #> 5 3 53 \"\" 6 (6.869683 53.42999, 6.87… \"\" line 388.82… #> 6 3 70 \"\" 6 (6.869683 53.42999, 6.85… \"\" line 359.61… #> # ℹ 95 more rows #> # ℹ 10 more variables: voltage , frequency , cnfkm , #> # fromrelation , ref , name , xohmkm , wires , #> # ithmaxa , lid #> # #> # Node data: 91 × 14 #> netcapacity typ geometry lat voltage frequency ngen #> #> 1 \"\" substation (6.679331 52.32104) 52.3210417… 110000 \"\" \"\" #> 2 \"\" substation (6.830673 52.2139) 52.2139014… 110000 \"\" \"\" #> 3 \"\" substation (6.869683 53.42999) 53.4299869… 220000 \"\" \"\" #> # ℹ 88 more rows #> # ℹ 7 more variables: operator , lon , ref , source , #> # name , capacity , id ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() library(osmdata) #> Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright # Call the Overpass API to extract streets in Anif. data = opq(\"Anif, Austria\") |> add_osm_feature(key = \"highway\") |> osmdata_sf() |> osm_poly2line() # Extract only the linestring geometries from the response. streets = data$osm_lines |> select(name, \"type\" = highway, surface) streets #> Simple feature collection with 1781 features and 3 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 13.03806 ymin: 47.71134 xmax: 13.08752 ymax: 47.76715 #> Geodetic CRS: WGS 84 #> First 10 features: #> name type surface #> 5205037 Sankt-Leonhard-Straße secondary asphalt #> 13868047 Christophorusstraße residential #> 13868111 Überfuhrstraße unclassified asphalt #> 16300987 motorway_link asphalt #> 16628000 Berchtesgadener Straße primary asphalt #> 20812716 Ursteinsteg cycleway asphalt #> 20812718 Tauernradweg path fine_gravel #> 22767760 motorway_link asphalt #> 22767761 motorway_link asphalt #> 22767763 motorway_link asphalt #> geometry #> 5205037 LINESTRING (13.05769 47.724... #> 13868047 LINESTRING (13.08263 47.746... #> 13868111 LINESTRING (13.08397 47.746... #> 16300987 LINESTRING (13.0515 47.7375... #> 16628000 LINESTRING (13.05344 47.739... #> 20812716 LINESTRING (13.08375 47.725... #> 20812718 LINESTRING (13.08152 47.731... #> 22767760 LINESTRING (13.04707 47.741... #> 22767761 LINESTRING (13.05249 47.738... #> 22767763 LINESTRING (13.05394 47.740... net = as_sfnetwork(streets, directed = FALSE) net #> # A sfnetwork: 2519 nodes and 1781 edges #> # #> # An undirected multigraph with 837 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 13.03806 ymin: 47.71134 xmax: 13.08752 ymax: 47.76715 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 2,519 × 1 (active) #> geometry #> #> 1 (13.05769 47.72452) #> 2 (13.05883 47.72453) #> 3 (13.08263 47.74633) #> 4 (13.08086 47.75767) #> 5 (13.08397 47.74621) #> 6 (13.0515 47.73759) #> # ℹ 2,513 more rows #> # #> # Edge data: 1,781 × 6 #> from to name type surface geometry #> #> 1 1 2 Sankt-Leonhard-Straße secondary asphalt (13.05769 47.72452, 13.0… #> 2 3 4 Christophorusstraße residenti… NA (13.08263 47.74633, 13.0… #> 3 3 5 Überfuhrstraße unclassif… asphalt (13.08397 47.74621, 13.0… #> # ℹ 1,778 more rows # The create network without subdivision has many disconnected components. with_graph(net, graph_component_count()) #> [1] 837 # Creating the network with subdivsion reduces this number drastically. net = as_sfnetwork(streets, subdivide = TRUE) with_graph(net, graph_component_count()) #> [1] 21 ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf() + theme_void() # Sample on a unit square. neta = play_geometric(10, 0.3) # Sample on a spatial feature. netb = play_geometric(20, set_units(250, \"m\"), bounds = st_bbox(mozart)) ggraph(neta, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(netb, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"from-node-and-edge-tables","dir":"Articles","previous_headings":"","what":"From node and edge tables","title":"Creating and representing spatial networks","text":"basic way create sfnetwork object provide ready--use node edge tables sfnetwork() construction function. Remember nodes sf object POINT geometries, first two columns edges table required named contain rownumbers nodes start end edge. edges spatially explicit, hence, also geometries, type LINESTRING endpoints equal locations source target nodes. construction function check provided input meets criteria. already sure data forms valid spatial network, can set force = TRUE. also possible provide nodes sf object, can converted . example, table two coordinate columns. additional arguments provided sfnetwork() construction function forwarded sf::st_as_sf() convert provided nodes table sf object. Instead integers referring rownumbers nodes table, columns edges table can also contain characters refer values specific node attribute column. name column given argument node_key. default, assumed column named name. Internally, construction function convert character values integer indices referencing rownumbers. edges geometries, can still create network spatially explicit edges setting edges_as_lines = TRUE. create linestring geometries straight lines source target nodes.","code":"p1 = st_point(c(6, 52)) p2 = st_point(c(8, 53)) p3 = st_point(c(8, 51)) l1 = st_linestring(c(p1, p2)) l2 = st_linestring(c(p2, p3)) l3 = st_linestring(c(p3, p1)) edges = st_sf(geometry = st_sfc(l1, l2, l3), crs = 4326) nodes = st_sf(geometry = st_sfc(p1, p2, p3), crs = 4326) edges$from = c(1, 2, 3) edges$to = c(2, 3, 1) net = sfnetwork(nodes, edges) net #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 6 ymin: 51 xmax: 8 ymax: 53 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 1 (active) #> geometry #> #> 1 (6 52) #> 2 (8 53) #> 3 (8 51) #> # #> # Edge data: 3 × 3 #> from to geometry #> #> 1 1 2 (6 52, 8 53) #> 2 2 3 (8 53, 8 51) #> 3 3 1 (8 51, 6 52) nodes_tbl = tibble(x = c(6, 8, 8), y = c(52, 53, 51)) net = sfnetwork(nodes_tbl, edges, coords = c(\"x\", \"y\"), crs = 4326) net #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 6 ymin: 51 xmax: 8 ymax: 53 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 1 (active) #> geometry #> #> 1 (6 52) #> 2 (8 53) #> 3 (8 51) #> # #> # Edge data: 3 × 3 #> from to geometry #> #> 1 1 2 (6 52, 8 53) #> 2 2 3 (8 53, 8 51) #> 3 3 1 (8 51, 6 52) nodes$type = c(\"city\", \"village\", \"farm\") edges = st_drop_geometry(edges) edges$from = c(\"city\", \"village\", \"farm\") edges$to = c(\"village\", \"farm\", \"city\") net = sfnetwork(nodes, edges, node_key = \"type\", edges_as_lines = TRUE) net #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 6 ymin: 51 xmax: 8 ymax: 53 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 2 (active) #> geometry type #> #> 1 (6 52) city #> 2 (8 53) village #> 3 (8 51) farm #> # #> # Edge data: 3 × 3 #> from to geometry #> #> 1 1 2 (6 52, 8 53) #> 2 2 3 (8 53, 8 51) #> 3 3 1 (8 51, 6 52) ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = as.factor(type)), size = 4) + scale_color_discrete(\"type\") + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"from-spatial-lines","dir":"Articles","previous_headings":"","what":"From spatial lines","title":"Creating and representing spatial networks","text":"common way create spatial network start set LINESTRING geometries sf format. assumed edge network. Providing as_sfnetwork() automatically call create_from_spatial_lines(). function creates nodes endpoints lines. Endpoints shared multiple lines, become single node network. determine spatial equality endpoints, sfnetworks default uses 12-digit precision coordinates. can change either setting different precision (see ) effectively rounding coordinate values using utility function st_round(). Lines Network Besides endpoints, linestring geometries may interior points define shape. may multiple linestrings interior points location. Since endpoints, become node network. also want add nodes shared interior points, set subdivide = TRUE, call to_spatial_subdivision() morpher construction. See vignette Spatial morphers details.","code":"# Linestring geometries. roxel #> Simple feature collection with 1215 features and 2 fields #> Attribute-geometry relationships: constant (2) #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 1,215 × 3 #> name type geometry #> #> 1 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 … #> 2 Stiegkamp residential (7.537815 51.95867, 7.537015 … #> 3 Havixbecker Straße residential (7.533441 51.95578, 7.533467 … #> 4 Holzschuhmacherweg residential (7.525977 51.95283, 7.526581 … #> 5 Annette-von-Droste-Hülshoff-Straße secondary (7.532301 51.95559, 7.532214 … #> 6 NA footway (7.543404 51.94779, 7.54358 5… #> 7 Deermannskamp residential (7.537675 51.95689, 7.537904 … #> 8 Lindenstraße residential (7.539105 51.9504, 7.540105 5… #> 9 NA NA (7.534875 51.95795, 7.534819 … #> 10 Annette-von-Droste-Hülshoff-Straße secondary (7.532465 51.95424, 7.532469 … #> # ℹ 1,205 more rows # Network. net = as_sfnetwork(roxel) net #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows ggplot(roxel) + geom_sf() + theme_void() ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf() + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"from-spatial-points","dir":"Articles","previous_headings":"","what":"From spatial points","title":"Creating and representing spatial networks","text":"also possible create network set POINT geometries. assumed nodes network. Providing as_sfnetwork() automatically call create_from_spatial_points(). second input requires adjacency matrix specifies nodes connected . Adjacency matrices networks n×nn \\times n matrices nn number nodes, element AijA_{ij} holding value edge node ii node jj, value otherwise. Points Network adjacency matrix can also provided sparse form, node indices nodes connected listed. allows directly forward output binary spatial predicate. example, using sf::st_is_within_distance(), can connect nodes within given distance . Points Network Finally, sfnetworks can create adjacency matrix internally according specified method. case, just need provide name method. Supported options currently : complete: nodes directly connected . sequence: nodes sequentially connected , meaning first node connected second node, second node connected third node, etc. minimum_spanning_tree: nodes connected spatial minimum spanning tree, .e. set edges minimum total edge length required connect nodes. Can also specified mst. delaunay: nodes connected Delaunay triangulation. Requires spdep package installed, assumes planar coordinates. gabriel: nodes connected Gabriel graph. Requires spdep package installed, assumes planar coordinates. relative_neighborhood: nodes connected relative neighborhood graph. Can also specified rn. Requires spdep package installed, assumes planar coordinates. nearest_neighbors: node connected kk nearest neighbors, kk specified k argument. default, k = 1, meaning nodes connected nearest neighbor graph. Can also specified knn. Requires spdep package installed. Complete Sequential Minimum spanning tree Delaunay triangulation Gabriel Relative neighbors Nearest neighbors K nearest neighbors (k = 3)","code":"# Point geometries. mozart #> Simple feature collection with 17 features and 3 fields #> Attribute-geometry relationships: constant (3) #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 17 × 4 #> name type website geometry #> * #> 1 Mozartkino cinema https://www.… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> 4 Mozart Denkmal artwork NA (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) #> 6 Mozartsteg bridge NA (4549473 2747624) #> 7 Mozarts Geburtshaus museum http://www.m… (4549064 2747619) #> 8 Café Mozart cafe https://www.… (4548994 2747632) #> 9 Mozartkugel confectionery NA (4549120 2747654) #> 10 Mozartsteg/Imbergstraße bus_stop NA (4549418 2747723) #> 11 Spirit of Mozart artwork https://salz… (4549119 2747790) #> 12 Mozart-Eine Hommage artwork https://salz… (4548664 2747868) #> 13 Mozarts Wohnhaus apartments NA (4549073 2747916) #> 14 Universität Mozarteum university NA (4549059 2748042) #> 15 Stiftung Mozarteum concert_hall NA (4548897 2748037) #> 16 Hotel Mozart hotel http://www.h… (4549378 2748391) #> 17 Mozart Studentenheim dormitory NA (4548984 2748537) # Adjacency matrix. adj = matrix(c(rep(TRUE, 17), rep(rep(FALSE, 17), 16)), nrow = 17) # Network. net = as_sfnetwork(mozart, adj) net #> # A sfnetwork: 17 nodes and 17 edges #> # #> # A bipartite multigraph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 4 (active) #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> 4 Mozart Denkmal artwork NA (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) #> 6 Mozartsteg bridge NA (4549473 2747624) #> # ℹ 11 more rows #> # #> # Edge data: 17 × 3 #> from to geometry #> #> 1 1 1 (4549504 2747309, 4549504 2747309) #> 2 2 1 (4549003 2747376, 4549504 2747309) #> 3 3 1 (4549589 2747507, 4549504 2747309) #> # ℹ 14 more rows ggplot(mozart) + geom_sf(size = 4) + theme_void() ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() adj = st_is_within_distance(mozart, dist = set_units(250, \"m\")) adj #> Sparse geometry binary predicate list of length 17, where the predicate #> was `is_within_distance' #> first 10 elements: #> 1: 1, 3, 4, 5 #> 2: 2 #> 3: 1, 3, 4, 5, 6 #> 4: 1, 3, 4, 5, 6, 10 #> 5: 1, 3, 4, 5, 6, 10 #> 6: 3, 4, 5, 6, 10 #> 7: 7, 8, 9, 11 #> 8: 7, 8, 9, 11 #> 9: 7, 8, 9, 11 #> 10: 4, 5, 6, 10 net = as_sfnetwork(mozart, adj) ggplot(mozart) + geom_sf(size = 4) + theme_void() ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() make_ggraph = function(x) { ggraph(x, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() } make_ggraph(as_sfnetwork(mozart, \"complete\")) make_ggraph(as_sfnetwork(mozart, \"sequence\")) make_ggraph(as_sfnetwork(mozart, \"mst\")) make_ggraph(as_sfnetwork(mozart, \"delaunay\")) make_ggraph(as_sfnetwork(mozart, \"gabriel\")) make_ggraph(as_sfnetwork(mozart, \"rn\")) make_ggraph(as_sfnetwork(mozart, \"knn\")) #> Warning in spdep::knn2nb(spdep::knearneigh(st_geometry(x), k = k), sym = #> FALSE): neighbour object has 4 sub-graphs make_ggraph(as_sfnetwork(mozart, \"knn\", k = 3)) #> Warning in spdep::knn2nb(spdep::knearneigh(st_geometry(x), k = k), sym = #> FALSE): neighbour object has 2 sub-graphs"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"from-other-network-representations","dir":"Articles","previous_headings":"","what":"From other network representations","title":"Creating and representing spatial networks","text":"conversion function as_sfnetwork() can also used convert instances network classes sfnetwork object. includes classes also designed spatial networks, dodgr_streetnet dodgr package routing street networks, linnet spatstat.linnet package statistical point pattern analysis spatial linear networks. However, can also used convert instances non-spatial network formats, long specify way spatial location nodes. example, igraph object x y coordinates stored node attributes. case, additional arguments provided as_sfnetwork() forwarded sf::st_as_sf() convert nodes given network sf object.","code":"# igraph object. inet = igraph::sample_grg(5, 0.5, coords = TRUE) inet #> IGRAPH 037109b U--- 5 2 -- Geometric random graph #> + attr: name (g/c), radius (g/n), torus (g/l), x (v/n), y (v/n) #> + edges from 037109b: #> [1] 2--3 4--5 # sfnetwork object. net = as_sfnetwork(inet, coords = c(\"x\", \"y\")) net #> # A sfnetwork: 5 nodes and 2 edges #> # #> # An unrooted forest with 3 trees and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0.111582 ymin: 0.3144644 xmax: 0.9832471 ymax: 0.9943113 #> # CRS: NA #> # #> # Node data: 5 × 1 (active) #> geometry #> #> 1 (0.111582 0.968579) #> 2 (0.3840216 0.4292271) #> 3 (0.8146119 0.3144644) #> 4 (0.8447424 0.9943113) #> 5 (0.9832471 0.9893714) #> # #> # Edge data: 2 × 2 #> from to #> #> 1 2 3 #> 2 4 5"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"from-files","dir":"Articles","previous_headings":"","what":"From files","title":"Creating and representing spatial networks","text":"currently functions sfnetworks reading writing data (ideas). However, can use sf::st_read() spatial file formats read points /lines, construct network using sfnetwork() (described ) as_sfnetwork() (described lines points). network specific file types, can use igraph::read_graph() read data R, convert spatial network format using as_sfnetwork() long required spatial information present (see ). common format latter category GraphML. example file can found , containing power grid Netherlands. reading using igraph, first convert tbl_graph can easily explore data. can see spatial geometries nodes edges stored WKT strings columns named wktsrid4326. Remember additional arguments as_sfnetwork() igraph objects forwarded sf::st_as_sf() convert nodes sf object. makes conversion sfnetwork object easy : However, affect nodes table (since one required geometries). edges explicit geometries yet. Using morpher function to_spatial_explicit(), can “explicitize” edge geometries constructed network. Also , additional arguments forwarded sf::st_as_sf().","code":"url = \"https://raw.githubusercontent.com/ComplexNetTSP/Power_grids/v1.0.0/Countries/Netherlands/graphml/Netherlands_highvoltage.graphml\" igraph::read_graph(url, format = \"graphml\") |> as_tbl_graph() #> # A tbl_graph: 91 nodes and 101 edges #> # #> # An undirected simple graph with 2 components #> # #> # Node Data: 91 × 14 (active) #> netcapacity typ wktsrid4326 lat voltage frequency ngen operator lon #> #> 1 \"\" substat… SRID=4326;… 52.3… 110000 \"\" \"\" \"TenneT\" 6.67… #> 2 \"\" substat… SRID=4326;… 52.2… 110000 \"\" \"\" \"\" 6.83… #> 3 \"\" substat… SRID=4326;… 53.4… 220000 \"\" \"\" \"TenneT\" 6.86… #> 4 \"\" joint SRID=4326;… 53.2… 220000… \"50;50;5… \"\" \"TenneT\" 6.47… #> 5 \"\" joint SRID=4326;… 51.4… 150000… \"50;50;5… \"\" \"TenneT\" 5.62… #> 6 \"\" joint SRID=4326;… 52.4… 150000… \"50;50;5… \"\" \"TenneT\" 4.87… #> 7 \"\" joint SRID=4326;… 52.4… 380000… \"50;50;5… \"\" \"TenneT\" 4.87… #> 8 \"\" substat… SRID=4326;… 52.4… 380000… \"\" \"\" \"TenneT\" 4.87… #> 9 \"\" substat… SRID=4326;… 51.8… 380000 \"\" \"\" \"TenneT\" 4.26… #> 10 \"\" substat… SRID=4326;… 51.6… 380000… \"\" \"\" \"TenneT\" 5.91… #> # ℹ 81 more rows #> # ℹ 5 more variables: ref , source , name , capacity , #> # id #> # #> # Edge Data: 101 × 18 #> from to rohmkm cables wktsrid4326 operator type lengthm voltage frequency #> #> 1 1 52 \"\" 6;3;3… SRID=4326;… \"\" line 49125.… 380000… 50 #> 2 1 21 \"\" 3;3;3… SRID=4326;… \"TenneT\" line 7653.0… 110000… 50;50 #> 3 2 23 \"\" 6;6 SRID=4326;… \"TenneT\" line 6135.3… 380000… 50 #> # ℹ 98 more rows #> # ℹ 8 more variables: cnfkm , fromrelation , ref , name , #> # xohmkm , wires , ithmaxa , lid net = igraph::read_graph(url, format = \"graphml\") |> as_sfnetwork(wkt = \"wktsrid4326\", crs = 4326) |> rename(geometry = wktsrid4326) net #> # A sfnetwork: 91 nodes and 101 edges #> # #> # An undirected simple graph with 2 components and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 3.692428 ymin: 51.14805 xmax: 7.041048 ymax: 53.44424 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 91 × 14 (active) #> netcapacity typ geometry lat voltage frequency ngen #> #> 1 \"\" substation (6.679331 52.32104) 52.3210417… 110000 \"\" \"\" #> 2 \"\" substation (6.830673 52.2139) 52.2139014… 110000 \"\" \"\" #> 3 \"\" substation (6.869683 53.42999) 53.4299869… 220000 \"\" \"\" #> 4 \"\" joint (6.474364 53.21321) 53.2132104… 220000… \"50;50;5… \"\" #> 5 \"\" joint (5.621211 51.45516) 51.4551594… 150000… \"50;50;5… \"\" #> 6 \"\" joint (4.873691 52.42842) 52.4284153… 150000… \"50;50;5… \"\" #> # ℹ 85 more rows #> # ℹ 7 more variables: operator , lon , ref , source , #> # name , capacity , id #> # #> # Edge data: 101 × 18 #> from to rohmkm cables wktsrid4326 operator type lengthm voltage frequency #> #> 1 1 52 \"\" 6;3;3… SRID=4326;… \"\" line 49125.… 380000… 50 #> 2 1 21 \"\" 3;3;3… SRID=4326;… \"TenneT\" line 7653.0… 110000… 50;50 #> 3 2 23 \"\" 6;6 SRID=4326;… \"TenneT\" line 6135.3… 380000… 50 #> # ℹ 98 more rows #> # ℹ 8 more variables: cnfkm , fromrelation , ref , name , #> # xohmkm , wires , ithmaxa , lid net = net |> convert(to_spatial_explicit, wkt = \"wktsrid4326\", crs = 4326, .clean = TRUE) |> activate(edges) |> rename(geometry = wktsrid4326) net #> # A sfnetwork: 91 nodes and 101 edges #> # #> # An undirected simple graph with 2 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 3.692428 ymin: 51.14805 xmax: 7.041048 ymax: 53.44424 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 101 × 18 (active) #> from to rohmkm cables geometry operator type lengthm #> #> 1 1 52 \"\" 6;3;3;3;3 (6.188921 52.53048, 6.67… \"\" line 49125.… #> 2 1 21 \"\" 3;3;3;3;6… (6.768035 52.27755, 6.67… \"TenneT\" line 7653.0… #> 3 2 23 \"\" 6;6 (6.830673 52.2139, 6.760… \"TenneT\" line 6135.3… #> 4 2 13 \"\" 6;6 (6.830673 52.2139, 6.888… \"\" line 4296.2… #> 5 3 53 \"\" 6 (6.869683 53.42999, 6.87… \"\" line 388.82… #> 6 3 70 \"\" 6 (6.869683 53.42999, 6.85… \"\" line 359.61… #> # ℹ 95 more rows #> # ℹ 10 more variables: voltage , frequency , cnfkm , #> # fromrelation , ref , name , xohmkm , wires , #> # ithmaxa , lid #> # #> # Node data: 91 × 14 #> netcapacity typ geometry lat voltage frequency ngen #> #> 1 \"\" substation (6.679331 52.32104) 52.3210417… 110000 \"\" \"\" #> 2 \"\" substation (6.830673 52.2139) 52.2139014… 110000 \"\" \"\" #> 3 \"\" substation (6.869683 53.42999) 53.4299869… 220000 \"\" \"\" #> # ℹ 88 more rows #> # ℹ 7 more variables: operator , lon , ref , source , #> # name , capacity , id ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"from-openstreetmap-data","dir":"Articles","previous_headings":"","what":"From OpenStreetMap data","title":"Creating and representing spatial networks","text":"common source spatial network data OpenStreetMap.open collaborative geographic database. can used example extract geometries streets rivers anywhere world. R, two main packages allow read OpenStreetMap data: osmdata package provides interface Overpass API OpenStreetMap. osmextract package can read OpenStreetMap data osm.pbf files. small areas repeated calls, Overpass API easiest way get data. However, area interest large, want load data many times, preferred overload API read osm.pbf files instead. Geofabrik one platforms can download files many different regions world. , show small example using osmdata. can read street centerlines Anif, small village Austria, shown . details workflow, check osmdata documentation. Now, can simply create network lines using as_sfnetwork(), shown . However, need aware OpenStreetMap data created primarily network structure mind. means locations two streets connect always endpoints linestring geometries, can interior point geometry well. setting subdivide = TRUE linestring geometries subdivided places interior point shared multiple features. way, node placed locations.","code":"library(osmdata) #> Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright # Call the Overpass API to extract streets in Anif. data = opq(\"Anif, Austria\") |> add_osm_feature(key = \"highway\") |> osmdata_sf() |> osm_poly2line() # Extract only the linestring geometries from the response. streets = data$osm_lines |> select(name, \"type\" = highway, surface) streets #> Simple feature collection with 1781 features and 3 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 13.03806 ymin: 47.71134 xmax: 13.08752 ymax: 47.76715 #> Geodetic CRS: WGS 84 #> First 10 features: #> name type surface #> 5205037 Sankt-Leonhard-Straße secondary asphalt #> 13868047 Christophorusstraße residential #> 13868111 Überfuhrstraße unclassified asphalt #> 16300987 motorway_link asphalt #> 16628000 Berchtesgadener Straße primary asphalt #> 20812716 Ursteinsteg cycleway asphalt #> 20812718 Tauernradweg path fine_gravel #> 22767760 motorway_link asphalt #> 22767761 motorway_link asphalt #> 22767763 motorway_link asphalt #> geometry #> 5205037 LINESTRING (13.05769 47.724... #> 13868047 LINESTRING (13.08263 47.746... #> 13868111 LINESTRING (13.08397 47.746... #> 16300987 LINESTRING (13.0515 47.7375... #> 16628000 LINESTRING (13.05344 47.739... #> 20812716 LINESTRING (13.08375 47.725... #> 20812718 LINESTRING (13.08152 47.731... #> 22767760 LINESTRING (13.04707 47.741... #> 22767761 LINESTRING (13.05249 47.738... #> 22767763 LINESTRING (13.05394 47.740... net = as_sfnetwork(streets, directed = FALSE) net #> # A sfnetwork: 2519 nodes and 1781 edges #> # #> # An undirected multigraph with 837 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 13.03806 ymin: 47.71134 xmax: 13.08752 ymax: 47.76715 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 2,519 × 1 (active) #> geometry #> #> 1 (13.05769 47.72452) #> 2 (13.05883 47.72453) #> 3 (13.08263 47.74633) #> 4 (13.08086 47.75767) #> 5 (13.08397 47.74621) #> 6 (13.0515 47.73759) #> # ℹ 2,513 more rows #> # #> # Edge data: 1,781 × 6 #> from to name type surface geometry #> #> 1 1 2 Sankt-Leonhard-Straße secondary asphalt (13.05769 47.72452, 13.0… #> 2 3 4 Christophorusstraße residenti… NA (13.08263 47.74633, 13.0… #> 3 3 5 Überfuhrstraße unclassif… asphalt (13.08397 47.74621, 13.0… #> # ℹ 1,778 more rows # The create network without subdivision has many disconnected components. with_graph(net, graph_component_count()) #> [1] 837 # Creating the network with subdivsion reduces this number drastically. net = as_sfnetwork(streets, subdivide = TRUE) with_graph(net, graph_component_count()) #> [1] 21 ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf() + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"random-networks","dir":"Articles","previous_headings":"","what":"Random networks","title":"Creating and representing spatial networks","text":"function play_geometric() creates random geometric graph. randomly samples nn nodes, connects edge within given distance threshold . default, sampling take place unit square. However, bounds argument can also provide spatial feature sample . use sf::st_sample() internally. Random network Random network B","code":"# Sample on a unit square. neta = play_geometric(10, 0.3) # Sample on a spatial feature. netb = play_geometric(20, set_units(250, \"m\"), bounds = st_bbox(mozart)) ggraph(neta, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(netb, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn02_create_represent.html","id":"validating-sfnetwork-objects","dir":"Articles","previous_headings":"","what":"Validating sfnetwork objects","title":"Creating and representing spatial networks","text":"described beginning, several requirements sfnetwork object considered valid spatial network. validate_network() utility function checks requirements met. checks executed already construction. Trying construct invalid network result error: However, work around setting force = TRUE. skip checks, create sfnetwork object even structure valid. aware functions sfnetworks designed assumption analyzed network valid. issue node edge geometries match (.e. endpoints edges equal nodes supposed source target), utility function make_edges_valid() can fix two different ways: default, replace invalid endpoint edge geometry point geometry node referenced column. set preserve_geometries = TRUE, edge geometries remain unchanged. Invalid endpoints added new nodes network, columns updated accordingly. Invalid network Valid network Valid network B","code":"validate_network(net) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> → Checking edge geometry types ... #> ✔ All edges have geometry type LINESTRING #> → Checking coordinate reference system equality ... #> ✔ Nodes and edges have the same crs #> → Checking coordinate precision equality ... #> ✔ Nodes and edges have the same precision #> → Checking if geometries match ... #> ✔ Node locations match edge boundaries #> ✔ Spatial network structure is valid p1 = st_point(c(6, 52)) p2 = st_point(c(8, 53)) p3 = st_point(c(8, 51)) p4 = st_point(c(7, 52.5)) p5 = st_point(c(7, 52)) l1 = st_linestring(c(p2, p4)) l2 = st_linestring(c(p2, p5)) edges = st_sf(geometry = st_sfc(l1, l2), crs = 4326) nodes = st_sf(geometry = st_sfc(p1, p2, p3), crs = 4326) edges$from = c(2, 2) edges$to = c(1, 3) net = sfnetwork(nodes, edges) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> → Checking edge geometry types ... #> ✔ All edges have geometry type LINESTRING #> → Checking coordinate reference system equality ... #> ✔ Nodes and edges have the same crs #> → Checking coordinate precision equality ... #> ✔ Nodes and edges have the same precision #> → Checking if geometries match ... #> Error in `validate_network()`: #> ! Node locations do not match edge boundaries net = sfnetwork(nodes, edges, force = TRUE) neta = make_edges_valid(net) netb = make_edges_valid(net, preserve_geometries = TRUE) ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(neta, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(netb, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"the-basics","dir":"Articles","previous_headings":"","what":"The basics","title":"Cleaning spatial networks","text":"Functions modify topology network implemented sfnetworks spatial morphers. Network cleaning functions belong family. applications described , sufficient know can use spatial morpher function inside tidygraph::convert() verb convert network new structure. One thing notice tidygraph keeps track original node edge indices columns .tidygraph_node_index .tidygraph_edge_index. want output, add .clean = TRUE tidygraph::convert() call. presenting cleaning functions currently implemented, lets create network cleaned.","code":"p01 = st_point(c(0, 1)) p02 = st_point(c(1, 1)) p03 = st_point(c(2, 1)) p04 = st_point(c(3, 1)) p05 = st_point(c(4, 1)) p06 = st_point(c(3, 2)) p07 = st_point(c(3, 0)) p08 = st_point(c(4, 3)) p09 = st_point(c(4, 2)) p10 = st_point(c(4, 0)) p11 = st_point(c(5, 2)) p12 = st_point(c(5, 0)) p13 = st_point(c(5, -1)) p14 = st_point(c(5.8, 1)) p15 = st_point(c(6, 1.2)) p16 = st_point(c(6.2, 1)) p17 = st_point(c(6, 0.8)) p18 = st_point(c(6, 2)) p19 = st_point(c(6, -1)) p20 = st_point(c(7, 1)) p21 = st_point(c(0, 2)) p22 = st_point(c(0, -1)) l01 = st_sfc(st_linestring(c(p01, p02, p03))) l02 = st_sfc(st_linestring(c(p03, p04, p05))) l03 = st_sfc(st_linestring(c(p06, p04, p07))) l04 = st_sfc(st_linestring(c(p08, p11, p09))) l05 = st_sfc(st_linestring(c(p09, p05, p10))) l06 = st_sfc(st_linestring(c(p08, p09))) l07 = st_sfc(st_linestring(c(p10, p12, p13, p10))) l08 = st_sfc(st_linestring(c(p05, p14))) l09 = st_sfc(st_linestring(c(p15, p14))) l10 = st_sfc(st_linestring(c(p16, p15))) l11 = st_sfc(st_linestring(c(p14, p17))) l12 = st_sfc(st_linestring(c(p17, p16))) l13 = st_sfc(st_linestring(c(p15, p18))) l14 = st_sfc(st_linestring(c(p17, p19))) l15 = st_sfc(st_linestring(c(p16, p20))) l16 = st_sfc(st_linestring(c(p21, p01))) l17 = st_sfc(st_linestring(c(p22, p01))) lines = c( l01, l02, l03, l04, l05, l06, l07, l08, l09, l10, l11, l12, l13, l14, l15 ) edges = st_sf(id = seq_along(lines), geometry = lines) net = as_sfnetwork(edges) |> bind_spatial_nodes(st_sf(geometry = st_sfc(p01, p21, p22))) |> mutate( foo = sample(letters, n(), replace = TRUE), bar = sample(c(1:10), n(), replace = TRUE) ) |> activate(edges) |> bind_spatial_edges(st_sf(from = c(17, 18), to = c(16, 16), geometry = c(l16, l17))) |> mutate( foo = sample(letters, n(), replace = TRUE), bar = sample(c(1:10), n(), replace = TRUE) ) make_ggraph = function(x) { ggraph(x, \"sf\") + geom_edge_sf(aes(color = as.factor(id)), linewidth = 2, show.legend = FALSE) + geom_node_sf(size = 4) + theme_void() } make_ggraph(net)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"simplify-the-network","dir":"Articles","previous_headings":"","what":"Simplify the network","title":"Cleaning spatial networks","text":"network may contain sets edges connect pair nodes. edges can called multiple edges. Also, may contain edge starts ends node. edge can called loop edge. graph theory, simple graph defined graph contain multiple edges loop edges. obtain simple version network, can remove multiple edges loop edges using morpher to_spatial_simple(). re-arranging edges table applying morpher can influence edges kept whenever sets multiple edges detected. example, might want always keep edge shortest distance set.","code":"simple = net |> convert(to_spatial_simple) make_ggraph(net) make_ggraph(simple) simple = net |> activate(edges) |> arrange(edge_length()) |> convert(to_spatial_simple) make_ggraph(net) make_ggraph(simple)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"subdivide-edges","dir":"Articles","previous_headings":"","what":"Subdivide edges","title":"Cleaning spatial networks","text":"constructing sfnetwork set sf linestrings, endpoints linestrings become nodes network. endpoints shared multiple lines, become single node, edges connected. However, linestring geometry can also contain interior points define shape line, endpoints. can happen interior point one edge equal either interior point endpoint another edge. network structure, however, two edges connected, don’t share endpoints. unwanted, need split two edges shared point connect accordingly. graph theory terms process splitting edge called subdivision: subdivision edge o={,b}o = \\{, b\\} (.e. edge node aa node bb) addition new node cc replacement oo two new edges p={,c}p = \\{, c\\} q={c,b}q = \\{c, b\\}. function to_spatial_subdivision() subdivides edges interior points whenever interior points equal one interior points endpoints edges, recalculates network connectivity afterwards. illustrate workflow, lets consider situation interior point pxp_{x} edge xx shared point pyp_{y} edge yy. gives two possible situations: xx subdivided pxp_{x} two new edges x1x_{1} x2x_{2} new node pxp_{x}. yy subdivided pyp_{y} two new edges y1y_{1} y2y_{2} new node pyp_{y}. new nodes pxp_{x} pyp_{y} merged single node pp edge set {x1,x2,y1,y2}\\{x_{1}, x_{2}, y_{1}, y_{2}\\} incidents. xx subdivided pxp_{x} two new edges x1x_{1} x2x_{2} new node pxp_{x}. new node pxp_{x} merged node pyp_{y} single node pp edge set {y,x1,x2}\\{y, x_{1}, x_{2}\\} incidents. Note edge subdivided crosses another edge location interior point endpoint linestring geometry two edges. example network, means:","code":"subdivision = simple |> convert(to_spatial_subdivision) make_ggraph(simple) make_ggraph(subdivision)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"smooth-pseudo-nodes","dir":"Articles","previous_headings":"","what":"Smooth pseudo nodes","title":"Cleaning spatial networks","text":"network may contain nodes one incoming one outgoing edge. tasks like calculating shortest paths, nodes redundant, don’t represent point different directions can possibly taken. Sometimes, type nodes referred pseudo nodes. Note equivalent undirected networks node two incident edges, since incoming outgoing meaning . reduce complexity subsequent operations, might want get rid pseudo nodes. graph theory terms process opposite subdivision also called smoothing: smoothing node bb incident edges o={,b}o = \\{, b\\} p={b,c}p = \\{b, c\\} removes bb, oo pp creates new edge q={,c}q = \\{, c\\}. function to_spatial_smooth() iteratively smooths pseudo nodes, removal concatenates linestring geometries two affected edges together new, single linestring geometry. Pseudo nodes may function representing location certain attribute changes. example, point street different surface type. require_equal argument allows specify one edge attributes checked equality removing pseudo node. attributes equal, node removed, , remain. argument value evaluated using tidy selection, meaning can specify column names unquoted, also use selection helpers. to_spatial_smooth() morpher also allows specify want combine attributes concatenated edges. done attribute_summary argument. attributes combined course dependent type purpose attribute. Therefore, combination technique can specified per-attribute basis. two ways specify combination technique attribute: character, referring name pre-defined combination technique igraph. Examples include mean, sum, first last. See overview implemented techniques. function, taking vector attribute values input returning single value. helpful want combine attributes way pre-defined. Providing single character single function (e.g. attribute_summary = \"sum\") apply technique attribute. Instead, can provide named list different technique attribute. list can also include one unnamed element containing technique applied attributes referenced elements. Note geometry-list column, tidygraph index columns, well columns considered attributes!","code":"smooth = subdivision |> convert(to_spatial_smooth) make_ggraph(subdivision) make_ggraph(smooth) # Only smooth pseudo nodes if incident edges have the same value for \"foo\". smooth_b = net |> convert(to_spatial_smooth, require_equal = foo) # Only smooth pseudo nodes if incident edges have the same value for all attributes. smooth_c = net |> convert(to_spatial_smooth, require_equal = everything()) smooth_d = subdivision |> convert( to_spatial_smooth, attribute_summary = list(foo = paste, bar = \"sum\") ) smooth_d #> # A sfnetwork: 17 nodes and 16 edges #> # #> # A directed simple graph with 2 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: -1 xmax: 7 ymax: 3 #> # CRS: NA #> # #> # Edge data: 16 × 7 (active) #> from to id foo bar .tidygraph_edge_index geometry #> #> 1 17 2 2 7 (3 1, 4 1) #> 2 2 7 8 10 (4 1, 5.8 1) #> 3 3 17 3 6 (3 2, 3 1) #> 4 17 4 3 6 (3 1, 3 0) #> 5 2 6 5 10 (4 1, 4 0) #> 6 7 10 11 7 (5.8 1, 6 0.8) #> # ℹ 10 more rows #> # #> # Node data: 17 × 4 #> geometry foo bar .tidygraph_node_index #> #> 1 (0 1) b 3 1 #> 2 (4 1) n 7 3 #> 3 (3 2) x 9 4 #> # ℹ 14 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"require-equal-attributes","dir":"Articles","previous_headings":"","what":"Require equal attributes","title":"Cleaning spatial networks","text":"Pseudo nodes may function representing location certain attribute changes. example, point street different surface type. require_equal argument allows specify one edge attributes checked equality removing pseudo node. attributes equal, node removed, , remain. argument value evaluated using tidy selection, meaning can specify column names unquoted, also use selection helpers.","code":"# Only smooth pseudo nodes if incident edges have the same value for \"foo\". smooth_b = net |> convert(to_spatial_smooth, require_equal = foo) # Only smooth pseudo nodes if incident edges have the same value for all attributes. smooth_c = net |> convert(to_spatial_smooth, require_equal = everything())"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"summarize-attribute-values","dir":"Articles","previous_headings":"","what":"Summarize attribute values","title":"Cleaning spatial networks","text":"to_spatial_smooth() morpher also allows specify want combine attributes concatenated edges. done attribute_summary argument. attributes combined course dependent type purpose attribute. Therefore, combination technique can specified per-attribute basis. two ways specify combination technique attribute: character, referring name pre-defined combination technique igraph. Examples include mean, sum, first last. See overview implemented techniques. function, taking vector attribute values input returning single value. helpful want combine attributes way pre-defined. Providing single character single function (e.g. attribute_summary = \"sum\") apply technique attribute. Instead, can provide named list different technique attribute. list can also include one unnamed element containing technique applied attributes referenced elements. Note geometry-list column, tidygraph index columns, well columns considered attributes!","code":"smooth_d = subdivision |> convert( to_spatial_smooth, attribute_summary = list(foo = paste, bar = \"sum\") ) smooth_d #> # A sfnetwork: 17 nodes and 16 edges #> # #> # A directed simple graph with 2 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: -1 xmax: 7 ymax: 3 #> # CRS: NA #> # #> # Edge data: 16 × 7 (active) #> from to id foo bar .tidygraph_edge_index geometry #> #> 1 17 2 2 7 (3 1, 4 1) #> 2 2 7 8 10 (4 1, 5.8 1) #> 3 3 17 3 6 (3 2, 3 1) #> 4 17 4 3 6 (3 1, 3 0) #> 5 2 6 5 10 (4 1, 4 0) #> 6 7 10 11 7 (5.8 1, 6 0.8) #> # ℹ 10 more rows #> # #> # Node data: 17 × 4 #> geometry foo bar .tidygraph_node_index #> #> 1 (0 1) b 3 1 #> 2 (4 1) n 7 3 #> 3 (3 2) x 9 4 #> # ℹ 14 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"simplify-intersections","dir":"Articles","previous_headings":"","what":"Simplify intersections","title":"Cleaning spatial networks","text":"Especially road networks may find intersections edges modeled single node. Instead, leg intersection dedicated edge. simplify topology network, might want reduce complex intersection structures single node. Hence, want reduce group nodes single node, maintaining connectivity network. graph theory terms process called contraction: contraction set nodes P={p1,p2,...,pn}P = \\{p_{1}, p_{2}, ..., p_{n}\\} replacement SS incident edges single node p*p^{*} set edges connect p*p^{*} nodes adjacent node pi∈Pp_{} \\P. morpher to_spatial_contracted() contracts groups nodes based given grouping variable. geometry contracted node (default) centroid original group members’ geometries. Moreover, geometries edges start end contracted node updated boundaries match new node geometries. Grouping variables internally forwarded dplyr::group_by(). means can group nodes based (combination ) attribute(s). However, case, want group nodes spatially, nodes close space form group get contracted. Spatial grouping nodes can done group_spatial_dbscan() function, exposes DBSCAN clustering algorithm dbscan package. main parameter ϵ\\epsilon defines radius neighborhood node meters. default, based network distance rather euclidean distance.","code":"contraction = smooth |> activate(nodes) |> convert(to_spatial_contracted, group_spatial_dbscan(0.5)) make_ggraph(smooth) make_ggraph(contraction)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"merge-nodes-at-equal-locations","dir":"Articles","previous_headings":"","what":"Merge nodes at equal locations","title":"Cleaning spatial networks","text":"attentive reader may noticed network still consists two disconnected components, caused fact two seperate nodes exactly location. to_spatial_unique() morpher implements special variation node contraction: contracts nodes share spatial location. incident edges contracted nodes become incident new node. Visually see difference, now reduced number components 1: to_spatial_unique() morpher also allows specify want combine attributes contracted nodes. done attribute_summary argument works explained to_spatial_smooth().","code":"st_equals(contraction) #> Sparse geometry binary predicate list of length 14, where the predicate #> was `equals' #> first 10 elements: #> 1: 1 #> 2: 2, 11 #> 3: 3 #> 4: 4 #> 5: 5 #> 6: 6 #> 7: 7 #> 8: 8 #> 9: 9 #> 10: 10 with_graph(contraction, graph_component_count()) #> [1] 2 unique = contraction |> convert(to_spatial_unique) make_ggraph(contraction) make_ggraph(unique) with_graph(unique, graph_component_count()) #> [1] 1 # Plot components before and after. contraction |> mutate(comp = group_components()) |> activate(edges) |> mutate(comp = .N()$comp[from]) |> ggraph(\"sf\") + geom_edge_sf(aes(color = as.factor(comp)), linewidth = 2, show.legend = FALSE) + geom_node_sf(size = 4) + theme_void() unique |> mutate(comp = group_components()) |> activate(edges) |> mutate(comp = .N()$comp[from]) |> ggraph(\"sf\") + geom_edge_sf(aes(color = as.factor(comp)), linewidth = 2, show.legend = FALSE) + geom_node_sf(size = 4) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"overview","dir":"Articles","previous_headings":"","what":"Overview","title":"Cleaning spatial networks","text":"single pipeline, can clean dirty network follows.","code":"clean = net |> activate(edges) |> arrange(edge_length()) |> activate(nodes) |> convert(to_spatial_simple) |> convert(to_spatial_subdivision) |> convert(to_spatial_smooth) |> convert(to_spatial_contracted, group_spatial_dbscan(0.5)) |> convert(to_spatial_unique) make_ggraph(net) make_ggraph(clean)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn03_cleaning.html","id":"non-tidyverse-workflow","dir":"Articles","previous_headings":"","what":"Non-tidyverse workflow","title":"Cleaning spatial networks","text":"cleaning morphers internal worker exported well. can used want work outside “tidy workflow”. cleaning operation can done follows:","code":"simple = simplify_network(net) subdivision = subdivide_edges(simple) smooth = smooth_pseudo_nodes(subdivision) groups = with_graph(smooth, group_spatial_dbscan(0.5)) contraction = contract_nodes(smooth, groups) unique = contract_nodes(contraction, st_match(st_geometry(net))) make_ggraph(net) make_ggraph(unique)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"spatial-filters","dir":"Articles","previous_headings":"","what":"Spatial filters","title":"Spatial joins and filters","text":"Information can filtered network using spatial predicate functions inside sf function sf::st_filter(), works follows: function applied set geometries respect another set geometries B, removes features based spatial relation features B. practical example: using predicate intersects, geometries intersect geometry B removed. applying sf::st_filter() sfnetwork, internally applied active element network. example: filtering information network activated nodes, using set polygons B predicate intersects, remove nodes intersect polygons B network. edges active, remove edges intersect polygons B network. Although filter applied active element network, may also affect element. nodes removed, incident edges removed well. However, edges removed, nodes endpoints remain, even don’t incident edges. behavior inherited tidygraph understandable graph theory point view: definition nodes can exist peacefully isolation, edges can never exist without nodes endpoints. isolated nodes remain filtering edges can easily removed using combination regular dplyr::filter() verb tidygraph::node_is_isolated() query function. Original network Filtered nodes Filtered edges Removed isolated nodes non-spatial filters applied attribute columns, simply use dplyr::filter() instead sf::st_filter(). tidygraph, filtering information networks done using specific node edge query functions inside dplyr::filter() verb. example already shown , isolated nodes removed network. sfnetworks, several spatial predicates implemented node edge query functions can also spatial filtering tidygraph style. See list implemented spatial node query functions, spatial edge query functions. Using makes spatial filter operations fit better tidy workflows tidygraph. example, filter edges cross edge. tidygraph::.E() function used example makes possible directly access complete edges table inside verbs. Similarly, can use tidygraph::.N() access nodes table tidygraph::.G() access network object whole. Original network Filtered network Besides predicate query functions, can also use coordinate query functions spatial filters nodes. example: Original network Filtered network Filtering returns subset original geometries, leaves geometries unchanged. different clipping, get cut border provided clip feature. three ways can : sf::st_intersection() keeps parts original geometries lie within clip feature, sf::st_difference() keeps parts original geometries lie outside clip feature, sf::st_crop() keeps parts original geometries lie within bounding box clip feature. Note case nodes, clipping different filtering, since point geometries fall party inside partly outside another feature. However, case edges, clipping cut linestring geometries edges border clip feature (case cropping, bounding box feature). preserve valid spatial network structure, sfnetworks adds new nodes cut locations. Original network Filtered Clipped","code":"net = as_sfnetwork(mozart, \"gabriel\") ply = st_buffer(st_centroid(st_combine(mozart)), 300) filtered_by_nodes = net |> st_filter(ply, .pred = st_intersects) filtered_by_edges_a = net |> activate(edges) |> st_filter(ply, .pred = st_intersects) filtered_by_edges_b = net |> activate(edges) |> st_filter(ply, .pred = st_intersects) |> activate(nodes) |> filter(!node_is_isolated()) ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_nodes, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_edges_a, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_edges_b, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() complete_net = as_sfnetwork(mozart, \"complete\") filtered = complete_net |> activate(edges) |> filter(!edge_crosses(.E())) |> activate(nodes) |> filter(!node_is_isolated()) ggraph(complete_net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(filtered, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() x = 4549358 filtered_by_coords = net |> filter(node_X() > x) ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_vline(xintercept = x, linewidth = 1, color = \"orange\") + theme_void() ggraph(filtered_by_coords, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_vline(xintercept = x, linewidth = 1, color = \"orange\") + theme_void() clipped = net |> activate(edges) |> st_intersection(ply) |> activate(nodes) |> filter(!node_is_isolated()) #> Warning: attribute variables are assumed to be spatially constant throughout #> all geometries ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_edges_b, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(clipped, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"using-st_filter","dir":"Articles","previous_headings":"","what":"Using st_filter","title":"Spatial joins and filters","text":"Information can filtered network using spatial predicate functions inside sf function sf::st_filter(), works follows: function applied set geometries respect another set geometries B, removes features based spatial relation features B. practical example: using predicate intersects, geometries intersect geometry B removed. applying sf::st_filter() sfnetwork, internally applied active element network. example: filtering information network activated nodes, using set polygons B predicate intersects, remove nodes intersect polygons B network. edges active, remove edges intersect polygons B network. Although filter applied active element network, may also affect element. nodes removed, incident edges removed well. However, edges removed, nodes endpoints remain, even don’t incident edges. behavior inherited tidygraph understandable graph theory point view: definition nodes can exist peacefully isolation, edges can never exist without nodes endpoints. isolated nodes remain filtering edges can easily removed using combination regular dplyr::filter() verb tidygraph::node_is_isolated() query function. Original network Filtered nodes Filtered edges Removed isolated nodes non-spatial filters applied attribute columns, simply use dplyr::filter() instead sf::st_filter().","code":"net = as_sfnetwork(mozart, \"gabriel\") ply = st_buffer(st_centroid(st_combine(mozart)), 300) filtered_by_nodes = net |> st_filter(ply, .pred = st_intersects) filtered_by_edges_a = net |> activate(edges) |> st_filter(ply, .pred = st_intersects) filtered_by_edges_b = net |> activate(edges) |> st_filter(ply, .pred = st_intersects) |> activate(nodes) |> filter(!node_is_isolated()) ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_nodes, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_edges_a, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_edges_b, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"using-spatial-node-and-edge-query-functions","dir":"Articles","previous_headings":"","what":"Using spatial node and edge query functions","title":"Spatial joins and filters","text":"tidygraph, filtering information networks done using specific node edge query functions inside dplyr::filter() verb. example already shown , isolated nodes removed network. sfnetworks, several spatial predicates implemented node edge query functions can also spatial filtering tidygraph style. See list implemented spatial node query functions, spatial edge query functions. Using makes spatial filter operations fit better tidy workflows tidygraph. example, filter edges cross edge. tidygraph::.E() function used example makes possible directly access complete edges table inside verbs. Similarly, can use tidygraph::.N() access nodes table tidygraph::.G() access network object whole. Original network Filtered network Besides predicate query functions, can also use coordinate query functions spatial filters nodes. example: Original network Filtered network","code":"complete_net = as_sfnetwork(mozart, \"complete\") filtered = complete_net |> activate(edges) |> filter(!edge_crosses(.E())) |> activate(nodes) |> filter(!node_is_isolated()) ggraph(complete_net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(filtered, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() x = 4549358 filtered_by_coords = net |> filter(node_X() > x) ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_vline(xintercept = x, linewidth = 1, color = \"orange\") + theme_void() ggraph(filtered_by_coords, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_vline(xintercept = x, linewidth = 1, color = \"orange\") + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"clipping","dir":"Articles","previous_headings":"","what":"Clipping","title":"Spatial joins and filters","text":"Filtering returns subset original geometries, leaves geometries unchanged. different clipping, get cut border provided clip feature. three ways can : sf::st_intersection() keeps parts original geometries lie within clip feature, sf::st_difference() keeps parts original geometries lie outside clip feature, sf::st_crop() keeps parts original geometries lie within bounding box clip feature. Note case nodes, clipping different filtering, since point geometries fall party inside partly outside another feature. However, case edges, clipping cut linestring geometries edges border clip feature (case cropping, bounding box feature). preserve valid spatial network structure, sfnetworks adds new nodes cut locations. Original network Filtered Clipped","code":"clipped = net |> activate(edges) |> st_intersection(ply) |> activate(nodes) |> filter(!node_is_isolated()) #> Warning: attribute variables are assumed to be spatially constant throughout #> all geometries ggraph(net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(filtered_by_edges_b, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void() ggraph(clipped, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf(data = ply, color = \"orange\", fill = NA, linewidth = 1) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"spatial-joins","dir":"Articles","previous_headings":"","what":"Spatial joins","title":"Spatial joins and filters","text":"Information can spatially joined network using spatial predicate functions inside sf function sf::st_join(), works follows: function applied set geometries respect another set geometries B, attaches feature attributes features B features based spatial relation. practical example: using predicate intersects, feature attributes feature y B attached feature x whenever x intersects y. applying sf::st_join() sfnetwork object, internally applied active element network. example: joining information network activated nodes, set polygons B using predicate intersects, attach attributes polygon B nodes intersect specific polygon. edges active, attach information intersecting edges instead. Lets show example first create imaginary postal code areas Mozart dataset. Original network postal codes Network joined information example , polygons spatially distinct. Hence, node can intersect single polygon. happen join polygons overlap? attributes polygon attached node intersects multiple polygons ? sf issue solved duplicating point much times number polygons intersects , attaching attributes intersecting polygon one duplicates. approach fit network case, however. edge can single node endpoints, thus, duplicated nodes isolated redundant network structure. Therefore, sfnetworks join information first match whenever multiple matches single node. warning given case aware fact information joined network. set ignore_multiple = FALSE, multiple matches result duplicated nodes, duplicates isolated (.e. connected rest network). can use morpher to_spatial_unique() merge spatially duplicated nodes one, specifying attributes combined. See example. Note case joining edges, multiple matches per edge problem network structure. simply duplicate edge (.e. creating set parallel edges) whenever occurs. non-spatial joins based attribute columns, simply use join function dplyr (e.g. dplyr::left_join() dplyr::inner_join()) instead sf::st_join(). Another network specific use-case spatial joins join information external points interest (POIs) nodes network. However, , points need exactly equal coordinates one nodes. Often case. solve situations, first need update coordinates POIs match nearest node. can done using st_project_on_network(). Original network POIs POIs snapped network snapping POIs, can use sf::st_join() expected. remember multiple POIs snapped node, information first one joined network, unless set ignore_multiple = FALSE. example , makes sense include information first POI already existing node. second POI, however, nearest node quite far away relative nearest location nearest edge. case, might want split edge location, add new node network. combination process use metaphor throwing network POIs together blender, mix smoothly together. function st_network_blend() exactly . POI, finds nearest location pp nearest edge ee. pp already existing node (.e. pp endpoint ee), joins information POI node. pp already existing node, subdivides ee pp, adds pp new node network, joins information POI new node. process, matter pp interior point linestring geometry ee. Original network POIs POIs blended network st_network_blend() function tolerance parameter, defines maximum distance POI can network order blended . Hence, POIs least close network tolerance distance blended, others ignored. tolerance can specified non-negative number. default assumed units meters, behavior can changed manually setting units units::units(). Blend without tolerance Blend tolerance important details aware using st_network_blend(). Firstly: multiple POIs nearest location nearest edge, first blended network. reasons explained : network structure clear approach dealing duplicated nodes. arranging table POIs dplyr::arrange() blending can influence (type ) POI given priority cases. also option set ignore_duplicates = FALSE. , duplicated projections result duplicated nodes, duplicates isolated (.e. connected rest network). can use morpher to_spatial_unique() merge spatially duplicated nodes one, specifying attributes combined. See example. Secondly: single POI multiple nearest edges, blended first edges. Therefore, might good idea run to_spatial_subdivision() morpher blending, intersecting unconnected edges get connected. Lastly: important aware floating point precision. See discussion GitHub issue background. short: due internal rounding rational numbers R actually possible even intersection point two lines evaluated intersecting lines . Sounds confusing? ! see example : : expect intersection edge blended network even set tolerance = 0, fact always happen. avoid problems, can better set tolerance small number instead zero. examples joining information external features network. joining two networks? st_network_join() function . takes two sfnetworks input makes spatial full join geometries nodes data, based equals spatial predicate. means, nodes network x nodes network y present joined network, nodes x equal geometries nodes y, nodes become single node joined network. Edge data combined using dplyr::bind_rows() semantic, meaning data matched column name values filled NA missing either networks. columns edge data updated automatically correctly match new node indices joined network. spatial join performed edges. Hence, edge x equal geometry edge y, remain separate edges joined network. Two networks Joined network","code":"codes = net |> st_make_grid(n = c(2, 2)) |> st_as_sf() |> mutate(code = as.character(seq(1000, 1000 + n() * 10 - 10, 10))) joined = net |> st_join(codes, join = st_intersects) joined #> # A sfnetwork: 17 nodes and 50 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 5 (active) #> name type website geometry code #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) 1010 #> 2 Haus für Mozart theatre NA (4549003 2747376) 1000 #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 1010 #> 4 Mozart Denkmal artwork NA (4549387 2747514) 1010 #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 1010 #> 6 Mozartsteg bridge NA (4549473 2747624) 1010 #> # ℹ 11 more rows #> # #> # Edge data: 50 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 1 4 (4549504 2747309, 4549387 2747514) #> 3 2 4 (4549003 2747376, 4549387 2747514) #> # ℹ 47 more rows ggraph(net, \"sf\") + geom_sf(data = codes, aes(fill = code)) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(joined, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = code), size = 4) + theme_void() box = st_as_sfc(st_bbox(mozart)) two_equal_polys = st_as_sf(c(box, box)) |> mutate(foo = c(\"a\", \"b\")) # Join on nodes gives a warning that only the first match per node is joined. # The number of nodes in the resulting network remains the same. net |> st_join(two_equal_polys, join = st_intersects) #> Warning: [1m[22m`st_join()` did not join all features. #> [33m![39m Multiple matches were detected for some nodes, of which all but the first one #> are ignored. #> [36mℹ[39m If you want to add multiple matches as isolated nodes instead, set #> `ignore_multiple` to `FALSE`. #> # A sfnetwork: 17 nodes and 50 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 5 (active) #> name type website geometry foo #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) a #> 2 Haus für Mozart theatre NA (4549003 2747376) a #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) a #> 4 Mozart Denkmal artwork NA (4549387 2747514) a #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) a #> 6 Mozartsteg bridge NA (4549473 2747624) a #> # ℹ 11 more rows #> # #> # Edge data: 50 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 1 4 (4549504 2747309, 4549387 2747514) #> 3 2 4 (4549003 2747376, 4549387 2747514) #> # ℹ 47 more rows # With these settings multiple matches result in duplicated nodes. # In this example it means we have twice the number of nodes than before. # The duplicated nodes are isolated, i.e. not connected to any other node. net |> st_join(two_equal_polys, join = st_intersects, ignore_multiple = FALSE) #> Warning: [1m[22m`st_join()` created isolated nodes. #> [33m![39m Multiple matches were detected for some nodes, of which all but the first one #> are added as isolated nodes to the network. #> [36mℹ[39m If you want to ignore multiple matches instead, set `ignore_multiple` to #> `TRUE`. #> # A sfnetwork: 34 nodes and 50 edges #> # #> # A bipartite simple graph with 18 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 34 × 5 (active) #> name type website foo geometry #> #> 1 Mozartkino cinema https://www.mo… a (4549504 2747309) #> 2 Haus für Mozart theatre NA a (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA a (4549589 2747507) #> 4 Mozart Denkmal artwork NA a (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA a (4549491 2747551) #> 6 Mozartsteg bridge NA a (4549473 2747624) #> # ℹ 28 more rows #> # #> # Edge data: 50 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 1 4 (4549504 2747309, 4549387 2747514) #> 3 2 4 (4549003 2747376, 4549387 2747514) #> # ℹ 47 more rows # Join on edges duplicates edges that have multiple matches. # The number of edges in the resulting network is higher than in the original. net |> activate(edges) |> st_join(two_equal_polys, join = st_intersects) #> # A sfnetwork: 17 nodes and 100 edges #> # #> # A bipartite multigraph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 100 × 4 (active) #> from to geometry foo #> #> 1 1 3 (4549504 2747309, 4549589 2747507) a #> 2 1 3 (4549504 2747309, 4549589 2747507) b #> 3 1 4 (4549504 2747309, 4549387 2747514) a #> 4 1 4 (4549504 2747309, 4549387 2747514) b #> 5 2 4 (4549003 2747376, 4549387 2747514) a #> 6 2 4 (4549003 2747376, 4549387 2747514) b #> # ℹ 94 more rows #> # #> # Node data: 17 × 4 #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> # ℹ 14 more rows # Create a network. n1 = st_point(c(0, 0)) n2 = st_point(c(1, 0)) net = st_sf(geometry = st_sfc(st_linestring(c(n1, n2)))) |> as_sfnetwork() # Create a set of POIs. p1 = st_point(c(0, 0.2)) p2 = st_point(c(0.6, 0.2)) pois = st_sf( poi_type = c(\"bakery\", \"butcher\"), geometry = st_sfc(p1, p2) ) # Update coordinates of POIs to match their nearest node. ppois = st_project_on_network(pois, net, on = \"nodes\") ggraph(net, \"sf\") + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(net, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(ppois)), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf( data = ppois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + theme_void() st_join(net, ppois) #> # A sfnetwork: 2 nodes and 1 edges #> # #> # A rooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 1 ymax: 0 #> # CRS: NA #> # #> # Node data: 2 × 2 (active) #> geometry poi_type #> #> 1 (0 0) bakery #> 2 (1 0) butcher #> # #> # Edge data: 1 × 3 #> from to geometry #> #> 1 1 2 (0 0, 1 0) blend = st_network_blend(net, pois) blend #> # A sfnetwork: 3 nodes and 2 edges #> # #> # A rooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 1 ymax: 0 #> # CRS: NA #> # #> # Node data: 3 × 2 (active) #> geometry poi_type #> #> 1 (0 0) bakery #> 2 (1 0) NA #> 3 (0.6 0) butcher #> # #> # Edge data: 2 × 3 #> from to geometry #> #> 1 1 3 (0 0, 0.6 0) #> 2 3 2 (0.6 0, 1 0) ggraph(net, \"sf\") + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(blend, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() # Update the POIs. p3 = st_point(c(0.4, 0.3)) pois = st_sf( poi_type = c(\"bakery\", \"butcher\", \"bar\"), geometry = st_sfc(p1, p2, p3) ) blend = st_network_blend(net, pois) blend_with_tolerance = st_network_blend(net, pois, tolerance = 0.2) ggraph(blend, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(blend_with_tolerance, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() # Create two intersecting lines. p1 = st_point(c(0.53236, 1.95377)) p2 = st_point(c(0.53209, 1.95328)) l1 = st_sfc(st_linestring(c(p1, p2))) p3 = st_point(c(0.53209, 1.95345)) p4 = st_point(c(0.53245, 1.95345)) l2 = st_sfc(st_linestring(c(p3, p4))) # The two lines share an intersection point. st_intersection(l1, l2) #> Geometry set for 1 feature #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 0.5321837 ymin: 1.95345 xmax: 0.5321837 ymax: 1.95345 #> CRS: NA #> POINT (0.5321837 1.95345) # But this intersection point does not intersects the line itself! st_intersects(l1, st_intersection(l1, l2), sparse = FALSE) #> [,1] #> [1,] FALSE # The intersection point is instead located a tiny bit next to the line. st_distance(l1, st_intersection(l1, l2)) #> [,1] #> [1,] 4.310191e-17 net = as_sfnetwork(l1) p = st_intersection(l1, l2) plot(l1) plot(l2, col = \"grey\", lwd = 2, add = TRUE) plot(st_network_blend(net, p, tolerance = 0), lwd = 2, cex = 2, add = TRUE) #> Warning: [1m[22m`st_network_blend()` did not blend any points into the network. #> [36mℹ[39m Increase `tolerance` for a higher tolerance distance. plot(l1) plot(l2, col = \"grey\", lwd = 2, add = TRUE) plot(st_network_blend(net, p, tolerance = 1e-10), lwd = 2, cex = 2, add = TRUE) # Create two networks. # Create a network. n1 = st_point(c(0, 0)) n2 = st_point(c(1, 0)) n3 = st_point(c(1, 1)) n4 = st_point(c(0, 1)) e1 = st_sfc(st_linestring(c(n1, n2))) e2 = st_sfc(st_linestring(c(n2, n3))) e3 = st_sfc(st_linestring(c(n3, n4))) neta = st_sf(geometry = c(e1, e2)) |> as_sfnetwork() netb = st_sf(geometry = c(e2, e3)) |> as_sfnetwork() # Join them into a single network. joined = st_network_join(neta, netb) joined #> # A sfnetwork: 4 nodes and 4 edges #> # #> # A directed acyclic multigraph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 1 ymax: 1 #> # CRS: NA #> # #> # Node data: 4 × 1 (active) #> geometry #> #> 1 (0 0) #> 2 (1 0) #> 3 (1 1) #> 4 (0 1) #> # #> # Edge data: 4 × 3 #> from to geometry #> #> 1 1 2 (0 0, 1 0) #> 2 2 3 (1 0, 1 1) #> 3 2 3 (1 0, 1 1) #> # ℹ 1 more row plot(neta, col = \"skyblue\", pch = 15, cex = 2, lwd = 4) plot(netb, col = \"orange\", pch = 18, cex = 2, lty = 2, lwd = 4, add = TRUE) plot(joined, cex = 2, lwd = 4)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"using-st_join","dir":"Articles","previous_headings":"","what":"Using st_join","title":"Spatial joins and filters","text":"Information can spatially joined network using spatial predicate functions inside sf function sf::st_join(), works follows: function applied set geometries respect another set geometries B, attaches feature attributes features B features based spatial relation. practical example: using predicate intersects, feature attributes feature y B attached feature x whenever x intersects y. applying sf::st_join() sfnetwork object, internally applied active element network. example: joining information network activated nodes, set polygons B using predicate intersects, attach attributes polygon B nodes intersect specific polygon. edges active, attach information intersecting edges instead. Lets show example first create imaginary postal code areas Mozart dataset. Original network postal codes Network joined information example , polygons spatially distinct. Hence, node can intersect single polygon. happen join polygons overlap? attributes polygon attached node intersects multiple polygons ? sf issue solved duplicating point much times number polygons intersects , attaching attributes intersecting polygon one duplicates. approach fit network case, however. edge can single node endpoints, thus, duplicated nodes isolated redundant network structure. Therefore, sfnetworks join information first match whenever multiple matches single node. warning given case aware fact information joined network. set ignore_multiple = FALSE, multiple matches result duplicated nodes, duplicates isolated (.e. connected rest network). can use morpher to_spatial_unique() merge spatially duplicated nodes one, specifying attributes combined. See example. Note case joining edges, multiple matches per edge problem network structure. simply duplicate edge (.e. creating set parallel edges) whenever occurs. non-spatial joins based attribute columns, simply use join function dplyr (e.g. dplyr::left_join() dplyr::inner_join()) instead sf::st_join().","code":"codes = net |> st_make_grid(n = c(2, 2)) |> st_as_sf() |> mutate(code = as.character(seq(1000, 1000 + n() * 10 - 10, 10))) joined = net |> st_join(codes, join = st_intersects) joined #> # A sfnetwork: 17 nodes and 50 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 5 (active) #> name type website geometry code #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) 1010 #> 2 Haus für Mozart theatre NA (4549003 2747376) 1000 #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) 1010 #> 4 Mozart Denkmal artwork NA (4549387 2747514) 1010 #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) 1010 #> 6 Mozartsteg bridge NA (4549473 2747624) 1010 #> # ℹ 11 more rows #> # #> # Edge data: 50 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 1 4 (4549504 2747309, 4549387 2747514) #> 3 2 4 (4549003 2747376, 4549387 2747514) #> # ℹ 47 more rows ggraph(net, \"sf\") + geom_sf(data = codes, aes(fill = code)) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(joined, \"sf\") + geom_edge_sf() + geom_node_sf(aes(color = code), size = 4) + theme_void() box = st_as_sfc(st_bbox(mozart)) two_equal_polys = st_as_sf(c(box, box)) |> mutate(foo = c(\"a\", \"b\")) # Join on nodes gives a warning that only the first match per node is joined. # The number of nodes in the resulting network remains the same. net |> st_join(two_equal_polys, join = st_intersects) #> Warning: [1m[22m`st_join()` did not join all features. #> [33m![39m Multiple matches were detected for some nodes, of which all but the first one #> are ignored. #> [36mℹ[39m If you want to add multiple matches as isolated nodes instead, set #> `ignore_multiple` to `FALSE`. #> # A sfnetwork: 17 nodes and 50 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 5 (active) #> name type website geometry foo #> #> 1 Mozartkino cinema https://www.mo… (4549504 2747309) a #> 2 Haus für Mozart theatre NA (4549003 2747376) a #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) a #> 4 Mozart Denkmal artwork NA (4549387 2747514) a #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) a #> 6 Mozartsteg bridge NA (4549473 2747624) a #> # ℹ 11 more rows #> # #> # Edge data: 50 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 1 4 (4549504 2747309, 4549387 2747514) #> 3 2 4 (4549003 2747376, 4549387 2747514) #> # ℹ 47 more rows # With these settings multiple matches result in duplicated nodes. # In this example it means we have twice the number of nodes than before. # The duplicated nodes are isolated, i.e. not connected to any other node. net |> st_join(two_equal_polys, join = st_intersects, ignore_multiple = FALSE) #> Warning: [1m[22m`st_join()` created isolated nodes. #> [33m![39m Multiple matches were detected for some nodes, of which all but the first one #> are added as isolated nodes to the network. #> [36mℹ[39m If you want to ignore multiple matches instead, set `ignore_multiple` to #> `TRUE`. #> # A sfnetwork: 34 nodes and 50 edges #> # #> # A bipartite simple graph with 18 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 34 × 5 (active) #> name type website foo geometry #> #> 1 Mozartkino cinema https://www.mo… a (4549504 2747309) #> 2 Haus für Mozart theatre NA a (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA a (4549589 2747507) #> 4 Mozart Denkmal artwork NA a (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA a (4549491 2747551) #> 6 Mozartsteg bridge NA a (4549473 2747624) #> # ℹ 28 more rows #> # #> # Edge data: 50 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 1 4 (4549504 2747309, 4549387 2747514) #> 3 2 4 (4549003 2747376, 4549387 2747514) #> # ℹ 47 more rows # Join on edges duplicates edges that have multiple matches. # The number of edges in the resulting network is higher than in the original. net |> activate(edges) |> st_join(two_equal_polys, join = st_intersects) #> # A sfnetwork: 17 nodes and 100 edges #> # #> # A bipartite multigraph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 100 × 4 (active) #> from to geometry foo #> #> 1 1 3 (4549504 2747309, 4549589 2747507) a #> 2 1 3 (4549504 2747309, 4549589 2747507) b #> 3 1 4 (4549504 2747309, 4549387 2747514) a #> 4 1 4 (4549504 2747309, 4549387 2747514) b #> 5 2 4 (4549003 2747376, 4549387 2747514) a #> 6 2 4 (4549003 2747376, 4549387 2747514) b #> # ℹ 94 more rows #> # #> # Node data: 17 × 4 #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> # ℹ 14 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"join-points-to-their-nearest-node","dir":"Articles","previous_headings":"","what":"Join points to their nearest node","title":"Spatial joins and filters","text":"Another network specific use-case spatial joins join information external points interest (POIs) nodes network. However, , points need exactly equal coordinates one nodes. Often case. solve situations, first need update coordinates POIs match nearest node. can done using st_project_on_network(). Original network POIs POIs snapped network snapping POIs, can use sf::st_join() expected. remember multiple POIs snapped node, information first one joined network, unless set ignore_multiple = FALSE.","code":"# Create a network. n1 = st_point(c(0, 0)) n2 = st_point(c(1, 0)) net = st_sf(geometry = st_sfc(st_linestring(c(n1, n2)))) |> as_sfnetwork() # Create a set of POIs. p1 = st_point(c(0, 0.2)) p2 = st_point(c(0.6, 0.2)) pois = st_sf( poi_type = c(\"bakery\", \"butcher\"), geometry = st_sfc(p1, p2) ) # Update coordinates of POIs to match their nearest node. ppois = st_project_on_network(pois, net, on = \"nodes\") ggraph(net, \"sf\") + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(net, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(ppois)), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + geom_sf( data = ppois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + theme_void() st_join(net, ppois) #> # A sfnetwork: 2 nodes and 1 edges #> # #> # A rooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 1 ymax: 0 #> # CRS: NA #> # #> # Node data: 2 × 2 (active) #> geometry poi_type #> #> 1 (0 0) bakery #> 2 (1 0) butcher #> # #> # Edge data: 1 × 3 #> from to geometry #> #> 1 1 2 (0 0, 1 0)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"blending-points-into-a-network","dir":"Articles","previous_headings":"","what":"Blending points into a network","title":"Spatial joins and filters","text":"example , makes sense include information first POI already existing node. second POI, however, nearest node quite far away relative nearest location nearest edge. case, might want split edge location, add new node network. combination process use metaphor throwing network POIs together blender, mix smoothly together. function st_network_blend() exactly . POI, finds nearest location pp nearest edge ee. pp already existing node (.e. pp endpoint ee), joins information POI node. pp already existing node, subdivides ee pp, adds pp new node network, joins information POI new node. process, matter pp interior point linestring geometry ee. Original network POIs POIs blended network st_network_blend() function tolerance parameter, defines maximum distance POI can network order blended . Hence, POIs least close network tolerance distance blended, others ignored. tolerance can specified non-negative number. default assumed units meters, behavior can changed manually setting units units::units(). Blend without tolerance Blend tolerance important details aware using st_network_blend(). Firstly: multiple POIs nearest location nearest edge, first blended network. reasons explained : network structure clear approach dealing duplicated nodes. arranging table POIs dplyr::arrange() blending can influence (type ) POI given priority cases. also option set ignore_duplicates = FALSE. , duplicated projections result duplicated nodes, duplicates isolated (.e. connected rest network). can use morpher to_spatial_unique() merge spatially duplicated nodes one, specifying attributes combined. See example. Secondly: single POI multiple nearest edges, blended first edges. Therefore, might good idea run to_spatial_subdivision() morpher blending, intersecting unconnected edges get connected. Lastly: important aware floating point precision. See discussion GitHub issue background. short: due internal rounding rational numbers R actually possible even intersection point two lines evaluated intersecting lines . Sounds confusing? ! see example : : expect intersection edge blended network even set tolerance = 0, fact always happen. avoid problems, can better set tolerance small number instead zero.","code":"blend = st_network_blend(net, pois) blend #> # A sfnetwork: 3 nodes and 2 edges #> # #> # A rooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 1 ymax: 0 #> # CRS: NA #> # #> # Node data: 3 × 2 (active) #> geometry poi_type #> #> 1 (0 0) bakery #> 2 (1 0) NA #> 3 (0.6 0) butcher #> # #> # Edge data: 2 × 3 #> from to geometry #> #> 1 1 3 (0 0, 0.6 0) #> 2 3 2 (0.6 0, 1 0) ggraph(net, \"sf\") + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(blend, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() # Update the POIs. p3 = st_point(c(0.4, 0.3)) pois = st_sf( poi_type = c(\"bakery\", \"butcher\", \"bar\"), geometry = st_sfc(p1, p2, p3) ) blend = st_network_blend(net, pois) blend_with_tolerance = st_network_blend(net, pois, tolerance = 0.2) ggraph(blend, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(blend_with_tolerance, \"sf\") + geom_sf( data = st_nearest_points(pois, st_combine(st_geometry(blend, \"nodes\"))), color = \"grey\", linetype = 2 ) + geom_sf( data = pois, aes(color = poi_type), pch = 8, size = 4, show.legend = FALSE ) + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() # Create two intersecting lines. p1 = st_point(c(0.53236, 1.95377)) p2 = st_point(c(0.53209, 1.95328)) l1 = st_sfc(st_linestring(c(p1, p2))) p3 = st_point(c(0.53209, 1.95345)) p4 = st_point(c(0.53245, 1.95345)) l2 = st_sfc(st_linestring(c(p3, p4))) # The two lines share an intersection point. st_intersection(l1, l2) #> Geometry set for 1 feature #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 0.5321837 ymin: 1.95345 xmax: 0.5321837 ymax: 1.95345 #> CRS: NA #> POINT (0.5321837 1.95345) # But this intersection point does not intersects the line itself! st_intersects(l1, st_intersection(l1, l2), sparse = FALSE) #> [,1] #> [1,] FALSE # The intersection point is instead located a tiny bit next to the line. st_distance(l1, st_intersection(l1, l2)) #> [,1] #> [1,] 4.310191e-17 net = as_sfnetwork(l1) p = st_intersection(l1, l2) plot(l1) plot(l2, col = \"grey\", lwd = 2, add = TRUE) plot(st_network_blend(net, p, tolerance = 0), lwd = 2, cex = 2, add = TRUE) #> Warning: [1m[22m`st_network_blend()` did not blend any points into the network. #> [36mℹ[39m Increase `tolerance` for a higher tolerance distance. plot(l1) plot(l2, col = \"grey\", lwd = 2, add = TRUE) plot(st_network_blend(net, p, tolerance = 1e-10), lwd = 2, cex = 2, add = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn04_join_filter.html","id":"joining-two-networks","dir":"Articles","previous_headings":"","what":"Joining two networks","title":"Spatial joins and filters","text":"examples joining information external features network. joining two networks? st_network_join() function . takes two sfnetworks input makes spatial full join geometries nodes data, based equals spatial predicate. means, nodes network x nodes network y present joined network, nodes x equal geometries nodes y, nodes become single node joined network. Edge data combined using dplyr::bind_rows() semantic, meaning data matched column name values filled NA missing either networks. columns edge data updated automatically correctly match new node indices joined network. spatial join performed edges. Hence, edge x equal geometry edge y, remain separate edges joined network. Two networks Joined network","code":"# Create two networks. # Create a network. n1 = st_point(c(0, 0)) n2 = st_point(c(1, 0)) n3 = st_point(c(1, 1)) n4 = st_point(c(0, 1)) e1 = st_sfc(st_linestring(c(n1, n2))) e2 = st_sfc(st_linestring(c(n2, n3))) e3 = st_sfc(st_linestring(c(n3, n4))) neta = st_sf(geometry = c(e1, e2)) |> as_sfnetwork() netb = st_sf(geometry = c(e2, e3)) |> as_sfnetwork() # Join them into a single network. joined = st_network_join(neta, netb) joined #> # A sfnetwork: 4 nodes and 4 edges #> # #> # A directed acyclic multigraph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 1 ymax: 1 #> # CRS: NA #> # #> # Node data: 4 × 1 (active) #> geometry #> #> 1 (0 0) #> 2 (1 0) #> 3 (1 1) #> 4 (0 1) #> # #> # Edge data: 4 × 3 #> from to geometry #> #> 1 1 2 (0 0, 1 0) #> 2 2 3 (1 0, 1 1) #> 3 2 3 (1 0, 1 1) #> # ℹ 1 more row plot(neta, col = \"skyblue\", pch = 15, cex = 2, lwd = 4) plot(netb, col = \"orange\", pch = 18, cex = 2, lty = 2, lwd = 4, add = TRUE) plot(joined, cex = 2, lwd = 4)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"the-basics","dir":"Articles","previous_headings":"","what":"The basics","title":"Routing on spatial networks","text":"sfnetworks two core functions routing spatial networks. first one, st_network_paths(), returns course optimal paths pairs nodes. second one, st_network_cost(), returns matrix optimal travel costs pairs nodes. functions need provided nodes route (origins), nodes route (destinations). basic way integer node indices, correspond rownumbers nodes table. many ways, though, explained detail section. Secondly, specified weight edge . Higher edge weights result higher travel costs. default, sfnetworks always use geographic lengths edges. possible specify different edge weights, explained detail section. function st_network_paths() returns sf object one row per requested path. Columns contain node indices origin destination path. column node_path contains indices nodes path, order visit. Similarly, column edge_path contains indices edges paths, order visit. nodes /edges names stored column named name want use values instead encode , set use_names = TRUE. Column cost stores total travel cost path. geometry column linestring resulted concatenating individual geometries visited edges. function st_network_cost() returns n×mn \\times m matrix, nn number specified origins, mm number specified destinations. Element AijA_{ij} stores total travel cost shortest path ii-th origin jj-th destination. matrix usually important starting point analysis. example, can serve input route optimization algorithms, spatial clustering algorithms calculation statistical measures based spatial proximity. also function st_network_distance(), synonym st_network_cost() edge weights always geographic edge length. function added provide intuitive network-specific alternative sf::st_distance(). note nice little example network nodes connected . many real-world networks may always case, meaning node pairs path . case st_network_paths() still return “path”, empty geometry FALSE value path_found column. st_network_cost() store Inf value. many cases, good idea first extract largest connected component network computing routes. can done morpher tidygraph::to_largest_component(). Full network Largest component want extract shortest paths linestring geometries, rather subset network keep nodes edges path, to_spatial_shortest_paths() morpher choice. accepts arguments st_network_paths(), return filtered network requested path. nodes edges tables sub-network arranged order appear path. Path 1 -> 12 Path 1 -> 16 Path 1 -> 17","code":"# Create a network. net = as_sfnetwork(mozart, \"gabriel\", directed = FALSE) # Compute the shortest path between node 1 and nodes 12 and 17. paths = st_network_paths(net, 1, c(12, 17)) paths #> Simple feature collection with 2 features and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549504 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 2 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 1 12 TRUE 1081. (4549504 2747309, 4549387 27… #> 2 1 17 TRUE 1436. (4549504 2747309, 4549387 27… # Do the same but now use node names to encode nodes in the output. paths = st_network_paths(net, 1, c(12, 17), use_names = TRUE) paths #> Simple feature collection with 2 features and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549504 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 2 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 Mozartki… Moza… TRUE 1081. (4549504 2747309, 454938… #> 2 Mozartki… Moza… TRUE 1436. (4549504 2747309, 454938… ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = paths, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(net)[1, ], size = 6) + geom_sf(data = node_data(net)[c(12, 17), ], pch = 15, size = 6) + theme_void() # Compute the cost matrix for travel between three nodes. st_network_cost(net, c(1, 12, 17), c(1, 12, 17)) #> Units: [m] #> 1 12 17 #> 1 0.000 1081.3335 1435.9344 #> 12 1081.333 0.0000 795.9422 #> 17 1435.934 795.9422 0.0000 # Use node names to encode nodes. st_network_cost(net, c(1, 12, 17), c(1, 12, 17), use_names = TRUE) #> Units: [m] #> Mozartkino Mozart-Eine Hommage Mozart Studentenheim #> Mozartkino 0.000 1081.3335 1435.9344 #> Mozart-Eine Hommage 1081.333 0.0000 795.9422 #> Mozart Studentenheim 1435.934 795.9422 0.0000 divided_net = as_sfnetwork(mozart, \"knn\", k = 3, directed = FALSE) #> Warning in spdep::knn2nb(spdep::knearneigh(st_geometry(x), k = k), sym = #> FALSE): neighbour object has 2 sub-graphs paths = st_network_paths(divided_net, 12, c(1, 17)) paths #> Simple feature collection with 2 features and 6 fields (with 1 geometry empty) #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4548664 ymin: 2747868 xmax: 4548984 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 2 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 12 1 FALSE Inf EMPTY #> 2 12 17 TRUE 796. (4548664 2747868, 4548897 274… ggraph(divided_net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = paths, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(divided_net)[12, ], size = 6) + geom_sf(data = node_data(divided_net)[c(1, 17), ], pch = 15, size = 6) + theme_void() st_network_cost(divided_net, c(1, 12, 17), c(1, 12, 17)) #> Units: [m] #> 1 12 17 #> 1 0 Inf Inf #> 12 Inf 0.0000 795.9422 #> 17 Inf 795.9422 0.0000 # Extract only the largest connected component. component = convert(divided_net, to_largest_component) ggraph(divided_net, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() ggraph(component, \"sf\") + geom_edge_sf() + geom_node_sf(size = 4) + theme_void() paths = net |> morph(to_spatial_shortest_paths, 1, c(12, 16, 17)) |> crystallize() paths #> # A tibble: 3 × 2 #> name graph #> #> 1 1 #> 2 2 #> 3 3 purrr::walk(paths$graph, plot, cex = 4)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"choosing-a-routing-backend","dir":"Articles","previous_headings":"","what":"Choosing a routing backend","title":"Routing on spatial networks","text":"mentioned, sfnetworks implement routing algorithms . , relies packages, call “routing backends” “routers” short. default routing backend igraph. st_network_paths() function wraps, depending argument settings, igraph::shortest_paths(), igraph::all_shortest_paths() igraph::k_shortest_paths(). st_network_cost() function wraps igraph::distances(). benefits routing backend : 1) can compute shortest paths, exists one; 2) can compute kk shortest paths Yen’s algorithm; 3) internal conversion data structures needed. However, routing supported single origin. Hence, many--many routing possible. second routing backend currently supported dodgr. package implements fast routing algorithm C++. exposed sfnetworks wrapping dodgr::dodgr_paths() st_network_paths() dodgr::dodgr_dists() st_network_cost(). benefits routing backend : 1) can route multiple origins multiple destinations, .e. many--many routing; 2) supports dual-weighted routing (see ); 3) fast also large networks. However, currently support kk shortest paths routing, internal conversions needed bridge different data structures. can specify routing backend use router argument. want change default routing backend, update global options: options(sfn_default_router = \"dodgr\").","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"specifying-origins-and-destinations","dir":"Articles","previous_headings":"","what":"Specifying origins and destinations","title":"Routing on spatial networks","text":"nodes route (.e. origins) nodes route (.e. destinations) referenced integer index, corresponds rownumber nodes table network. However, sfnetworks allows reference nodes also different ways, internally find corresponding node indices . called sfnetwork node query, evaluated evaluate_node_query(). However, normally never call function directly user. Instead, simply specify node query argument value arguments. query can formatted follows: spatial features: Spatial features can given object class sf sfc. nearest node feature found calling nearest_nodes(). node type query function: node type query specific type node measure function defines node given type . Nodes meet criterium queried. node predicate query function: node predicate query specific type node measure function defines node given spatial predicate applies spatial relation node spatial features. Nodes meet criterium queried. column name: referenced column expected logical values defining node queried . Tidy evaluation used hence column name unquoted. integers: Integers interpreted node indices. node index corresponds row-number nodes table network. characters: Characters interpreted node names. node name corresponds value column named name nodes table network. Note column expected store unique names without duplicated values. logicals: Logicals define node queried .","code":"pt = st_centroid(st_combine(mozart)) pl = st_buffer(mozart[15, ], 350) paths_A = st_network_paths( net, from = pt, to = centrality_degree() < 3 ) paths_B = st_network_paths( net, from = \"Mozartkino\", to = node_is_within(pl) ) ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = paths_A, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(net)[unique(paths_A$from), ], size = 6) + geom_sf(data = node_data(net)[unique(paths_A$to), ], pch = 15, size = 6) + geom_sf(data = pt, color = \"skyblue\", size = 6) + theme_void() ggraph(net, \"sf\") + geom_sf(data = pl, fill = \"skyblue\", alpha = 0.8) + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = paths_B, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(net)[unique(paths_B$from), ], size = 6) + geom_sf(data = node_data(net)[unique(paths_B$to), ], pch = 15, size = 6) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"specifying-edge-weights","dir":"Articles","previous_headings":"","what":"Specifying edge weights","title":"Routing on spatial networks","text":"shortest path , depends weight edge. higher weight, longer edge. spatial network analysis, often makes sense use geographic length edge weights, shortest path path shortest geographic distance. Therefore, sfnetworks uses default. possible specify different edge weights weights argument. Weights specified numeric vector length number edges network. However, sfnetworks allows specify also different ways, internally compute numeric vector . called sfnetwork edge specification, evaluated evaluate_weight_spec(). However, normally never call function directly user. Instead, simply provide specification argument value weights argument. specification can formatted follows: edge measure function: spatial edge measure function computes given measure edge, used edge weights. default edge_length() measure used routing functions. column name: column edges table network contains edge weights. Tidy evaluation used hence column name unquoted. numeric vector: vector length number edges network, specifying edge weight . dual weights: Dual weights can specified dual_weights() function. allows use different set weights shortest paths computation reporting total cost paths. dodgr routing backend supports dual-weighted routing. See example. Edge length Edge speed Shortest route Fastest route important note functions sfnetworks consider edge weights use edge_length() default, case tidygraph. always explicitly specify weights, example computing betweenness centrality using tidygraph::centrality_betweenness(). Otherwise, edge weighted 1, shortest path path fewest number edges. Furthermore, important know igraph different behavior regarding edge weights. weights = NULL, look edge attribute named weight use whenever present. tidygraph, therefore also sfnetworks, , always default edge weights 1 whenever weights = NULL.","code":"# Assign each edge a speed. # Some edges will have a higher speed. # Based on this, compute the travel time of each edge. speeds = set_units(rep(15, n_edges(net)), \"km/h\") speeds[c(17, 25)] = set_units(20, \"km/h\") net = net |> activate(edges) |> mutate(speed = speeds) |> mutate(time = edge_length() / speed) # Now compute the shortest and the fastest routes. shortest = st_network_paths(net, 1, 17, weights = edge_length()) # The default. fastest = st_network_paths(net, 1, 17, weights = time) ggraph(net, \"sf\") + geom_edge_sf(aes(color = drop_units(edge_length())), linewidth = 2) + geom_node_sf(size = 4) + scale_edge_color_continuous(\"length [m]\") + theme_void() ggraph(net, \"sf\") + geom_edge_sf(aes(color = drop_units(speed)), linewidth = 2) + geom_node_sf(size = 4) + scale_edge_color_continuous(\"speed [km/h]\") + theme_void() ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = shortest, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(net)[1, ], size = 6) + geom_sf(data = node_data(net)[17, ], pch = 15, size = 6) + theme_void() ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = fastest, color = \"orange\", linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(net)[1, ], size = 6) + geom_sf(data = node_data(net)[17, ], pch = 15, size = 6) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"applications","dir":"Articles","previous_headings":"","what":"Applications","title":"Routing on spatial networks","text":"section, show small set applications routing related functions. meant overview covers everything. Also, remember sfnetworks general-purpose spatial network analysis package optimized specific application. However, especially combination packages can address wide variety use-cases. Thanks igraph routing backend, can compute shortest path two nodes, also next k−1k-1 shortest paths. , set k argument st_network_paths() integer higher 1. supported one--one routing, .e. single origin single destination. purpose closest facility analysis , given set destination locations (also referred facilities) origin locations (also referred sites), find closest nn facilities site. example, might want find nearest transit hub address city, nearest hospital high-risk road intersections. solve problem, can calculate cost matrix sites origins, facilities destinations points. , row (.e. site) find column(s) lowest cost value. Note facility site represented nearest node network. First blending network using st_network_blend() gives accurate results. traveling salesman problem aims find shortest tour visits every location set exactly . solve , sfnetworks provides interface TSP::TSP() function. requires TSP package installed. st_network_travel() function returns sf object similar output st_network_paths(). row represent one leg route, one location next. Note location visit represented nearest node network. First blending network using st_network_blend() gives accurate results. respect given point pp given distance dd, isodistance line holds distance point line pp equal dd. spatial network analysis, common find nodes fall within isodistance line computed given source node pp. enclosing nodes concave hull, obtain isodistance polygon. workflow implemented function st_network_iso(). first compute distance matrix given source node pp (can specified explained ) nodes network using st_network_cost(), filter nodes within given distance dd. Using sf::st_concave_hull(), compute concave hull around nodes obtain isodistance polygon. Multiple distance thresholds can given, resulting multiple isodistance polygons drawn. output function sf object one row per requested polygon. setting ratio argument (value 0 1, 1 convex hull), can increase decrease level detail polygons. default, holes allowed polygons, can changed setting allow_holes = TRUE. note changing ratio requires GEOS version least 3.11. GEOS C/C++ library computational geometry used sf. different approach can taken morpher to_spatial_neighborhood(). Instead drawing polygons, function subset network contain nodes inside isodistance line, edges connect . st_network_iso() to_spatial_neighborhood() allow specify edge weights geographic distance. can done weights argument, explained . using time edge weight, talk isochrones instead isodistances. many cases shortest path based geographical distances travel time necessarily optimal path. appropriate route may depend many factors, example staying away large potentially unpleasant roads motor traffic. networks different characteristics. OpenStreetMap networks highway attribute often good (albeit crude) approximation road type. roxel demo dataset derived OpenStreetMap stores highway attribute type column. can see Roxel largely residential road network: Building shortest paths calculated previous section can try alternative routing profile. purposes illustration, lets imagine ’re routing vehicle want keep away residential roads. can now compare shortest path optimal path according weighting profile. Shortest route Optimal route Note developing sophisticated routing profiles beyond scope package. need complex mode-specific routing profiles, recommend looking routing profiles associated open source routing engines OSRM, dodgr R package. Another direction travel extend approach illustrated , work well-suited separate package builds sfnetworks, possibly integrating routing profiles dodgr. ’d like work project improve mode-specific routing R building package, please let us know discussion room! many cases may interested obtaining cost matrix stores geographic distances optimal routes according custom set edge weights. , want use custom weights define “shortest” path , report actual geographic distance path. called dual-weighted routing. dodgr routing backend supports . sfnetworks offers dual_weights() function allow specify dual weights weights argument routing functions. accepts two sets weights, can specified ways explained section. first set weights reported weights, second set weights actual weights used define optimal path.","code":"paths = st_network_paths(net, 1, 17, k = 3) paths #> Simple feature collection with 3 features and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4548984 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 3 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 1 17 TRUE 1436. (4549504 2747309, 4549387 27… #> 2 1 17 TRUE 1580. (4549504 2747309, 4549589 27… #> 3 1 17 TRUE 1602. (4549504 2747309, 4549589 27… paths = paths |> mutate(k = c(1:n())) |> arrange(desc(k)) ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = paths, aes(color = as.factor(k)), linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(net)[1, ], size = 6) + geom_sf(data = node_data(net)[17, ], pch = 15, size = 6) + scale_color_discrete(\"k\") + theme_void() # Create a network. net = as_sfnetwork(roxel, directed = FALSE) |> st_transform(3035) # Create some facility locations spread over the area. facilities = st_sfc( st_point(c(4151100, 3207700)), st_point(c(4151040, 3206660)), st_point(c(4151800, 3207200)), st_point(c(4152000, 3207600)), crs = 3035 ) # Select a random set of sites. sites = st_sample(st_convex_hull(st_combine(net)), 50) # Blend the sites and facilities into the network to get better results. # Also select only the largest connected component. # Such that we avoid points being blended to a small disconnected component. net = net |> convert(to_largest_component, .clean = TRUE) |> st_network_blend(c(sites, facilities)) # Calculate the cost matrix. mat = net |> st_network_cost(from = sites, to = facilities) # Find for each site which facility is closest. closest = facilities[apply(mat, 1, function(x) which(x == min(x))[1])] # Create a line between each site and its closest facility, for visualization. draw_lines = function(sources, targets) { f = function(a, b) st_sfc(st_cast(c(a, b), \"LINESTRING\")) lines = do.call(\"c\", mapply(f, sources, targets, SIMPLIFY = FALSE)) st_crs(lines) = st_crs(sources) lines } connections = draw_lines(sites, closest) ggraph(net, \"sf\") + geom_edge_sf(color = \"grey\") + geom_node_sf(color = \"grey\") + geom_sf(data = connections, color = \"orange\") + geom_sf(data = sites, color = \"orange\", size = 4) + geom_sf(data = facilities, color = \"skyblue\", size = 6) + theme_void() # We will use the facilities from the previous section as visiting locations. # They are already blended into the largest component of the network. route = st_network_travel(net, facilities) route #> Simple feature collection with 4 features and 6 fields #> Geometry type: MULTILINESTRING #> Dimension: XY #> Bounding box: xmin: 4150908 ymin: 3206643 xmax: 4152015 ymax: 3207744 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 4 × 7 #> from to node_path edge_path path_found cost geometry #> * [m] #> 1 869 1003 TRUE 602. ((4151793 3207244, 4151805… #> 2 1003 633 TRUE 1074. ((4151039 3206662, 4151063… #> 3 633 1001 TRUE 1385. ((4151138 3207734, 4151160… #> 4 1001 869 TRUE 1178. ((4151073 3207744, 4151097… ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = route, color = \"orange\", linewidth = 2) + geom_sf(data = facilities, size = 6) + theme_void() # Define the source. # This point will be snapped to its nearest node. pt = st_centroid(st_transform(st_as_sfc(st_bbox(roxel)), 3035)) # Compute isodistance polygons for four different thresholds. polys = st_network_iso(net, pt, rev(c(100, 250, 500, 1000))) polys #> Simple feature collection with 4 features and 1 field #> Geometry type: POLYGON #> Dimension: XY #> Bounding box: xmin: 4150754 ymin: 3206653 xmax: 4152274 ymax: 3208212 #> Projected CRS: ETRS89-extended / LAEA Europe #> cost geometry #> 1 1000 [m] POLYGON ((4151598 3206653, ... #> 2 500 [m] POLYGON ((4151611 3207041, ... #> 3 250 [m] POLYGON ((4151519 3207212, ... #> 4 100 [m] POLYGON ((4151540 3207378, ... ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = polys, aes(fill = drop_units(cost)), alpha = 0.5) + scale_fill_continuous(\"distance [m]\") + theme_void() sub_net = convert(net, to_spatial_neighborhood, pt, 500) plot(net, col = \"darkgrey\") plot(sub_net, col = \"orange\", lwd = 2, cex = 1, add = TRUE) roxel |> count(type) #> Simple feature collection with 9 features and 2 fields #> Geometry type: MULTILINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 9 × 3 #> type n geometry #> * #> 1 cycleway 5 ((7.540663 51.95534, 7.540831 51.95536), (7.534414 51.9547… #> 2 footway 134 ((7.543404 51.94779, 7.54358 51.94786, 7.543685 51.9479), … #> 3 path 113 ((7.54059 51.95077, 7.54127 51.95012), (7.53819 51.95738, … #> 4 residential 325 ((7.537815 51.95867, 7.537015 51.95848, 7.537374 51.95787,… #> 5 secondary 54 ((7.532301 51.95559, 7.532214 51.95575, 7.532142 51.95589,… #> 6 service 256 ((7.525727 51.94672, 7.52585 51.94668, 7.526145 51.94655, … #> 7 track 15 ((7.541088 51.95588, 7.541908 51.95604), (7.535803 51.9433… #> 8 unclassified 57 ((7.534157 51.94654, 7.534845 51.94597, 7.534993 51.94583,… #> 9 NA 256 ((7.526311 51.94653, 7.526298 51.94649, 7.526311 51.94644,… ggraph(net, \"sf\") + geom_edge_sf(aes(color = as.factor(type)), linewidth = 2) + geom_node_sf() + scale_edge_color_discrete(\"type\") + theme_void() weighting_profile = c( cycleway = Inf, footway = Inf, path = Inf, residential = 3, secondary = 1, service = 3, track = 10, unclassified = 10 ) net = net |> activate(edges) |> mutate(multiplier = ifelse(is.na(type), 1, weighting_profile[type])) |> mutate(weight = drop_units(edge_length() * multiplier)) shortest = st_network_paths(net, 452, 212) optimal = st_network_paths(net, 452, 212, weights = weight) ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = shortest, color = \"orange\", linewidth = 2) + geom_sf(data = node_data(net)[452, ], size = 6) + geom_sf(data = node_data(net)[212, ], pch = 15, size = 6) + theme_void() ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = optimal, color = \"orange\", linewidth = 2) + geom_sf(data = node_data(net)[452, ], size = 6) + geom_sf(data = node_data(net)[212, ], pch = 15, size = 6) + theme_void() # Cost matrix reporting the custom weights. st_network_cost( net, seq(1, 901, by = 150), seq(1, 901, by = 150), weights = weight, router = \"dodgr\" ) |> round() #> 1 151 301 451 601 751 901 #> 1 0 2953 374 1599 1445 863 5485 #> 151 2953 0 2579 3721 2371 3816 7772 #> 301 374 2579 0 1244 1071 1237 5567 #> 451 1599 3721 1244 0 2213 1349 5971 #> 601 1445 2371 1071 2213 0 2308 6437 #> 751 863 3816 1237 1349 2308 0 4811 #> 901 5485 8385 5806 5559 6876 4811 0 # Cost matrix using custom weights but reporting real distances. st_network_cost( net, seq(1, 901, by = 150), seq(1, 901, by = 150), weights = dual_weights(edge_length(), weight), router = \"dodgr\" ) |> round() #> 1 151 301 451 601 751 901 #> 1 0 994 249 886 768 305 1127 #> 151 994 0 758 1588 588 1264 1622 #> 301 249 758 0 914 530 519 1350 #> 451 886 1588 914 0 1360 696 1334 #> 601 768 588 530 1360 0 1036 1510 #> 751 305 1264 519 696 1036 0 894 #> 901 1127 1622 1350 1334 1510 894 0"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"k-shortest-paths","dir":"Articles","previous_headings":"","what":"K shortest paths","title":"Routing on spatial networks","text":"Thanks igraph routing backend, can compute shortest path two nodes, also next k−1k-1 shortest paths. , set k argument st_network_paths() integer higher 1. supported one--one routing, .e. single origin single destination.","code":"paths = st_network_paths(net, 1, 17, k = 3) paths #> Simple feature collection with 3 features and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4548984 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 3 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 1 17 TRUE 1436. (4549504 2747309, 4549387 27… #> 2 1 17 TRUE 1580. (4549504 2747309, 4549589 27… #> 3 1 17 TRUE 1602. (4549504 2747309, 4549589 27… paths = paths |> mutate(k = c(1:n())) |> arrange(desc(k)) ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_sf(data = paths, aes(color = as.factor(k)), linewidth = 2) + geom_node_sf(color = \"darkgrey\", size = 4) + geom_sf(data = node_data(net)[1, ], size = 6) + geom_sf(data = node_data(net)[17, ], pch = 15, size = 6) + scale_color_discrete(\"k\") + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"closest-facility-analysis","dir":"Articles","previous_headings":"","what":"Closest facility analysis","title":"Routing on spatial networks","text":"purpose closest facility analysis , given set destination locations (also referred facilities) origin locations (also referred sites), find closest nn facilities site. example, might want find nearest transit hub address city, nearest hospital high-risk road intersections. solve problem, can calculate cost matrix sites origins, facilities destinations points. , row (.e. site) find column(s) lowest cost value. Note facility site represented nearest node network. First blending network using st_network_blend() gives accurate results.","code":"# Create a network. net = as_sfnetwork(roxel, directed = FALSE) |> st_transform(3035) # Create some facility locations spread over the area. facilities = st_sfc( st_point(c(4151100, 3207700)), st_point(c(4151040, 3206660)), st_point(c(4151800, 3207200)), st_point(c(4152000, 3207600)), crs = 3035 ) # Select a random set of sites. sites = st_sample(st_convex_hull(st_combine(net)), 50) # Blend the sites and facilities into the network to get better results. # Also select only the largest connected component. # Such that we avoid points being blended to a small disconnected component. net = net |> convert(to_largest_component, .clean = TRUE) |> st_network_blend(c(sites, facilities)) # Calculate the cost matrix. mat = net |> st_network_cost(from = sites, to = facilities) # Find for each site which facility is closest. closest = facilities[apply(mat, 1, function(x) which(x == min(x))[1])] # Create a line between each site and its closest facility, for visualization. draw_lines = function(sources, targets) { f = function(a, b) st_sfc(st_cast(c(a, b), \"LINESTRING\")) lines = do.call(\"c\", mapply(f, sources, targets, SIMPLIFY = FALSE)) st_crs(lines) = st_crs(sources) lines } connections = draw_lines(sites, closest) ggraph(net, \"sf\") + geom_edge_sf(color = \"grey\") + geom_node_sf(color = \"grey\") + geom_sf(data = connections, color = \"orange\") + geom_sf(data = sites, color = \"orange\", size = 4) + geom_sf(data = facilities, color = \"skyblue\", size = 6) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"traveling-salesman-problem","dir":"Articles","previous_headings":"","what":"Traveling salesman problem","title":"Routing on spatial networks","text":"traveling salesman problem aims find shortest tour visits every location set exactly . solve , sfnetworks provides interface TSP::TSP() function. requires TSP package installed. st_network_travel() function returns sf object similar output st_network_paths(). row represent one leg route, one location next. Note location visit represented nearest node network. First blending network using st_network_blend() gives accurate results.","code":"# We will use the facilities from the previous section as visiting locations. # They are already blended into the largest component of the network. route = st_network_travel(net, facilities) route #> Simple feature collection with 4 features and 6 fields #> Geometry type: MULTILINESTRING #> Dimension: XY #> Bounding box: xmin: 4150908 ymin: 3206643 xmax: 4152015 ymax: 3207744 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 4 × 7 #> from to node_path edge_path path_found cost geometry #> * [m] #> 1 869 1003 TRUE 602. ((4151793 3207244, 4151805… #> 2 1003 633 TRUE 1074. ((4151039 3206662, 4151063… #> 3 633 1001 TRUE 1385. ((4151138 3207734, 4151160… #> 4 1001 869 TRUE 1178. ((4151073 3207744, 4151097… ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = route, color = \"orange\", linewidth = 2) + geom_sf(data = facilities, size = 6) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"isodistance-polygons","dir":"Articles","previous_headings":"","what":"Isodistance polygons","title":"Routing on spatial networks","text":"respect given point pp given distance dd, isodistance line holds distance point line pp equal dd. spatial network analysis, common find nodes fall within isodistance line computed given source node pp. enclosing nodes concave hull, obtain isodistance polygon. workflow implemented function st_network_iso(). first compute distance matrix given source node pp (can specified explained ) nodes network using st_network_cost(), filter nodes within given distance dd. Using sf::st_concave_hull(), compute concave hull around nodes obtain isodistance polygon. Multiple distance thresholds can given, resulting multiple isodistance polygons drawn. output function sf object one row per requested polygon. setting ratio argument (value 0 1, 1 convex hull), can increase decrease level detail polygons. default, holes allowed polygons, can changed setting allow_holes = TRUE. note changing ratio requires GEOS version least 3.11. GEOS C/C++ library computational geometry used sf. different approach can taken morpher to_spatial_neighborhood(). Instead drawing polygons, function subset network contain nodes inside isodistance line, edges connect . st_network_iso() to_spatial_neighborhood() allow specify edge weights geographic distance. can done weights argument, explained . using time edge weight, talk isochrones instead isodistances.","code":"# Define the source. # This point will be snapped to its nearest node. pt = st_centroid(st_transform(st_as_sfc(st_bbox(roxel)), 3035)) # Compute isodistance polygons for four different thresholds. polys = st_network_iso(net, pt, rev(c(100, 250, 500, 1000))) polys #> Simple feature collection with 4 features and 1 field #> Geometry type: POLYGON #> Dimension: XY #> Bounding box: xmin: 4150754 ymin: 3206653 xmax: 4152274 ymax: 3208212 #> Projected CRS: ETRS89-extended / LAEA Europe #> cost geometry #> 1 1000 [m] POLYGON ((4151598 3206653, ... #> 2 500 [m] POLYGON ((4151611 3207041, ... #> 3 250 [m] POLYGON ((4151519 3207212, ... #> 4 100 [m] POLYGON ((4151540 3207378, ... ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = polys, aes(fill = drop_units(cost)), alpha = 0.5) + scale_fill_continuous(\"distance [m]\") + theme_void() sub_net = convert(net, to_spatial_neighborhood, pt, 500) plot(net, col = \"darkgrey\") plot(sub_net, col = \"orange\", lwd = 2, cex = 1, add = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"custom-routing","dir":"Articles","previous_headings":"","what":"Custom routing","title":"Routing on spatial networks","text":"many cases shortest path based geographical distances travel time necessarily optimal path. appropriate route may depend many factors, example staying away large potentially unpleasant roads motor traffic. networks different characteristics. OpenStreetMap networks highway attribute often good (albeit crude) approximation road type. roxel demo dataset derived OpenStreetMap stores highway attribute type column. can see Roxel largely residential road network: Building shortest paths calculated previous section can try alternative routing profile. purposes illustration, lets imagine ’re routing vehicle want keep away residential roads. can now compare shortest path optimal path according weighting profile. Shortest route Optimal route Note developing sophisticated routing profiles beyond scope package. need complex mode-specific routing profiles, recommend looking routing profiles associated open source routing engines OSRM, dodgr R package. Another direction travel extend approach illustrated , work well-suited separate package builds sfnetworks, possibly integrating routing profiles dodgr. ’d like work project improve mode-specific routing R building package, please let us know discussion room!","code":"roxel |> count(type) #> Simple feature collection with 9 features and 2 fields #> Geometry type: MULTILINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 9 × 3 #> type n geometry #> * #> 1 cycleway 5 ((7.540663 51.95534, 7.540831 51.95536), (7.534414 51.9547… #> 2 footway 134 ((7.543404 51.94779, 7.54358 51.94786, 7.543685 51.9479), … #> 3 path 113 ((7.54059 51.95077, 7.54127 51.95012), (7.53819 51.95738, … #> 4 residential 325 ((7.537815 51.95867, 7.537015 51.95848, 7.537374 51.95787,… #> 5 secondary 54 ((7.532301 51.95559, 7.532214 51.95575, 7.532142 51.95589,… #> 6 service 256 ((7.525727 51.94672, 7.52585 51.94668, 7.526145 51.94655, … #> 7 track 15 ((7.541088 51.95588, 7.541908 51.95604), (7.535803 51.9433… #> 8 unclassified 57 ((7.534157 51.94654, 7.534845 51.94597, 7.534993 51.94583,… #> 9 NA 256 ((7.526311 51.94653, 7.526298 51.94649, 7.526311 51.94644,… ggraph(net, \"sf\") + geom_edge_sf(aes(color = as.factor(type)), linewidth = 2) + geom_node_sf() + scale_edge_color_discrete(\"type\") + theme_void() weighting_profile = c( cycleway = Inf, footway = Inf, path = Inf, residential = 3, secondary = 1, service = 3, track = 10, unclassified = 10 ) net = net |> activate(edges) |> mutate(multiplier = ifelse(is.na(type), 1, weighting_profile[type])) |> mutate(weight = drop_units(edge_length() * multiplier)) shortest = st_network_paths(net, 452, 212) optimal = st_network_paths(net, 452, 212, weights = weight) ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = shortest, color = \"orange\", linewidth = 2) + geom_sf(data = node_data(net)[452, ], size = 6) + geom_sf(data = node_data(net)[212, ], pch = 15, size = 6) + theme_void() ggraph(net, \"sf\") + geom_edge_sf(color = \"darkgrey\") + geom_node_sf(color = \"darkgrey\") + geom_sf(data = optimal, color = \"orange\", linewidth = 2) + geom_sf(data = node_data(net)[452, ], size = 6) + geom_sf(data = node_data(net)[212, ], pch = 15, size = 6) + theme_void()"},{"path":"https://luukvdmeer.github.io/sfnetworks/articles/sfn05_routing.html","id":"dual-weighted-routing","dir":"Articles","previous_headings":"","what":"Dual-weighted routing","title":"Routing on spatial networks","text":"many cases may interested obtaining cost matrix stores geographic distances optimal routes according custom set edge weights. , want use custom weights define “shortest” path , report actual geographic distance path. called dual-weighted routing. dodgr routing backend supports . sfnetworks offers dual_weights() function allow specify dual weights weights argument routing functions. accepts two sets weights, can specified ways explained section. first set weights reported weights, second set weights actual weights used define optimal path.","code":"# Cost matrix reporting the custom weights. st_network_cost( net, seq(1, 901, by = 150), seq(1, 901, by = 150), weights = weight, router = \"dodgr\" ) |> round() #> 1 151 301 451 601 751 901 #> 1 0 2953 374 1599 1445 863 5485 #> 151 2953 0 2579 3721 2371 3816 7772 #> 301 374 2579 0 1244 1071 1237 5567 #> 451 1599 3721 1244 0 2213 1349 5971 #> 601 1445 2371 1071 2213 0 2308 6437 #> 751 863 3816 1237 1349 2308 0 4811 #> 901 5485 8385 5806 5559 6876 4811 0 # Cost matrix using custom weights but reporting real distances. st_network_cost( net, seq(1, 901, by = 150), seq(1, 901, by = 150), weights = dual_weights(edge_length(), weight), router = \"dodgr\" ) |> round() #> 1 151 301 451 601 751 901 #> 1 0 994 249 886 768 305 1127 #> 151 994 0 758 1588 588 1264 1622 #> 301 249 758 0 914 530 519 1350 #> 451 886 1588 914 0 1360 696 1334 #> 601 768 588 530 1360 0 1036 1510 #> 751 305 1264 519 696 1036 0 894 #> 901 1127 1622 1350 1334 1510 894 0"},{"path":"https://luukvdmeer.github.io/sfnetworks/authors.html","id":null,"dir":"","previous_headings":"","what":"Authors","title":"Authors and Citation","text":"Lucas van der Meer. Author, maintainer. Lorena Abad. Author. Andrea Gilardi. Author. Robin Lovelace. Author.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/authors.html","id":"citation","dir":"","previous_headings":"","what":"Citation","title":"Authors and Citation","text":"van der Meer L, Abad L, Gilardi , Lovelace R (2024). sfnetworks: Tidy Geospatial Networks. R package version 1.0.0, https://github.com/luukvdmeer/sfnetworks, https://luukvdmeer.github.io/sfnetworks/.","code":"@Manual{, title = {sfnetworks: Tidy Geospatial Networks}, author = {Lucas {van der Meer} and Lorena Abad and Andrea Gilardi and Robin Lovelace}, year = {2024}, note = {R package version 1.0.0, https://github.com/luukvdmeer/sfnetworks}, url = {https://luukvdmeer.github.io/sfnetworks/}, }"},{"path":"https://luukvdmeer.github.io/sfnetworks/index.html","id":"tidy-geospatial-networks-in-r-","dir":"","previous_headings":"","what":"Tidy Geospatial Networks","title":"Tidy Geospatial Networks","text":"{sfnetworks} R package analysis geospatial networks. connects extends functionalities {tidygraph} package network analysis {sf} package spatial data science.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/index.html","id":"background","dir":"","previous_headings":"","what":"Background","title":"Tidy Geospatial Networks","text":"Geospatial networks graphs embedded geographical space. means nodes edges graph can represented geographic features: nodes commonly points, edges linestrings. play important role many different domains, ranging transportation planning logistics ecology epidemiology. structure characteristics geospatial networks go beyond standard graph topology, therefore crucial explicitly take space account analyzing . created {sfnetworks} facilitate integrated workflow. combines forces two popular R packages: {sf} spatial data science {tidygraph} standard graph analysis. core package dedicated data structure geospatial networks, can provided input graph analytical functions {tidygraph} well spatial analytical functions {sf}, without need conversion. Additionally, implemented set geospatial network specific functions, routines shortest path calculation, network cleaning topology modification. {sfnetworks} designed general-purpose package suitable usage across different application domains, can seamlessly integrated tidyverse workflows.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/index.html","id":"installation","dir":"","previous_headings":"","what":"Installation","title":"Tidy Geospatial Networks","text":"can install latest stable version {sfnetworks} CRAN : can install development version GitHub : Note: Two important dependencies {sfnetworks}, {sf} package spatial data science {igraph} package network analysis (main “analysis backend” {tidygraph}), require low-level software libraries installed system. Depending operating system use, can mean install system requirements first, can install {sfnetworks}. See installation guides sf igraph details.","code":"install.packages(\"sfnetworks\") remotes::install_github(\"luukvdmeer/sfnetworks\")"},{"path":"https://luukvdmeer.github.io/sfnetworks/index.html","id":"usage","dir":"","previous_headings":"","what":"Usage","title":"Tidy Geospatial Networks","text":"get started {sfnetworks}, read Introduction sfnetworks. Four additional package vignettes guide detail functionalities package: Creating representing spatial networks Cleaning spatial networks Spatial joins filters Routing spatial networks","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/index.html","id":"contribution","dir":"","previous_headings":"","what":"Contribution","title":"Tidy Geospatial Networks","text":"look much forward contributions package. See contributing guide details. project released Contributor Code Conduct. participating project agree abide terms.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/index.html","id":"acknowledgment","dir":"","previous_headings":"","what":"Acknowledgment","title":"Tidy Geospatial Networks","text":"project gratefully acknowledges financial support ","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as.linnet.html","id":null,"dir":"Reference","previous_headings":"","what":"Convert a sfnetwork into a linnet — as.linnet","title":"Convert a sfnetwork into a linnet — as.linnet","text":"method convert object class sfnetwork linnet format enhance interoperability sfnetworks spatstat. Use method without .sfnetwork suffix loading spatstat package.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as.linnet.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Convert a sfnetwork into a linnet — as.linnet","text":"","code":"as.linnet.sfnetwork(X, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as.linnet.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Convert a sfnetwork into a linnet — as.linnet","text":"X object class sfnetwork projected CRS. ... Arguments passed linnet.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as.linnet.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Convert a sfnetwork into a linnet — as.linnet","text":"object class linnet.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_s2_geography.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract the geometries of a sfnetwork as a S2 geography vector — as_s2_geography","title":"Extract the geometries of a sfnetwork as a S2 geography vector — as_s2_geography","text":"method convert object class sfnetwork s2_geography format. Use method without .sfnetwork suffix loading s2 package.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_s2_geography.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract the geometries of a sfnetwork as a S2 geography vector — as_s2_geography","text":"","code":"as_s2_geography.sfnetwork(x, focused = TRUE, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_s2_geography.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract the geometries of a sfnetwork as a S2 geography vector — as_s2_geography","text":"x object class sfnetwork. focused features focus extracted? Defaults TRUE. See focus information focused networks. ... Arguments passed corresponding s2 function.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_s2_geography.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract the geometries of a sfnetwork as a S2 geography vector — as_s2_geography","text":"object class s2_geography.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_sfnetwork.html","id":null,"dir":"Reference","previous_headings":"","what":"Convert a foreign object to a sfnetwork — as_sfnetwork","title":"Convert a foreign object to a sfnetwork — as_sfnetwork","text":"Convert given object object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_sfnetwork.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Convert a foreign object to a sfnetwork — as_sfnetwork","text":"","code":"as_sfnetwork(x, ...) # Default S3 method as_sfnetwork(x, ...) # S3 method for class 'sf' as_sfnetwork(x, ...) # S3 method for class 'sfc' as_sfnetwork(x, ...) # S3 method for class 'dodgr_streetnet' as_sfnetwork(x, ...) # S3 method for class 'linnet' as_sfnetwork(x, ...) # S3 method for class 'psp' as_sfnetwork(x, ...) # S3 method for class 'sfNetwork' as_sfnetwork(x, ...) # S3 method for class 'tbl_graph' as_sfnetwork(x, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_sfnetwork.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Convert a foreign object to a sfnetwork — as_sfnetwork","text":"x Object converted sfnetwork. ... Additional arguments passed functions.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_sfnetwork.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Convert a foreign object to a sfnetwork — as_sfnetwork","text":"object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_sfnetwork.html","id":"methods-by-class-","dir":"Reference","previous_headings":"","what":"Methods (by class)","title":"Convert a foreign object to a sfnetwork — as_sfnetwork","text":"as_sfnetwork(default): default, provided object first converted tbl_graph using as_tbl_graph. conversion sfnetwork work long nodes can converted sf object st_as_sf. Arguments st_as_sf can provided additional arguments forwarded st_as_sf sfnetwork construction function. as_sfnetwork(sf): Convert spatial features class sf directly sfnetwork. Supported geometry types either LINESTRING POINT. first case, lines become edges network, nodes placed boundaries. Additional arguments forwarded create_from_spatial_lines. latter case, points become nodes network, connected edges according specified method. Additional arguments forwarded create_from_spatial_points. as_sfnetwork(sfc): Convert spatial geometries class sfc directly sfnetwork. Supported geometry types either LINESTRING POINT. first case, lines become edges network, nodes placed boundaries. Additional arguments forwarded create_from_spatial_lines. latter case, points become nodes network, connected edges according specified method. Additional arguments forwarded create_from_spatial_points. as_sfnetwork(dodgr_streetnet): Convert directed graph class dodgr_streetnet directly sfnetwork. Additional arguments forwarded dodgr_to_sfnetwork. requires dodgr package installed. as_sfnetwork(linnet): Convert spatial linear networks class linnet directly sfnetwork. Additional arguments forwarded create_from_spatial_lines. requires spatstat.geom package installed. as_sfnetwork(psp): Convert spatial line segments class psp directly sfnetwork. lines become edges network, nodes placed boundary points. Additional arguments forwarded create_from_spatial_lines. as_sfnetwork(sfNetwork): Convert spatial networks class sfNetwork stplanr package directly sfnetwork. extract edges sf object re-create network structure. Additional arguments forwarded create_from_spatial_lines.directness original network preserved unless specified otherwise directed argument. as_sfnetwork(tbl_graph): Convert graph objects class tbl_graph directly sfnetwork. work least nodes can converted sf object st_as_sf. Arguments st_as_sf can provided additional arguments forwarded st_as_sf sfnetwork construction function. directness original graph preserved unless specified otherwise directed argument.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_sfnetwork.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Convert a foreign object to a sfnetwork — as_sfnetwork","text":"","code":"# From an sf object with LINESTRING geometries. library(sf, quietly = TRUE) #> Linking to GEOS 3.10.2, GDAL 3.4.1, PROJ 8.2.1; sf_use_s2() is TRUE oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) as_sfnetwork(roxel) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows plot(st_geometry(roxel)) plot(as_sfnetwork(roxel)) # From an sf object with POINT geometries. # For more examples see ?create_from_spatial_points. as_sfnetwork(mozart) #> # A sfnetwork: 17 nodes and 272 edges #> # #> # A bipartite simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 4 (active) #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> 4 Mozart Denkmal artwork NA (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) #> 6 Mozartsteg bridge NA (4549473 2747624) #> # ℹ 11 more rows #> # #> # Edge data: 272 × 3 #> from to geometry #> #> 1 1 2 (4549504 2747309, 4549003 2747376) #> 2 1 3 (4549504 2747309, 4549589 2747507) #> 3 1 4 (4549504 2747309, 4549387 2747514) #> # ℹ 269 more rows plot(st_geometry(mozart)) plot(as_sfnetwork(mozart)) par(oldpar) # From a dodgr_streetnet object. if (require(dodgr, quietly = TRUE) & require(geodist, quietly = TRUE)) { as_sfnetwork(dodgr::weight_streetnet(hampi)) } #> # A sfnetwork: 3337 nodes and 6813 edges #> # #> # A directed simple graph with 3 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 76.37261 ymin: 15.30104 xmax: 76.49232 ymax: 15.36033 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3,337 × 4 (active) #> name component n geometry #> #> 1 339318500 1 0 (76.47491 15.34167) #> 2 339318502 1 1 (76.47612 15.34173) #> 3 2398958028 1 2 (76.47621 15.34174) #> 4 1427116077 1 3 (76.47628 15.34179) #> 5 7799710916 1 4 (76.47634 15.34184) #> 6 339318503 1 5 (76.47641 15.3419) #> # ℹ 3,331 more rows #> # #> # Edge data: 6,813 × 12 #> from to weight d_weighted time time_weighted xfr yfr xto yto #> #> 1 1 2 130. 144. 39.0 43.3 76.5 15.3 76.5 15.3 #> 2 2 1 130. 144. 39.0 43.3 76.5 15.3 76.5 15.3 #> 3 2 3 8.89 9.88 2.67 2.96 76.5 15.3 76.5 15.3 #> # ℹ 6,810 more rows #> # ℹ 2 more variables: component , geometry # From a linnet object. if (require(spatstat.geom, quietly = TRUE)) { as_sfnetwork(simplenet) } #> spatstat.univar 3.1-1 #> spatstat.geom 3.3-3 #> # A sfnetwork: 10 nodes and 10 edges #> # #> # A directed acyclic simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0.1497036 ymin: 0.1608339 xmax: 0.8418658 ymax: 0.9415173 #> # CRS: NA #> # #> # Node data: 10 × 1 (active) #> geom #> #> 1 (0.181276 0.8345078) #> 2 (0.3254689 0.4607012) #> 3 (0.1497036 0.2119066) #> 4 (0.5358572 0.8028913) #> 5 (0.4411403 0.1608339) #> 6 (0.3795058 0.3206155) #> # ℹ 4 more rows #> # #> # Edge data: 10 × 4 #> from to label geom #> #> 1 1 2 segment (0.181276 0.8345078, 0.3254689 0.4607012) #> 2 3 2 segment (0.1497036 0.2119066, 0.3254689 0.4607012) #> 3 2 4 segment (0.3254689 0.4607012, 0.5358572 0.8028913) #> # ℹ 7 more rows # From a psp object. if (require(spatstat.geom, quietly = TRUE)) { set.seed(42) test_psp = psp(runif(10), runif(10), runif(10), runif(10), window=owin()) as_sfnetwork(test_psp) } #> # A sfnetwork: 20 nodes and 10 edges #> # #> # A rooted forest with 10 trees and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0.08243756 ymin: 0.003948339 xmax: 0.9888917 ymax: 0.9782264 #> # CRS: NA #> # #> # Node data: 20 × 1 (active) #> geom #> #> 1 (0.914806 0.4577418) #> 2 (0.9040314 0.7375956) #> 3 (0.9370754 0.7191123) #> 4 (0.1387102 0.8110551) #> 5 (0.2861395 0.9346722) #> 6 (0.9888917 0.3881083) #> # ℹ 14 more rows #> # #> # Edge data: 10 × 4 #> from to label geom #> #> 1 1 2 segment (0.914806 0.4577418, 0.9040314 0.7375956) #> 2 3 4 segment (0.9370754 0.7191123, 0.1387102 0.8110551) #> 3 5 6 segment (0.2861395 0.9346722, 0.9888917 0.3881083) #> # ℹ 7 more rows # From a tbl_graph with coordinate columns. library(tidygraph, quietly = TRUE) #> #> Attaching package: ‘tidygraph’ #> The following object is masked from ‘package:stats’: #> #> filter nodes = data.frame(lat = c(7, 7, 8), lon = c(51, 52, 52)) edges = data.frame(from = c(1, 1, 3), to = c(2, 3, 2)) tbl_net = tbl_graph(nodes, edges) as_sfnetwork(tbl_net, coords = c(\"lon\", \"lat\"), crs = 4326) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> ✔ Spatial network structure is valid #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed acyclic simple graph with 1 component and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 51 ymin: 7 xmax: 52 ymax: 8 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 1 (active) #> geometry #> #> 1 (51 7) #> 2 (52 7) #> 3 (52 8) #> # #> # Edge data: 3 × 2 #> from to #> #> 1 1 2 #> 2 1 3 #> 3 3 2"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_tibble.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract the active element of a sfnetwork as spatial tibble — as_tibble","title":"Extract the active element of a sfnetwork as spatial tibble — as_tibble","text":"sfnetwork method as_tibble conceptually different. Whenever geometry list column present, default return call 'spatial tibble'. mean object class c('sf', 'tbl_df') instead object class 'tbl_df'. little conceptual trick essential tidyverse functions handle sfnetwork objects, .e. always using corresponding sf method present. using as_tibble sfnetwork objects directly user, can disable behaviour setting spatial = FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_tibble.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract the active element of a sfnetwork as spatial tibble — as_tibble","text":"","code":"# S3 method for class 'sfnetwork' as_tibble(x, active = NULL, focused = TRUE, spatial = TRUE, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_tibble.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract the active element of a sfnetwork as spatial tibble — as_tibble","text":"x object class sfnetwork. active network element (.e. nodes edges) activate extracting. NULL, set current active element given network. Defaults NULL. focused features focus extracted? Defaults TRUE. See focus information focused networks. spatial extracted tibble 'spatial tibble', .e. object class c('sf', 'tbl_df'), contains geometry list column. Defaults TRUE. ... Arguments passed as_tibble.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_tibble.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract the active element of a sfnetwork as spatial tibble — as_tibble","text":"active element network object class sf geometry list column present spatial = TRUE, object class tibble otherwise.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/as_tibble.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Extract the active element of a sfnetwork as spatial tibble — as_tibble","text":"","code":"library(tibble, quietly = TRUE) net = as_sfnetwork(roxel) # Extract the active network element as a spatial tibble. as_tibble(net) #> Simple feature collection with 987 features and 0 fields #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> 7 (7.525977 51.95283) #> 8 (7.526581 51.95293) #> 9 (7.532301 51.95559) #> 10 (7.532142 51.95589) #> # ℹ 977 more rows # Extract any network element as a spatial tibble. as_tibble(net, \"edges\") #> Simple feature collection with 1215 features and 4 fields #> Attribute-geometry relationships: constant (2), NA's (2) #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… #> 5 9 10 Annette-von-Droste-Hülshoff-Stra… seco… (7.532301 51.95559, 7.53… #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… #> 7 13 14 Deermannskamp resi… (7.537675 51.95689, 7.53… #> 8 15 16 Lindenstraße resi… (7.539105 51.9504, 7.540… #> 9 17 18 NA NA (7.534875 51.95795, 7.53… #> 10 19 20 Annette-von-Droste-Hülshoff-Stra… seco… (7.532465 51.95424, 7.53… #> # ℹ 1,205 more rows # Extract the active network element as a regular tibble. as_tibble(net, spatial = FALSE) #> # A tibble: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> 7 (7.525977 51.95283) #> 8 (7.526581 51.95293) #> 9 (7.532301 51.95559) #> 10 (7.532142 51.95589) #> # ℹ 977 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/autoplot.html","id":null,"dir":"Reference","previous_headings":"","what":"Plot sfnetwork geometries with ggplot2 — autoplot","title":"Plot sfnetwork geometries with ggplot2 — autoplot","text":"Plot geometries object class sfnetwork automatically ggplot object. Use method without .sfnetwork suffix loading ggplot2 package.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/autoplot.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Plot sfnetwork geometries with ggplot2 — autoplot","text":"","code":"autoplot.sfnetwork(object, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/autoplot.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Plot sfnetwork geometries with ggplot2 — autoplot","text":"object object class sfnetwork. ... Ignored.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/autoplot.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Plot sfnetwork geometries with ggplot2 — autoplot","text":"object class ggplot.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/autoplot.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Plot sfnetwork geometries with ggplot2 — autoplot","text":"See autoplot.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/bind_spatial.html","id":null,"dir":"Reference","previous_headings":"","what":"Add nodes or edges to a spatial network. — bind_spatial","title":"Add nodes or edges to a spatial network. — bind_spatial","text":"functions spatially aware versions tidygraph's bind_nodes bind_edges allow add rows nodes edges tables sfnetwork object. bind_rows columns matched name filled NA column exist instances.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/bind_spatial.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Add nodes or edges to a spatial network. — bind_spatial","text":"","code":"bind_spatial_nodes(.data, ...) bind_spatial_edges(.data, ..., node_key = \"name\", force = FALSE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/bind_spatial.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Add nodes or edges to a spatial network. — bind_spatial","text":".data object class sfnetwork. ... One objects class sf containing nodes edges added. node_key name column nodes table character represented columns matched . NA, first column always chosen. setting effect given integers. Defaults 'name'. force network validity checks skipped? Defaults FALSE, meaning network validity checks executed binding edges, making sure boundary points edges match corresponding node coordinates.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/bind_spatial.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Add nodes or edges to a spatial network. — bind_spatial","text":"object class sfnetwork added nodes edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/bind_spatial.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Add nodes or edges to a spatial network. — bind_spatial","text":"","code":"library(sf, quietly = TRUE) library(dplyr, quietly = TRUE) #> #> Attaching package: ‘dplyr’ #> The following objects are masked from ‘package:stats’: #> #> filter, lag #> The following objects are masked from ‘package:base’: #> #> intersect, setdiff, setequal, union net = roxel |> slice(c(1:2)) |> st_transform(3035) |> as_sfnetwork() pts = roxel |> slice(c(3:4)) |> st_transform(3035) |> st_centroid() #> Warning: st_centroid assumes attributes are constant over geometries bind_spatial_nodes(net, pts) #> # A sfnetwork: 6 nodes and 2 edges #> # #> # A rooted forest with 4 trees and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150969 ymin: 3207609 xmax: 4151784 ymax: 3208259 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 6 × 3 (active) #> name type geometry #> #> 1 NA NA (4151782 3207612) #> 2 NA NA (4151765 3207609) #> 3 NA NA (4151784 3208259) #> 4 NA NA (4151728 3208240) #> 5 Havixbecker Straße residential (4151473 3207938) #> 6 Holzschuhmacherweg residential (4150969 3207642) #> # #> # Edge data: 2 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (4151782 3207612, 4151765 3207609) #> 2 3 4 Stiegkamp residential (4151784 3208259, 4151728 3208240)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/contract_nodes.html","id":null,"dir":"Reference","previous_headings":"","what":"Contract groups of nodes in a spatial network — contract_nodes","title":"Contract groups of nodes in a spatial network — contract_nodes","text":"Combine groups nodes single node per group. centroid group used default new geometry contracted node. edges spatially explicit, edge geometries updated accordingly valid spatial network structure preserved.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/contract_nodes.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Contract groups of nodes in a spatial network — contract_nodes","text":"","code":"contract_nodes( x, groups, simplify = TRUE, compute_centroids = TRUE, reconnect_edges = TRUE, attribute_summary = \"ignore\", store_original_ids = FALSE, store_original_data = FALSE )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/contract_nodes.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Contract groups of nodes in a spatial network — contract_nodes","text":"x object class sfnetwork. groups group index node x. simplify network simplified contraction? Defaults TRUE. means multiple edges loop edges removed. Multiple edges introduced contraction several connections groups nodes. Loop edges introduced contraction connections within group. Note however setting TRUE also removes multiple edges loop edges already existed contraction. compute_centroids new geometry contracted group nodes centroid group members? Defaults TRUE. set FALSE, geometry first node group used instead, requires considerably less computing time. reconnect_edges geometries edges updated match new node geometries? Defaults TRUE. set FALSE know node geometries change, otherwise valid spatial network structure broken. attribute_summary attributes contracted nodes summarized? several options, see igraph-attribute-combination details. store_original_ids group contracted nodes, indices original nodes stored attribute new edge, column named .tidygraph_node_index? line design principles tidygraph. Defaults FALSE. store_original_data group contracted nodes, data original nodes stored attribute new edge, column named .orig_data? line design principles tidygraph. Defaults FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/contract_nodes.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Contract groups of nodes in a spatial network — contract_nodes","text":"contracted network object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_lines.html","id":null,"dir":"Reference","previous_headings":"","what":"Create a spatial network from linestring geometries — create_from_spatial_lines","title":"Create a spatial network from linestring geometries — create_from_spatial_lines","text":"Create spatial network linestring geometries","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_lines.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Create a spatial network from linestring geometries — create_from_spatial_lines","text":"","code":"create_from_spatial_lines( x, directed = TRUE, compute_length = FALSE, subdivide = FALSE )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_lines.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Create a spatial network from linestring geometries — create_from_spatial_lines","text":"x object class sf sfc LINESTRING geometries. directed constructed network directed? Defaults TRUE. compute_length geographic length edges stored column named length? Uses st_length compute length edge geometries. already column named length, overwritten. Please note values column automatically recognized edge weights. needs specified explicitly calling function uses edge weights. Defaults FALSE. subdivide given linestring geometries subdivided locations interior point equal interior boundary point another feature? connect features locations. Defaults FALSE, meaning features connected boundaries.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_lines.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Create a spatial network from linestring geometries — create_from_spatial_lines","text":"object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_lines.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Create a spatial network from linestring geometries — create_from_spatial_lines","text":"assumed given linestring geometries form edges network. Nodes created line boundaries. Shared boundaries multiple linestrings become node.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_lines.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Create a spatial network from linestring geometries — create_from_spatial_lines","text":"default sfnetworks rounds coordinates 12 decimal places determine spatial equality. can influence behavior explicitly setting precision linestrings using st_set_precision.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_lines.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Create a spatial network from linestring geometries — create_from_spatial_lines","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) net = as_sfnetwork(roxel) net #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 1 (active) #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows plot(st_geometry(roxel)) plot(net) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_points.html","id":null,"dir":"Reference","previous_headings":"","what":"Create a spatial network from point geometries — create_from_spatial_points","title":"Create a spatial network from point geometries — create_from_spatial_points","text":"Create spatial network point geometries","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_points.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Create a spatial network from point geometries — create_from_spatial_points","text":"","code":"create_from_spatial_points( x, connections = \"complete\", directed = TRUE, edges_as_lines = TRUE, compute_length = FALSE, k = 1 )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_points.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Create a spatial network from point geometries — create_from_spatial_points","text":"x object class sf sfc POINT geometries. connections connect given point geometries ? Can specified either adjacency matrix, character describing specific method define connections. See Details. directed constructed network directed? Defaults TRUE. edges_as_lines created edges spatially explicit, .e. LINESTRING geometries stored geometry list column? Defaults TRUE. compute_length geographic length edges stored column named length? Uses st_length compute length edge geometries edges spatially explicit, st_distance compute distance boundary nodes edges spatially implicit. Please note values column automatically recognized edge weights. needs specified explicitly calling function uses edge weights. Defaults FALSE. k amount neighbors connect connections = 'knn'. Defaults 1, meaning nodes connected nearest neighbor. Ignored value connected argument.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_points.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Create a spatial network from point geometries — create_from_spatial_points","text":"object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_points.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Create a spatial network from point geometries — create_from_spatial_points","text":"assumed given points form nodes network. nodes connected edges depends connections argument. connections can specified adjacency matrix , n x n matrix n number nodes, element Aij holding TRUE value edge node node j, FALSE value otherwise. case undirected networks, matrix tested symmetry, edge exist node node j either element Aij element Aji TRUE. Non-logical matrices first converted logical matrices using .logical, whenever possible. provided adjacency matrix may also sparse. can object one sparse matrix classes Matrix package, list-formatted sparse matrix. list one element per node, holding integer indices nodes adjacent . example sgbp objects. values integers, first converted integers using .integer, whenever possible. Alternatively, connections can specified providing name specific method create adjacency matrix internally. Valid options : complete: nodes directly connected . sequence: nodes sequentially connected , meaning first node connected second node, second node connected third node, et cetera. mst: nodes connected spatial minimum spanning tree, .e. set edges minimum total edge length required connect nodes. tree always constructed undirected network, regardless value directed. argument. directed = TRUE, edge duplicated reversed ensure full connectivity network. Can also specified minimum_spanning_tree. delaunay: nodes connected Delaunay triangulation. Requires spdep package installed, assumes planar coordinates. gabriel: nodes connected Gabriel graph. Requires spdep package installed, assumes planar coordinates. rn: nodes connected relative neighborhood graph. Can also specified relative_neighborhood relative_neighbourhood. Requires spdep package installed, assumes planar coordinates. knn: node connected k nearest neighbors, k specified k argument. default, k = 1, meaning nodes connected nearest neighbor graph. Can also specified nearest_neighbors nearest_neighbours. Requires spdep package installed.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/create_from_spatial_points.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Create a spatial network from point geometries — create_from_spatial_points","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) pts = st_transform(mozart, 3035) # Using a custom adjacency matrix adj = matrix(c(rep(TRUE, 17), rep(rep(FALSE, 17), 16)), nrow = 17) net = as_sfnetwork(pts, connections = adj) plot(net) # Using a sparse adjacency matrix from a spatial predicate dst = units::set_units(300, \"m\") adj = st_is_within_distance(pts, dist = dst, remove_self = TRUE) net = as_sfnetwork(pts, connections = adj, directed = FALSE) plot(net) # Using pre-defined methods cnet = as_sfnetwork(pts, connections = \"complete\") snet = as_sfnetwork(pts, connections = \"sequence\") mnet = as_sfnetwork(pts, connections = \"mst\") dnet = as_sfnetwork(pts, connections = \"delaunay\") gnet = as_sfnetwork(pts, connections = \"gabriel\") rnet = as_sfnetwork(pts, connections = \"rn\") nnet = as_sfnetwork(pts, connections = \"knn\") #> Warning: neighbour object has 4 sub-graphs knet = as_sfnetwork(pts, connections = \"knn\", k = 2) #> Warning: neighbour object has 2 sub-graphs par(mar = c(1,1,1,1), mfrow = c(4,2)) plot(cnet, main = \"complete\") plot(snet, main = \"sequence\") plot(mnet, main = \"minimum spanning tree\") plot(dnet, main = \"delaunay triangulation\") plot(gnet, main = \"gabriel graph\") plot(rnet, main = \"relative neighborhood graph\") plot(nnet, main = \"nearest neighbor graph\") plot(knet, main = \"k nearest neighbor graph (k = 2)\") par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/data.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract the node or edge data from a spatial network — data","title":"Extract the node or edge data from a spatial network — data","text":"Extract node edge data spatial network","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/data.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract the node or edge data from a spatial network — data","text":"","code":"node_data(x, focused = TRUE) edge_data(x, focused = TRUE, require_sf = FALSE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/data.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract the node or edge data from a spatial network — data","text":"x object class sfnetwork. focused features focus extracted? Defaults TRUE. See focus information focused networks. require_sf sf object required? make extraction edge data fail edges spatially implicit. Defaults FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/data.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract the node or edge data from a spatial network — data","text":"nodes, always object class sf. edges, object class sf edges spatially explicit, object class tibble edges spatially implicity require_sf = FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/data.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Extract the node or edge data from a spatial network — data","text":"","code":"net = as_sfnetwork(roxel[1:10, ]) node_data(net) #> Simple feature collection with 20 features and 0 fields #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 7.525978 ymin: 51.94779 xmax: 7.543685 ymax: 51.95867 #> Geodetic CRS: WGS 84 #> # A tibble: 20 × 1 #> geometry #> * #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> 7 (7.525977 51.95283) #> 8 (7.526581 51.95293) #> 9 (7.532301 51.95559) #> 10 (7.532142 51.95589) #> 11 (7.543404 51.94779) #> 12 (7.543685 51.9479) #> 13 (7.537675 51.95689) #> 14 (7.537904 51.95656) #> 15 (7.539105 51.9504) #> 16 (7.540105 51.95058) #> 17 (7.534875 51.95795) #> 18 (7.533743 51.95769) #> 19 (7.532465 51.95424) #> 20 (7.532441 51.95482) edge_data(net) #> Simple feature collection with 10 features and 4 fields #> Attribute-geometry relationships: constant (2), NA's (2) #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.525978 ymin: 51.94779 xmax: 7.543685 ymax: 51.95867 #> Geodetic CRS: WGS 84 #> # A tibble: 10 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… #> 5 9 10 Annette-von-Droste-Hülshoff-Stra… seco… (7.532301 51.95559, 7.53… #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… #> 7 13 14 Deermannskamp resi… (7.537675 51.95689, 7.53… #> 8 15 16 Lindenstraße resi… (7.539105 51.9504, 7.540… #> 9 17 18 NA NA (7.534875 51.95795, 7.53… #> 10 19 20 Annette-von-Droste-Hülshoff-Stra… seco… (7.532465 51.95424, 7.53…"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/dual_weights.html","id":null,"dir":"Reference","previous_headings":"","what":"Specify dual edge weights — dual_weights","title":"Specify dual edge weights — dual_weights","text":"Dual edge weights two sets edge weights, one (actual weight) determine shortest path, (reported weight) report cost path.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/dual_weights.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Specify dual edge weights — dual_weights","text":"","code":"dual_weights(reported, actual)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/dual_weights.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Specify dual edge weights — dual_weights","text":"reported edge weights reported. Evaluated evaluate_weight_spec. actual actual edge weights used determine shortest paths. Evaluated evaluate_weight_spec.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/dual_weights.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Specify dual edge weights — dual_weights","text":"object class dual_weights.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/dual_weights.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Specify dual edge weights — dual_weights","text":"Dual edge weights enable dual-weighted routing. supported dodgr routing backend.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_edge_query.html","id":null,"dir":"Reference","previous_headings":"","what":"Query specific edge indices from a spatial network — evaluate_edge_query","title":"Query specific edge indices from a spatial network — evaluate_edge_query","text":"function meant called directly, used inside functions accept edge query.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_edge_query.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query specific edge indices from a spatial network — evaluate_edge_query","text":"","code":"evaluate_edge_query(data, query)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_edge_query.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Query specific edge indices from a spatial network — evaluate_edge_query","text":"data object class sfnetwork. query query defines edges extract indices, defused quosure. See Details different ways edge queries can formulated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_edge_query.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query specific edge indices from a spatial network — evaluate_edge_query","text":"vector queried edge indices.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_edge_query.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Query specific edge indices from a spatial network — evaluate_edge_query","text":"multiple ways edge indices can queried sfnetworks. query can formatted follows: spatial features: Spatial features can given object class sf sfc. nearest edge feature found calling st_nearest_feature. edge type query function: edge type query function defines edge given type . Nodes meet criterium queried. edge predicate query function: edge predicate query function defines edge given spatial predicate applies spatial relation edge spatial features. Nodes meet criterium queried. column name: referenced column expected logical values defining edge queried . Note tidy evaluation used hence column name unquoted. integers: Integers interpreted edge indices. edge index corresponds row-number edges table network. characters: Characters interpreted edge names. edge name corresponds value column named \"name\" edges table network. Note column expected store unique names without duplicated values. logicals: Logicals define edge queried . Queries can evaluated ways described forcefully converted integers using .integer.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_node_query.html","id":null,"dir":"Reference","previous_headings":"","what":"Query specific node indices from a spatial network — evaluate_node_query","title":"Query specific node indices from a spatial network — evaluate_node_query","text":"function meant called directly, used inside functions accept node query.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_node_query.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query specific node indices from a spatial network — evaluate_node_query","text":"","code":"evaluate_node_query(data, query)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_node_query.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Query specific node indices from a spatial network — evaluate_node_query","text":"data object class sfnetwork. query query defines nodes extract indices, defused quosure. See Details different ways node queries can formulated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_node_query.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query specific node indices from a spatial network — evaluate_node_query","text":"vector queried node indices.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_node_query.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Query specific node indices from a spatial network — evaluate_node_query","text":"multiple ways node indices can queried sfnetworks. query can formatted follows: spatial features: Spatial features can given object class sf sfc. nearest node feature found calling st_nearest_feature. node type query function: node type query function defines node given type . Nodes meet criterium queried. node predicate query function: node predicate query function defines node given spatial predicate applies spatial relation node spatial features. Nodes meet criterium queried. column name: referenced column expected logical values defining node queried . Note tidy evaluation used hence column name unquoted. integers: Integers interpreted node indices. node index corresponds row-number nodes table network. characters: Characters interpreted node names. node name corresponds value column named \"name\" nodes table network. Note column expected store unique names without duplicated values. logicals: Logicals define node queried . Queries can evaluated ways described forcefully converted integers using .integer.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_weight_spec.html","id":null,"dir":"Reference","previous_headings":"","what":"Specify edge weights in a spatial network — evaluate_weight_spec","title":"Specify edge weights in a spatial network — evaluate_weight_spec","text":"function meant called directly, used inside functions accept specification edge weights.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_weight_spec.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Specify edge weights in a spatial network — evaluate_weight_spec","text":"","code":"evaluate_weight_spec(data, spec)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_weight_spec.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Specify edge weights in a spatial network — evaluate_weight_spec","text":"data object class sfnetwork. spec specification defines compute extract edge weights defused quosure. See Details different ways edge weights can specified.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_weight_spec.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Specify edge weights in a spatial network — evaluate_weight_spec","text":"numeric vector edge weights.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_weight_spec.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Specify edge weights in a spatial network — evaluate_weight_spec","text":"multiple ways edge weights can specified sfnetworks. specification can formatted follows: edge measure function: spatial edge measure function computes given measure edge, used edge weights. column name: column edges table network contains edge weights. Note tidy evaluation used hence column name unquoted. numeric vector: vector length number edges network, specifying edge weight . dual weights: Dual weights can specified dual_weights function. allows use different set weights shortest paths computation reporting total cost paths. Note every routing backend support dual-weighted routing. weight specification NULL NA, means edge weights used. shortest path computation, means shortest path simply path fewest number edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/evaluate_weight_spec.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Specify edge weights in a spatial network — evaluate_weight_spec","text":"backward compatibility currently also still possible format specification quoted column name, may removed future versions. Also note many shortest path algorithms require edge weights positive.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/group_spatial.html","id":null,"dir":"Reference","previous_headings":"","what":"Group nodes based on spatial distance — group_spatial","title":"Group nodes based on spatial distance — group_spatial","text":"functions forms spatial extension grouping functions tidygraph, allowing detect communities spatial clustering algorithms.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/group_spatial.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Group nodes based on spatial distance — group_spatial","text":"","code":"group_spatial_dbscan(epsilon, min_pts = 1, use_network_distance = TRUE, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/group_spatial.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Group nodes based on spatial distance — group_spatial","text":"epsilon value epsilon parameter DBSCAN clustering algorithm, defining radius neighborhood node. min_pts value minPts parameter DBSCAN clustering algorithm, defining minimum number points neighborhood considered core point. use_network_distance distance nodes computed distance network (using st_network_distance? Defaults TRUE. set FALSE, straight-line distance (using st_distance) computed instead. ... Additional arguments passed clustering algorithm.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/group_spatial.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Group nodes based on spatial distance — group_spatial","text":"numeric vector membership node network. enumeration happens order based group size progressing largest smallest group.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/group_spatial.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Group nodes based on spatial distance — group_spatial","text":"Just grouping functions tidygraph, spatial grouping functions meant called inside tidygraph verbs mutate filter, network currently worked known thus needed argument function. want use algorithm outside tidygraph framework can use with_graph set context temporarily algorithm evaluated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/group_spatial.html","id":"functions","dir":"Reference","previous_headings":"","what":"Functions","title":"Group nodes based on spatial distance — group_spatial","text":"group_spatial_dbscan(): Uses density-based spatial clustering implemented dbscan function dbscan package. requires dbscan package installed. node marked noise form cluster.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/group_spatial.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Group nodes based on spatial distance — group_spatial","text":"","code":"library(tidygraph, quietly = TRUE) play_geometric(10, 0.5) |> activate(nodes) |> mutate(group = group_spatial_dbscan(0.25)) #> # A sfnetwork: 10 nodes and 23 edges #> # #> # An undirected simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0.03743103 ymin: 0.1712643 xmax: 0.9709666 ymax: 0.9735399 #> # CRS: NA #> # #> # Node data: 10 × 2 (active) #> geometry group #> #> 1 (0.03743103 0.4357716) 2 #> 2 (0.03893649 0.9735399) 1 #> 3 (0.261088 0.9575766) 1 #> 4 (0.3334272 0.6399788) 1 #> 5 (0.3795592 0.6188382) 1 #> 6 (0.3984854 0.3467482) 3 #> # ℹ 4 more rows #> # #> # Edge data: 23 × 3 #> from to geometry #> #> 1 1 4 (0.03743103 0.4357716, 0.3334272 0.6399788) #> 2 1 5 (0.03743103 0.4357716, 0.3795592 0.6188382) #> 3 1 6 (0.03743103 0.4357716, 0.3984854 0.3467482) #> # ℹ 20 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/ids.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract all node or edge indices from a spatial network — ids","title":"Extract all node or edge indices from a spatial network — ids","text":"Extract node edge indices spatial network","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/ids.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract all node or edge indices from a spatial network — ids","text":"","code":"node_ids(x, focused = TRUE) edge_ids(x, focused = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/ids.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract all node or edge indices from a spatial network — ids","text":"x object class sfnetwork. focused indices features focus extracted? Defaults TRUE. See focus information focused networks.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/ids.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract all node or edge indices from a spatial network — ids","text":"vector integers.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/ids.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Extract all node or edge indices from a spatial network — ids","text":"indices objects always integers correspond rownumbers respectively nodes edges table.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/ids.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Extract all node or edge indices from a spatial network — ids","text":"","code":"net = as_sfnetwork(roxel[1:10, ]) node_ids(net) #> [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 edge_ids(net) #> [1] 1 2 3 4 5 6 7 8 9 10"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/is_sfnetwork.html","id":null,"dir":"Reference","previous_headings":"","what":"Check if an object is a sfnetwork — is_sfnetwork","title":"Check if an object is a sfnetwork — is_sfnetwork","text":"Check object sfnetwork","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/is_sfnetwork.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Check if an object is a sfnetwork — is_sfnetwork","text":"","code":"is_sfnetwork(x) is.sfnetwork(x)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/is_sfnetwork.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Check if an object is a sfnetwork — is_sfnetwork","text":"x Object checked.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/is_sfnetwork.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Check if an object is a sfnetwork — is_sfnetwork","text":"TRUE given object object class sfnetwork, FALSE otherwise.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/is_sfnetwork.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Check if an object is a sfnetwork — is_sfnetwork","text":"","code":"library(tidygraph, quietly = TRUE, warn.conflicts = FALSE) net = as_sfnetwork(roxel) is_sfnetwork(net) #> [1] TRUE is_sfnetwork(as_tbl_graph(net)) #> [1] FALSE"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_directed.html","id":null,"dir":"Reference","previous_headings":"","what":"Convert undirected edges into directed edges based on their geometries — make_edges_directed","title":"Convert undirected edges into directed edges based on their geometries — make_edges_directed","text":"function converts undirected network directed network following direction given linestring geometries edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_directed.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Convert undirected edges into directed edges based on their geometries — make_edges_directed","text":"","code":"make_edges_directed(x)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_directed.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Convert undirected edges into directed edges based on their geometries — make_edges_directed","text":"x object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_directed.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Convert undirected edges into directed edges based on their geometries — make_edges_directed","text":"directed network object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_directed.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Convert undirected edges into directed edges based on their geometries — make_edges_directed","text":"undirected spatial networks required boundary edge geometries contain incident node geometries. However, required start point equals specified ** node end point specified ** node. Instead, may vice versa. undirected networks ** ** indices always swopped ** index lower ** index. Therefore, direction given ** ** indices necessarily match direction given edge geometries.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_directed.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Convert undirected edges into directed edges based on their geometries — make_edges_directed","text":"network already directed returned unmodified.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_explicit.html","id":null,"dir":"Reference","previous_headings":"","what":"Construct edge geometries for spatially implicit networks — make_edges_explicit","title":"Construct edge geometries for spatially implicit networks — make_edges_explicit","text":"function turns spatially implicit networks spatially explicit networks adding geometry column edge data.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_explicit.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Construct edge geometries for spatially implicit networks — make_edges_explicit","text":"","code":"make_edges_explicit(x, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_explicit.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Construct edge geometries for spatially implicit networks — make_edges_explicit","text":"x object class sfnetwork. ... Arguments forwarded st_as_sf directly convert edges table sf object. arguments given, edges made explicit simply drawing straight lines start end node edge.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_explicit.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Construct edge geometries for spatially implicit networks — make_edges_explicit","text":"object class sfnetwork spatially explicit edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_explicit.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Construct edge geometries for spatially implicit networks — make_edges_explicit","text":"network already spatially explicit returned unmodified.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_follow_indices.html","id":null,"dir":"Reference","previous_headings":"","what":"Match the direction of edge geometries to their specified incident nodes — make_edges_follow_indices","title":"Match the direction of edge geometries to their specified incident nodes — make_edges_follow_indices","text":"function updates edge geometries undirected networks guaranteed start specified ** node end specified ** node.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_follow_indices.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Match the direction of edge geometries to their specified incident nodes — make_edges_follow_indices","text":"","code":"make_edges_follow_indices(x)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_follow_indices.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Match the direction of edge geometries to their specified incident nodes — make_edges_follow_indices","text":"x object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_follow_indices.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Match the direction of edge geometries to their specified incident nodes — make_edges_follow_indices","text":"object class sfnetwork updated edge geometries.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_follow_indices.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Match the direction of edge geometries to their specified incident nodes — make_edges_follow_indices","text":"undirected spatial networks required boundary edge geometries contain incident node geometries. However, required start point equals specified ** node end point specified ** node. Instead, may vice versa. undirected networks ** ** indices always swopped ** index lower ** index. function reverses edge geometries start ** node end ** node, resulting network guaranteed edge boundary points exactly match incident node geometries. directed networks, change.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_implicit.html","id":null,"dir":"Reference","previous_headings":"","what":"Drop edge geometries of spatially explicit networks — make_edges_implicit","title":"Drop edge geometries of spatially explicit networks — make_edges_implicit","text":"function turns spatially explicit networks spatially implicit networks dropping geometry column edge data.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_implicit.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Drop edge geometries of spatially explicit networks — make_edges_implicit","text":"","code":"make_edges_implicit(x)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_implicit.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Drop edge geometries of spatially explicit networks — make_edges_implicit","text":"x object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_implicit.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Drop edge geometries of spatially explicit networks — make_edges_implicit","text":"object class sfnetwork spatially implicit edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_implicit.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Drop edge geometries of spatially explicit networks — make_edges_implicit","text":"network already spatially implicit returned unmodified.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_mixed.html","id":null,"dir":"Reference","previous_headings":"","what":"Make some edges directed and some undirected — make_edges_mixed","title":"Make some edges directed and some undirected — make_edges_mixed","text":"function creates mixed network, meaning edges directed, undirected. practice implemented directed network edges meant undirected duplicated reversed.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_mixed.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Make some edges directed and some undirected — make_edges_mixed","text":"","code":"make_edges_mixed(x, directed)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_mixed.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Make some edges directed and some undirected — make_edges_mixed","text":"x object class sfnetwork. directed integer vector edge indices specifying edges directed.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_mixed.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Make some edges directed and some undirected — make_edges_mixed","text":"mixed network object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_valid.html","id":null,"dir":"Reference","previous_headings":"","what":"Match edge geometries to their incident node locations — make_edges_valid","title":"Match edge geometries to their incident node locations — make_edges_valid","text":"function makes invalid edges valid modifying either edge node geometries boundary points edge linestring geometries always match point geometries nodes specified incident nodes ** ** columns.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_valid.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Match edge geometries to their incident node locations — make_edges_valid","text":"","code":"make_edges_valid(x, preserve_geometries = FALSE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_valid.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Match edge geometries to their incident node locations — make_edges_valid","text":"x object class sfnetwork. preserve_geometries edge geometries remain unmodified? Defaults FALSE. See Details.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_valid.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Match edge geometries to their incident node locations — make_edges_valid","text":"object class sfnetwork corrected edge geometries.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_valid.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Match edge geometries to their incident node locations — make_edges_valid","text":"geometries preserved, edges made valid adding edge boundary points equal corresponding node geometry new nodes network, updating ** ** indices match newly added nodes. FALSE, edges made valid modifying geometries, .e. edge boundary points equal corresponding node geometry replaced node geometry.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/make_edges_valid.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Match edge geometries to their incident node locations — make_edges_valid","text":"function works edge geometries meant start specified ** node end specified ** node. undirected networks necessarily case, since edge geometries allowed start specified ** node end specified ** node. Therefore, undirected networks edges first reversed running function. Use make_edges_follow_indices .","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/mozart.html","id":null,"dir":"Reference","previous_headings":"","what":"Point locations for places about W. A. Mozart in Salzburg, Austria — mozart","title":"Point locations for places about W. A. Mozart in Salzburg, Austria — mozart","text":"dataset containing point locations (museums, sculptures, squares, universities, etc.) places named Wolfgang Amadeus Mozart city Salzburg, Austria. data taken OpenStreetMap. See `data-raw/mozart.R` code creation.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/mozart.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Point locations for places about W. A. Mozart in Salzburg, Austria — mozart","text":"","code":"mozart"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/mozart.html","id":"format","dir":"Reference","previous_headings":"","what":"Format","title":"Point locations for places about W. A. Mozart in Salzburg, Austria — mozart","text":"object class sf LINESTRING geometries, containing 17 features four columns: name name point location type type location, e.g. museum, artwork, cinema, etc. website website URL information place, available geometry geometry list column","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/mozart.html","id":"source","dir":"Reference","previous_headings":"","what":"Source","title":"Point locations for places about W. A. Mozart in Salzburg, Austria — mozart","text":"https://www.openstreetmap.org","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/n.html","id":null,"dir":"Reference","previous_headings":"","what":"Count the number of nodes or edges in a network — n","title":"Count the number of nodes or edges in a network — n","text":"Count number nodes edges network","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/n.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Count the number of nodes or edges in a network — n","text":"","code":"n_nodes(x, focused = FALSE) n_edges(x, focused = FALSE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/n.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Count the number of nodes or edges in a network — n","text":"x object class sfnetwork, network object inheriting igraph. focused features focus counted? Defaults FALSE. See focus information focused networks.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/n.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Count the number of nodes or edges in a network — n","text":"integer.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/n.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Count the number of nodes or edges in a network — n","text":"","code":"net = as_sfnetwork(roxel) n_nodes(net) #> [1] 987 n_edges(net) #> [1] 1215"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nb.html","id":null,"dir":"Reference","previous_headings":"","what":"Conversion between neighbor lists and sfnetworks — nb","title":"Conversion between neighbor lists and sfnetworks — nb","text":"Neighbor lists sparse adjacency matrices list format specify node nodes adjacent. occur example sf package sgbp objects, also frequently used spdep package.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nb.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Conversion between neighbor lists and sfnetworks — nb","text":"","code":"nb_to_sfnetwork( x, nodes, directed = TRUE, edges_as_lines = TRUE, compute_length = FALSE, force = FALSE ) sfnetwork_to_nb(x, direction = \"out\")"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nb.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Conversion between neighbor lists and sfnetworks — nb","text":"x conversion sfnetwork: neighbor list, list adjacent . conversion sfnetwork: object class sfnetwork. nodes nodes object class sf sfc POINT geometries. directed constructed network directed? Defaults TRUE. edges_as_lines created edges spatially explicit, .e. LINESTRING geometries stored geometry list column? Defaults TRUE. compute_length geographic length edges stored column named length? Defaults FALSE. force validity checks skipped? Defaults FALSE, meaning network validity checks executed constructing network. checks make sure provided neighbor list valid structure, .e. length equal number provided nodes values integers referring one nodes. direction direction defines two nodes neighbors. Defaults '', meaning direction given network followed node j neighbor node exists edge ->j. May set '', meaning opposite direction followed node j neighbor node exists edge j->. May also set '', meaning network considered undirected. argument ignored undirected networks.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nb.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Conversion between neighbor lists and sfnetworks — nb","text":"conversion sfnetwork: object class sfnetwork. conversion sfnetwork: neighbor list, list one element per node holds integer indices nodes adjacent .","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract the nearest nodes or edges to given spatial features — nearest","title":"Extract the nearest nodes or edges to given spatial features — nearest","text":"Extract nearest nodes edges given spatial features","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract the nearest nodes or edges to given spatial features — nearest","text":"","code":"nearest_nodes(x, y, focused = TRUE) nearest_edges(x, y, focused = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract the nearest nodes or edges to given spatial features — nearest","text":"x object class sfnetwork. y Spatial features object class sf sfc. focused features focus extracted? Defaults TRUE. See focus information focused networks.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract the nearest nodes or edges to given spatial features — nearest","text":"object class sf row containing nearest node edge corresponding spatial features y.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Extract the nearest nodes or edges to given spatial features — nearest","text":"determine nearest node edge feature y function st_nearest_feature used. extracting nearest edges, spatially explicit edges required, .e. edges table geometry column.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Extract the nearest nodes or edges to given spatial features — nearest","text":"","code":"library(sf, quietly = TRUE) net = as_sfnetwork(roxel) pts = st_sample(st_bbox(roxel), 6) nodes = nearest_nodes(net, pts) edges = nearest_edges(net, pts) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) plot(net, main = \"Nearest nodes\") plot(pts, cex = 2, col = \"red\", pch = 20, add = TRUE) plot(st_geometry(nodes), cex = 2, col = \"orange\", pch = 20, add = TRUE) plot(net, main = \"Nearest edges\") plot(pts, cex = 2, col = \"red\", pch = 20, add = TRUE) plot(st_geometry(edges), lwd = 2, col = \"orange\", pch = 20, add = TRUE) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest_ids.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract the indices of nearest nodes or edges to given spatial features — nearest_ids","title":"Extract the indices of nearest nodes or edges to given spatial features — nearest_ids","text":"Extract indices nearest nodes edges given spatial features","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest_ids.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract the indices of nearest nodes or edges to given spatial features — nearest_ids","text":"","code":"nearest_node_ids(x, y, focused = TRUE) nearest_edge_ids(x, y, focused = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest_ids.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract the indices of nearest nodes or edges to given spatial features — nearest_ids","text":"x object class sfnetwork. y Spatial features object class sf sfc. focused indices features focus extracted? Defaults TRUE. See focus information focused networks.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest_ids.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract the indices of nearest nodes or edges to given spatial features — nearest_ids","text":"integer vector element containing index nearest node edge corresponding spatial features y.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest_ids.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Extract the indices of nearest nodes or edges to given spatial features — nearest_ids","text":"determine nearest node edge feature y function st_nearest_feature used. extracting nearest edges, spatially explicit edges required, .e. edges table geometry column.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/nearest_ids.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Extract the indices of nearest nodes or edges to given spatial features — nearest_ids","text":"","code":"library(sf, quietly = TRUE) net = as_sfnetwork(roxel) pts = st_sample(st_bbox(roxel), 6) nearest_node_ids(net, pts) #> [1] 761 256 8 353 985 730 nearest_edge_ids(net, pts) #> [1] 618 144 4 210 1192 939"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/node_coordinates.html","id":null,"dir":"Reference","previous_headings":"","what":"Query node coordinates — node_coordinates","title":"Query node coordinates — node_coordinates","text":"functions allow query specific coordinate values geometries nodes.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/node_coordinates.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query node coordinates — node_coordinates","text":"","code":"node_X() node_Y() node_Z() node_M()"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/node_coordinates.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query node coordinates — node_coordinates","text":"numeric vector length number nodes network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/node_coordinates.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Query node coordinates — node_coordinates","text":"Just query functions tidygraph, functions meant called inside tidygraph verbs mutate filter, network currently worked known thus needed argument function. want use algorithm outside tidygraph framework can use with_graph set context temporarily algorithm evaluated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/node_coordinates.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Query node coordinates — node_coordinates","text":"requested coordinate value available node, NA returned.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/node_coordinates.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Query node coordinates — node_coordinates","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) # Create a network. net = as_sfnetwork(roxel) # Use query function in a filter call. filtered = net |> activate(nodes) |> filter(node_X() > 7.54) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) plot(net, col = \"grey\") plot(filtered, col = \"red\", add = TRUE) par(oldpar) # Use query function in a mutate call. net |> activate(nodes) |> mutate(X = node_X(), Y = node_Y()) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 3 (active) #> geometry X Y #> #> 1 (7.538109 51.95286) 7.54 52.0 #> 2 (7.537867 51.95282) 7.54 52.0 #> 3 (7.537815 51.95867) 7.54 52.0 #> 4 (7.537015 51.95848) 7.54 52.0 #> 5 (7.533441 51.95578) 7.53 52.0 #> 6 (7.533415 51.95561) 7.53 52.0 #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows # Use query function directly. X = with_graph(net, node_X()) head(X) #> [1] 7.538109 7.537867 7.537815 7.537015 7.533441 7.533415"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/play_spatial.html","id":null,"dir":"Reference","previous_headings":"","what":"Create random spatial networks — play_spatial","title":"Create random spatial networks — play_spatial","text":"Random spatial networks created randomly sampling nodes within given area, connecting edges according specified method.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/play_spatial.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Create random spatial networks — play_spatial","text":"","code":"play_geometric( n, radius, bounds = NULL, edges_as_lines = TRUE, compute_length = FALSE, ... )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/play_spatial.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Create random spatial networks — play_spatial","text":"n number nodes sampled. radius radius within nodes connected edge. bounds spatial features within nodes sampled object class sf, sfc, sfg bbox. set NULL, nodes sampled within unit square. edges_as_lines created edges spatially explicit, .e. LINESTRING geometries stored geometry list column? Defaults TRUE. compute_length geographic length edges stored column named length? Uses st_length compute length edge geometries edges spatially explicit, st_distance compute distance boundary nodes edges spatially implicit. Please note values column automatically recognized edge weights. needs specified explicitly calling function uses edge weights. Defaults FALSE. ... Additional arguments passed st_sample. Ignored bounds = NULL.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/play_spatial.html","id":"functions","dir":"Reference","previous_headings":"","what":"Functions","title":"Create random spatial networks — play_spatial","text":"play_geometric(): Creates random geometric graph. Two nodes connected edge distance within given radius. nodes sampled unit square (.e. bounds = NULL) radius unitless. bounds given spatial feature, radius assumed meters geographic coordinates, units coordinate reference system projected coordinates. Alternatively, units can also specified explicitly providing units object.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/play_spatial.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Create random spatial networks — play_spatial","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) # Sample 10 nodes on a unit square # Connect nodes by an edge if they are within 0.25 distance from each other net = play_geometric(10, 0.25) net #> # A sfnetwork: 10 nodes and 6 edges #> # #> # An undirected simple graph with 5 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0.08561206 ymin: 0.0002388966 xmax: 0.9256447 ymax: 0.9330341 #> # CRS: NA #> # #> # Node data: 10 × 1 (active) #> geometry #> #> 1 (0.08561206 0.5636468) #> 2 (0.20857 0.08998052) #> 3 (0.2165673 0.3052184) #> 4 (0.2337034 0.0002388966) #> 5 (0.333072 0.9330341) #> 6 (0.6262453 0.7340943) #> # ℹ 4 more rows #> # #> # Edge data: 6 × 3 #> from to geometry #> #> 1 2 3 (0.20857 0.08998052, 0.2165673 0.3052184) #> 2 2 4 (0.20857 0.08998052, 0.2337034 0.0002388966) #> 3 6 7 (0.6262453 0.7340943, 0.6674265 0.5150633) #> # ℹ 3 more rows plot(net) # Sample 10 nodes within a spatial bounding box # Connect nodes by an edge if they are within 1 km from each other net = play_geometric(10, units::set_units(1, \"km\"), bounds = st_bbox(roxel)) net #> # A sfnetwork: 10 nodes and 32 edges #> # #> # An undirected simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.52265 ymin: 51.94154 xmax: 7.545803 ymax: 51.95783 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 10 × 1 (active) #> geometry #> #> 1 (7.545317 51.95206) #> 2 (7.545803 51.95209) #> 3 (7.540433 51.94154) #> 4 (7.540273 51.94851) #> 5 (7.535512 51.95356) #> 6 (7.52265 51.95783) #> # ℹ 4 more rows #> # #> # Edge data: 32 × 3 #> from to geometry #> #> 1 1 2 (7.545317 51.95206, 7.545803 51.95209) #> 2 1 4 (7.545317 51.95206, 7.540273 51.94851) #> 3 1 5 (7.545317 51.95206, 7.535512 51.95356) #> # ℹ 29 more rows plot(net) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/plot.sfnetwork.html","id":null,"dir":"Reference","previous_headings":"","what":"Plot the geometries of a sfnetwork — plot.sfnetwork","title":"Plot the geometries of a sfnetwork — plot.sfnetwork","text":"Plot geometries object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/plot.sfnetwork.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Plot the geometries of a sfnetwork — plot.sfnetwork","text":"","code":"# S3 method for class 'sfnetwork' plot(x, draw_lines = TRUE, node_args = list(), edge_args = list(), ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/plot.sfnetwork.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Plot the geometries of a sfnetwork — plot.sfnetwork","text":"x Object class sfnetwork. draw_lines edges network spatially implicit, straight lines drawn connected nodes? Defaults TRUE. Ignored edges network spatially explicit. node_args named list arguments passed plot.sf plotting nodes. edge_args named list arguments passed plot.sf plotting edges. ... Arguments passed plot.sf apply plot whole.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/plot.sfnetwork.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Plot the geometries of a sfnetwork — plot.sfnetwork","text":"Invisible.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/plot.sfnetwork.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Plot the geometries of a sfnetwork — plot.sfnetwork","text":"Arguments passed ... used plotting nodes plotting edges. Edges always plotted first. Arguments specified node_args edge_args specified ... well, result error.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/plot.sfnetwork.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Plot the geometries of a sfnetwork — plot.sfnetwork","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,1)) net = as_sfnetwork(roxel) plot(net) # When edges are spatially implicit. # By default straight lines will be drawn between connected nodes. par(mar = c(1,1,1,1), mfrow = c(1,2)) inet = st_drop_geometry(activate(net, \"edges\")) plot(inet) plot(inet, draw_lines = FALSE) # Changing plot settings. par(mar = c(1,1,1,1), mfrow = c(1,1)) plot(net, main = \"My network\", col = \"blue\", pch = 18, lwd = 1, cex = 2) # Changing plot settings for nodes and edges separately. plot(net, node_args = list(col = \"red\"), edge_args = list(col = \"blue\")) # Add grid and axis par(mar = c(2.5,2.5,1,1)) plot(net, graticule = TRUE, axes = TRUE) # Plot two networks on top of each other. par(mar = c(1,1,1,1), mfrow = c(1,1)) neta = as_sfnetwork(roxel[1:10, ]) netb = as_sfnetwork(roxel[50:60, ]) plot(neta) plot(netb, node_args = list(col = \"orange\"), add = TRUE) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/reexports.html","id":null,"dir":"Reference","previous_headings":"","what":"Objects exported from other packages — reexports","title":"Objects exported from other packages — reexports","text":"objects imported packages. Follow links see documentation. tidygraph %>%, activate, active, convert, crystallise, crystallize, morph, unmorph, with_graph","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/roxel.html","id":null,"dir":"Reference","previous_headings":"","what":"Road network of Münster Roxel — roxel","title":"Road network of Münster Roxel — roxel","text":"dataset containing road network (roads, bikelanes, footpaths, etc.) Roxel, neighborhood city Münster, Germany. data taken OpenStreetMap, querying key = 'highway'. See `data-raw/roxel.R` code creation.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/roxel.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Road network of Münster Roxel — roxel","text":"","code":"roxel"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/roxel.html","id":"format","dir":"Reference","previous_headings":"","what":"Format","title":"Road network of Münster Roxel — roxel","text":"object class sf LINESTRING geometries, containing 1215 features three columns: name name road, exists type type road, e.g. cycleway geometry geometry list column","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/roxel.html","id":"source","dir":"Reference","previous_headings":"","what":"Source","title":"Road network of Münster Roxel — roxel","text":"https://www.openstreetmap.org","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_attr.html","id":null,"dir":"Reference","previous_headings":"","what":"Query sf attributes from the active element of a sfnetwork — sf_attr","title":"Query sf attributes from the active element of a sfnetwork — sf_attr","text":"Query sf attributes active element sfnetwork","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_attr.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query sf attributes from the active element of a sfnetwork — sf_attr","text":"","code":"sf_attr(x, name, active = NULL)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_attr.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Query sf attributes from the active element of a sfnetwork — sf_attr","text":"x object class sfnetwork. name Name attribute query. Either 'sf_column' extract name geometry list column, 'agr' extract specification attribute-geometry relationships. active network element (.e. nodes edges) activate extracting. NULL, set current active element given network. Defaults NULL.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_attr.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query sf attributes from the active element of a sfnetwork — sf_attr","text":"value queried attribute.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_attr.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Query sf attributes from the active element of a sfnetwork — sf_attr","text":"","code":"net = as_sfnetwork(roxel) sf_attr(net, \"agr\", active = \"edges\") #> from to name type #> constant constant #> Levels: constant aggregate identity sf_attr(net, \"sf_column\", active = \"nodes\") #> [1] \"geometry\""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_methods.html","id":null,"dir":"Reference","previous_headings":"","what":"sf methods for sfnetworks — sf_methods","title":"sf methods for sfnetworks — sf_methods","text":"sf methods sfnetwork objects.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_methods.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"sf methods for sfnetworks — sf_methods","text":"","code":"# S3 method for class 'sfnetwork' st_as_sf(x, active = NULL, focused = TRUE, ...) # S3 method for class 'sfnetwork' st_geometry(obj, active = NULL, focused = TRUE, ...) # S3 method for class 'sfnetwork' st_geometry(x) <- value # S3 method for class 'sfnetwork' st_drop_geometry(x, ...) # S3 method for class 'sfnetwork' st_bbox(obj, active = NULL, ...) # S3 method for class 'sfnetwork' st_coordinates(x, active = NULL, ...) # S3 method for class 'sfnetwork' st_is(x, ...) # S3 method for class 'sfnetwork' st_is_valid(x, ...) # S3 method for class 'sfnetwork' st_as_s2(x, active = NULL, focused = TRUE, ...) # S3 method for class 'sfnetwork' st_crs(x, ...) # S3 method for class 'sfnetwork' st_crs(x) <- value # S3 method for class 'sfnetwork' st_precision(x) # S3 method for class 'sfnetwork' st_set_precision(x, precision) # S3 method for class 'sfnetwork' st_shift_longitude(x, ...) # S3 method for class 'sfnetwork' st_transform(x, ...) # S3 method for class 'sfnetwork' st_wrap_dateline(x, ...) # S3 method for class 'sfnetwork' st_normalize(x, ...) # S3 method for class 'sfnetwork' st_zm(x, ...) # S3 method for class 'sfnetwork' st_m_range(obj, active = NULL, ...) # S3 method for class 'sfnetwork' st_z_range(obj, active = NULL, ...) # S3 method for class 'sfnetwork' st_agr(x, active = NULL, ...) # S3 method for class 'sfnetwork' st_agr(x) <- value # S3 method for class 'sfnetwork' st_reverse(x, ...) # S3 method for class 'sfnetwork' st_segmentize(x, ...) # S3 method for class 'sfnetwork' st_simplify(x, ...) # S3 method for class 'sfnetwork' st_join(x, y, ..., ignore_multiple = TRUE) # S3 method for class 'morphed_sfnetwork' st_join(x, y, ...) # S3 method for class 'sfnetwork' st_filter(x, y, ...) # S3 method for class 'morphed_sfnetwork' st_filter(x, y, ...) # S3 method for class 'sfnetwork' st_crop(x, y, ...) # S3 method for class 'morphed_sfnetwork' st_crop(x, y, ...) # S3 method for class 'sfnetwork' st_difference(x, y, ...) # S3 method for class 'morphed_sfnetwork' st_difference(x, y, ...) # S3 method for class 'sfnetwork' st_intersection(x, y, ...) # S3 method for class 'morphed_sfnetwork' st_intersection(x, y, ...) # S3 method for class 'sfnetwork' st_intersects(x, y, ...) # S3 method for class 'sfnetwork' st_sample(x, ...) # S3 method for class 'sfnetwork' st_nearest_points(x, y, ...) # S3 method for class 'sfnetwork' st_area(x, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_methods.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"sf methods for sfnetworks — sf_methods","text":"x object class sfnetwork. active network element (.e. nodes edges) activate extracting. NULL, set current active element given network. Defaults NULL. focused features focus extracted? Defaults TRUE. See focus information focused networks. ... Arguments passed corresponding sf function. obj object class sfnetwork. value value assigned. See documentation corresponding sf function details. precision precision assigned. See st_precision details. y object class sf, directly convertible using st_as_sf. cases, can also object sfg bbox. Always look documentation corresponding sf function details. ignore_multiple performing spatial join nodes table, multiple matches single node, first one joined network. happen others? argument set TRUE, ignored. argument set FALSE, added isolated nodes returned network. Nodes equal locations can merged using spatial morpher to_spatial_unique. Defaults TRUE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_methods.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"sf methods for sfnetworks — sf_methods","text":"methods st_join, st_filter, st_intersection, st_difference st_crop, well methods setter functions geometric unary operations preserve class object applied , .e. either sfnetwork object morphed equivalent. dropping node geometries, object class tbl_graph returned. methods return type objects corresponding sf function. See sf documentation details.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_methods.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"sf methods for sfnetworks — sf_methods","text":"See sf documentation. following methods special behavior: st_geometry<-: geometry setter requires replacement geometries CRS network. Node replacements points, edge replacements linestrings. replacing node geometries, boundaries edge geometries replaced well preserve valid spatial network structure. replacing edge geometries, new edge boundaries match location specified incident node added new nodes network. st_transform: matter applied nodes edge table, method update coordinates tables. holds methods update way coordinates encoded without changing actual location, st_precision, st_normalize, st_zm, others. st_join: applied nodes table multiple matches exist node, first match joined. warning given case. ignore_multiple = FALSE, multiple mathces instead added isolated nodes returned network. st_intersection, st_difference st_crop: methods clip edge geometries applied edges table. preserve valid spatial network structure, clipped edge boundaries added new nodes network. st_reverse: reversing edge geometries directed network, indices columns swapped well. st_segmentize: segmentizing edge geometries, edge boundaries forced remain valid spatial network structure preserved. may lead slightly inaccurate results. Geometric unary operations supported sfnetwork objects change geometry type spatial location original features, since break valid spatial network structure. applying unsupported operations, first extract element interest (nodes edges) using st_as_sf.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sf_methods.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"sf methods for sfnetworks — sf_methods","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) net = as_sfnetwork(roxel) # Extract the active network element as sf object. st_as_sf(net) #> Simple feature collection with 987 features and 0 fields #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 987 × 1 #> geometry #> * #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> 4 (7.537015 51.95848) #> 5 (7.533441 51.95578) #> 6 (7.533415 51.95561) #> 7 (7.525977 51.95283) #> 8 (7.526581 51.95293) #> 9 (7.532301 51.95559) #> 10 (7.532142 51.95589) #> # ℹ 977 more rows # Extract any network element as sf object. st_as_sf(net, \"edges\") #> Simple feature collection with 1215 features and 4 fields #> Attribute-geometry relationships: constant (2), NA's (2) #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> # A tibble: 1,215 × 5 #> from to name type geometry #> * #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… #> 5 9 10 Annette-von-Droste-Hülshoff-Stra… seco… (7.532301 51.95559, 7.53… #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… #> 7 13 14 Deermannskamp resi… (7.537675 51.95689, 7.53… #> 8 15 16 Lindenstraße resi… (7.539105 51.9504, 7.540… #> 9 17 18 NA NA (7.534875 51.95795, 7.53… #> 10 19 20 Annette-von-Droste-Hülshoff-Stra… seco… (7.532465 51.95424, 7.53… #> # ℹ 1,205 more rows # Get the geometry of the active network element. st_geometry(net) #> Geometry set for 987 features #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> First 5 geometries: #> POINT (7.538109 51.95286) #> POINT (7.537867 51.95282) #> POINT (7.537815 51.95867) #> POINT (7.537015 51.95848) #> POINT (7.533441 51.95578) # Get the geometry of any network element. st_geometry(net, \"edges\") #> Geometry set for 1215 features #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> Geodetic CRS: WGS 84 #> First 5 geometries: #> LINESTRING (7.538109 51.95286, 7.537867 51.95282) #> LINESTRING (7.537815 51.95867, 7.537015 51.95848) #> LINESTRING (7.533441 51.95578, 7.533467 51.9557... #> LINESTRING (7.525977 51.95283, 7.526581 51.95293) #> LINESTRING (7.532301 51.95559, 7.532214 51.9557... # Replace the geometry of the nodes. # This will automatically update edge geometries to match the new nodes. newnet = net newnds = rep(st_centroid(st_combine(st_geometry(net))), n_nodes(net)) st_geometry(newnet) = newnds plot(net) plot(newnet) # Drop the geometries of the edges. # This returns an sfnetwork with spatially implicit edges. st_drop_geometry(activate(net, \"edges\")) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 4 (active) #> from to name type #> #> 1 1 2 Hagemanns Kämpken residential #> 2 3 4 Stiegkamp residential #> 3 5 6 Havixbecker Straße residential #> 4 7 8 Holzschuhmacherweg residential #> 5 9 10 Annette-von-Droste-Hülshoff-Straße secondary #> 6 11 12 NA footway #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows # Drop the geometries of the nodes. # This returns a tbl_graph. st_drop_geometry(net) #> # A tbl_graph: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components #> # #> # Node Data: 987 × 0 (active) #> # #> # Edge Data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows # Get the bounding box of the active network element. st_bbox(net) #> xmin ymin xmax ymax #> 7.522595 51.941511 7.546705 51.961194 # Get CRS of the network. st_crs(net) #> Coordinate Reference System: #> User input: EPSG:4326 #> wkt: #> GEOGCRS[\"WGS 84\", #> ENSEMBLE[\"World Geodetic System 1984 ensemble\", #> MEMBER[\"World Geodetic System 1984 (Transit)\"], #> MEMBER[\"World Geodetic System 1984 (G730)\"], #> MEMBER[\"World Geodetic System 1984 (G873)\"], #> MEMBER[\"World Geodetic System 1984 (G1150)\"], #> MEMBER[\"World Geodetic System 1984 (G1674)\"], #> MEMBER[\"World Geodetic System 1984 (G1762)\"], #> ELLIPSOID[\"WGS 84\",6378137,298.257223563, #> LENGTHUNIT[\"metre\",1]], #> ENSEMBLEACCURACY[2.0]], #> PRIMEM[\"Greenwich\",0, #> ANGLEUNIT[\"degree\",0.0174532925199433]], #> CS[ellipsoidal,2], #> AXIS[\"geodetic latitude (Lat)\",north, #> ORDER[1], #> ANGLEUNIT[\"degree\",0.0174532925199433]], #> AXIS[\"geodetic longitude (Lon)\",east, #> ORDER[2], #> ANGLEUNIT[\"degree\",0.0174532925199433]], #> USAGE[ #> SCOPE[\"Horizontal component of 3D system.\"], #> AREA[\"World.\"], #> BBOX[-90,-180,90,180]], #> ID[\"EPSG\",4326]] # Get agr factor of the active network element. st_agr(net) #> factor() #> Levels: constant aggregate identity # Get agr factor of any network element. st_agr(net, \"edges\") #> from to name type #> constant constant #> Levels: constant aggregate identity # Spatial join applied to the active network element. net = st_transform(net, 3035) codes = st_as_sf(st_make_grid(net, n = c(2, 2))) codes$post_code = as.character(seq(1000, 1000 + nrow(codes) * 10 - 10, 10)) joined = st_join(net, codes, join = st_intersects) joined #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150707 ymin: 3206375 xmax: 4152366 ymax: 3208564 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 987 × 2 (active) #> geometry post_code #> #> 1 (4151782 3207612) 1030 #> 2 (4151765 3207609) 1030 #> 3 (4151784 3208259) 1030 #> 4 (4151728 3208240) 1030 #> 5 (4151472 3207948) 1020 #> 6 (4151470 3207929) 1020 #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (4151782 3207612, 4151765 3207609) #> 2 3 4 Stiegkamp residential (4151784 3208259, 4151728 3208240) #> 3 5 6 Havixbecker Straße residential (4151472 3207948, 4151474 3207941,… #> # ℹ 1,212 more rows plot(net, col = \"grey\") plot(codes, col = NA, border = \"red\", lty = 4, lwd = 4, add = TRUE) text(st_coordinates(st_centroid(st_geometry(codes))), codes$post_code) plot(st_geometry(joined, \"edges\")) plot(st_as_sf(joined, \"nodes\"), pch = 20, add = TRUE) par(oldpar) # Spatial filter applied to the active network element. p1 = st_point(c(4151358, 3208045)) p2 = st_point(c(4151340, 3207520)) p3 = st_point(c(4151756, 3207506)) p4 = st_point(c(4151774, 3208031)) poly = st_multipoint(c(p1, p2, p3, p4)) |> st_cast('POLYGON') |> st_sfc(crs = 3035) |> st_as_sf() filtered = st_filter(net, poly, .pred = st_intersects) plot(net, col = \"grey\") plot(poly, border = \"red\", lty = 4, lwd = 4, add = TRUE) plot(filtered) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork.html","id":null,"dir":"Reference","previous_headings":"","what":"Create a sfnetwork — sfnetwork","title":"Create a sfnetwork — sfnetwork","text":"sfnetwork tidy data structure geospatial networks. extends tbl_graph data structure relational data domain geospatial networks, nodes edges embedded geographical space, offers smooth integration sf spatial data analysis.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Create a sfnetwork — sfnetwork","text":"","code":"sfnetwork( nodes, edges = NULL, directed = TRUE, node_key = \"name\", edges_as_lines = NULL, compute_length = FALSE, length_as_weight = deprecated(), force = FALSE, message = TRUE, ... )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Create a sfnetwork — sfnetwork","text":"nodes nodes network. object class sf, directly convertible using st_as_sf. features associated geometry type POINT. edges edges network. May object class sf, features associated geometry type LINESTRING. may also regular data.frame tbl_df object. case, nodes ends edge must referenced column, integers characters. Integers refer position node nodes table, characters refer name node stored column referred node_key argument. Setting edges NULL create network without edges. directed constructed network directed? Defaults TRUE. node_key name column nodes table character represented columns matched . NA, first column always chosen. setting effect given integers. Defaults 'name'. edges_as_lines edges spatially explicit, .e. LINESTRING geometries stored geometry list column? NULL, automatically defined, setting argument TRUE edges given object class sf, FALSE otherwise. Defaults NULL. compute_length geographic length edges stored column named length? Uses st_length compute length edge geometries edges spatially explicit, st_distance compute distance boundary nodes edges spatially implicit. already column named length, overwritten. Please note values column automatically recognized edge weights. needs specified explicitly calling function uses edge weights. Defaults FALSE. length_as_weight Deprecated, use compute_length instead. force network validity checks skipped? Defaults FALSE, meaning network validity checks executed constructing network. checks guarantee valid spatial network structure. nodes, means POINT geometries. case spatially explicit edges, also checked edges LINESTRING geometries, nodes edges CRS boundary points edges match corresponding node coordinates. checks important, also time consuming. already sure input data meet requirements, checks unnecessary can turned improve performance. message informational messages (messages neither warnings errors) printed constructing network? Defaults TRUE. ... Arguments passed st_as_sf, nodes need converted sf object construction.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Create a sfnetwork — sfnetwork","text":"object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Create a sfnetwork — sfnetwork","text":"","code":"library(sf, quietly = TRUE) p1 = st_point(c(7, 51)) p2 = st_point(c(7, 52)) p3 = st_point(c(8, 52)) nodes = st_as_sf(st_sfc(p1, p2, p3, crs = 4326)) e1 = st_cast(st_union(p1, p2), \"LINESTRING\") e2 = st_cast(st_union(p1, p3), \"LINESTRING\") e3 = st_cast(st_union(p3, p2), \"LINESTRING\") edges = st_as_sf(st_sfc(e1, e2, e3, crs = 4326)) edges$from = c(1, 1, 3) edges$to = c(2, 3, 2) # Default. sfnetwork(nodes, edges) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> → Checking edge geometry types ... #> ✔ All edges have geometry type LINESTRING #> → Checking coordinate reference system equality ... #> ✔ Nodes and edges have the same crs #> → Checking coordinate precision equality ... #> ✔ Nodes and edges have the same precision #> → Checking if geometries match ... #> ✔ Node locations match edge boundaries #> ✔ Spatial network structure is valid #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed acyclic simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 1 (active) #> x #> #> 1 (7 51) #> 2 (7 52) #> 3 (8 52) #> # #> # Edge data: 3 × 3 #> from to x #> #> 1 1 2 (7 51, 7 52) #> 2 1 3 (7 51, 8 52) #> 3 3 2 (8 52, 7 52) # Undirected network. sfnetwork(nodes, edges, directed = FALSE) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> → Checking edge geometry types ... #> ✔ All edges have geometry type LINESTRING #> → Checking coordinate reference system equality ... #> ✔ Nodes and edges have the same crs #> → Checking coordinate precision equality ... #> ✔ Nodes and edges have the same precision #> → Checking if geometries match ... #> ✔ Node locations match edge boundaries #> ✔ Spatial network structure is valid #> # A sfnetwork: 3 nodes and 3 edges #> # #> # An undirected simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 1 (active) #> x #> #> 1 (7 51) #> 2 (7 52) #> 3 (8 52) #> # #> # Edge data: 3 × 3 #> from to x #> #> 1 1 2 (7 51, 7 52) #> 2 1 3 (7 51, 8 52) #> 3 2 3 (8 52, 7 52) # Using character encoded from and to columns. nodes$name = c(\"city\", \"village\", \"farm\") edges$from = c(\"city\", \"city\", \"farm\") edges$to = c(\"village\", \"farm\", \"village\") sfnetwork(nodes, edges, node_key = \"name\") #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> → Checking edge geometry types ... #> ✔ All edges have geometry type LINESTRING #> → Checking coordinate reference system equality ... #> ✔ Nodes and edges have the same crs #> → Checking coordinate precision equality ... #> ✔ Nodes and edges have the same precision #> → Checking if geometries match ... #> ✔ Node locations match edge boundaries #> ✔ Spatial network structure is valid #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed acyclic simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 2 (active) #> x name #> #> 1 (7 51) city #> 2 (7 52) village #> 3 (8 52) farm #> # #> # Edge data: 3 × 3 #> from to x #> #> 1 1 2 (7 51, 7 52) #> 2 1 3 (7 51, 8 52) #> 3 3 2 (8 52, 7 52) # Spatially implicit edges. sfnetwork(nodes, edges, edges_as_lines = FALSE) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> ✔ Spatial network structure is valid #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed acyclic simple graph with 1 component and spatially implicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 2 (active) #> x name #> #> 1 (7 51) city #> 2 (7 52) village #> 3 (8 52) farm #> # #> # Edge data: 3 × 2 #> from to #> #> 1 1 2 #> 2 1 3 #> 3 3 2 # Store edge lenghts in a column named 'length'. sfnetwork(nodes, edges, compute_length = TRUE) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> → Checking edge geometry types ... #> ✔ All edges have geometry type LINESTRING #> → Checking coordinate reference system equality ... #> ✔ Nodes and edges have the same crs #> → Checking coordinate precision equality ... #> ✔ Nodes and edges have the same precision #> → Checking if geometries match ... #> ✔ Node locations match edge boundaries #> ✔ Spatial network structure is valid #> # A sfnetwork: 3 nodes and 3 edges #> # #> # A directed acyclic simple graph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7 ymin: 51 xmax: 8 ymax: 52 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 3 × 2 (active) #> x name #> #> 1 (7 51) city #> 2 (7 52) village #> 3 (8 52) farm #> # #> # Edge data: 3 × 4 #> from to x length #> [m] #> 1 1 2 (7 51, 7 52) 111195. #> 2 1 3 (7 51, 8 52) 130977. #> 3 3 2 (8 52, 7 52) 68458."},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork_to_dodgr.html","id":null,"dir":"Reference","previous_headings":"","what":"Conversion between dodgr streetnets and sfnetworks — sfnetwork_to_dodgr","title":"Conversion between dodgr streetnets and sfnetworks — sfnetwork_to_dodgr","text":"dodgr package designed routing directed graphs, known fast computations cost matrices, shortest paths, . sfnetwork, dodgr can chosen routing backend.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork_to_dodgr.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Conversion between dodgr streetnets and sfnetworks — sfnetwork_to_dodgr","text":"","code":"dodgr_to_sfnetwork(x, edges_as_lines = TRUE) sfnetwork_to_dodgr(x, weights = edge_length(), time = FALSE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork_to_dodgr.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Conversion between dodgr streetnets and sfnetworks — sfnetwork_to_dodgr","text":"x conversion sfnetwork: object class dodgr_streetnet. conversion sfnetwork: object class sfnetwork. edges_as_lines created edges spatially explicit, .e. LINESTRING geometries stored geometry list column? Defaults TRUE. weights edge weights stored dodgr streetnet. Evaluated evaluate_weight_spec. default edge_length, computes geographic lengths edges. Dual-weights can provided dual_weights. time provided weights time values? TRUE, stored column named 'time' rather 'd'. Defaults FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork_to_dodgr.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Conversion between dodgr streetnets and sfnetworks — sfnetwork_to_dodgr","text":"conversion sfnetwork: object class sfnetwork. conversion sfnetwork: object class dodgr_streetnet.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetwork_to_dodgr.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Conversion between dodgr streetnets and sfnetworks — sfnetwork_to_dodgr","text":"dodgr package designed directed graphs. provided sfnetwork object undirected, made directed duplicating reversing edge.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetworks-package.html","id":null,"dir":"Reference","previous_headings":"","what":"sfnetworks: Tidy Geospatial Networks — sfnetworks-package","title":"sfnetworks: Tidy Geospatial Networks — sfnetworks-package","text":"Provides tidy approach spatial network analysis, form classes functions enable seamless interaction network analysis package 'tidygraph' spatial analysis package 'sf'.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/sfnetworks-package.html","id":"author","dir":"Reference","previous_headings":"","what":"Author","title":"sfnetworks: Tidy Geospatial Networks — sfnetworks-package","text":"Maintainer: Lucas van der Meer luukvandermeer@live.nl (ORCID) Authors: Lorena Abad lore.abad6@gmail.com (ORCID) Andrea Gilardi andrea.gilardi@unimib.(ORCID) Robin Lovelace r.lovelace@leeds.ac.uk (ORCID)","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/simplify_network.html","id":null,"dir":"Reference","previous_headings":"","what":"Simplify a spatial network — simplify_network","title":"Simplify a spatial network — simplify_network","text":"Construct simple version network. simple network defined network without loop edges multiple edges. loop edge edge starts ends node. Multiple edges different edges node pair.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/simplify_network.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Simplify a spatial network — simplify_network","text":"","code":"simplify_network( x, remove_multiple = TRUE, remove_loops = TRUE, attribute_summary = \"first\", store_original_ids = FALSE, store_original_data = FALSE )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/simplify_network.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Simplify a spatial network — simplify_network","text":"x object class sfnetwork. remove_multiple multiple edges merged one. Defaults TRUE. remove_loops loop edges removed. Defaults TRUE. attribute_summary attributes merged multiple edges summarized? several options, see igraph-attribute-combination details. store_original_ids group merged multiple edges, indices original edges stored attribute new edge, column named .tidygraph_edge_index? line design principles tidygraph. Defaults FALSE. store_original_data group merged multiple edges, data original edges stored attribute new edge, column named .orig_data? line design principles tidygraph. Defaults FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/simplify_network.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Simplify a spatial network — simplify_network","text":"simple network object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/simplify_network.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Simplify a spatial network — simplify_network","text":"merging groups multiple edges single edge, geometry first edge group preserved. order edges can influenced calling arrange simplifying.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/smooth_pseudo_nodes.html","id":null,"dir":"Reference","previous_headings":"","what":"Smooth pseudo nodes — smooth_pseudo_nodes","title":"Smooth pseudo nodes — smooth_pseudo_nodes","text":"Construct smoothed version network iteratively removing pseudo nodes, preserving connectivity network. case directed networks, pseudo nodes nodes one incoming one outgoing edge. undirected networks, pseudo nodes nodes two incident edges. Equality attribute values among two edges can defined additional requirement setting require_equal parameter. Connectivity network preserved concatenating incident edges removed pseudo node.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/smooth_pseudo_nodes.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Smooth pseudo nodes — smooth_pseudo_nodes","text":"","code":"smooth_pseudo_nodes( x, protect = NULL, require_equal = NULL, attribute_summary = \"ignore\", store_original_ids = FALSE, store_original_data = FALSE )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/smooth_pseudo_nodes.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Smooth pseudo nodes — smooth_pseudo_nodes","text":"x object class sfnetwork. protect integer vector edge indices specifying nodes protected removed. Defaults NULL, meaning none nodes protected. require_equal character vector edge column names specifying attributes incident edges pseudo node equal order pseudo node removed? Defaults NULL, meaning attribute equality considered pseudo node removal. attribute_summary attributes concatenated edges summarized? several options, see igraph-attribute-combination details. store_original_ids concatenated edge, indices original edges stored attribute new edge, column named .tidygraph_edge_index? line design principles tidygraph. Defaults FALSE. store_original_data concatenated edge, data original edges stored attribute new edge, column named .orig_data? line design principles tidygraph. Defaults FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/smooth_pseudo_nodes.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Smooth pseudo nodes — smooth_pseudo_nodes","text":"smoothed network object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_centrality.html","id":null,"dir":"Reference","previous_headings":"","what":"Compute spatial centrality measures — spatial_centrality","title":"Compute spatial centrality measures — spatial_centrality","text":"functions collection centrality measures specific spatial networks, form spatial extension centrality measures tidygraph.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_centrality.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Compute spatial centrality measures — spatial_centrality","text":"","code":"centrality_straightness(...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_centrality.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Compute spatial centrality measures — spatial_centrality","text":"... Additional arguments passed functions.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_centrality.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Compute spatial centrality measures — spatial_centrality","text":"numeric vector length number nodes network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_centrality.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Compute spatial centrality measures — spatial_centrality","text":"Just centrality functions tidygraph, functions meant called inside tidygraph verbs mutate filter, network currently worked known thus needed argument function. want use algorithm outside tidygraph framework can use with_graph set context temporarily algorithm evaluated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_centrality.html","id":"functions","dir":"Reference","previous_headings":"","what":"Functions","title":"Compute spatial centrality measures — spatial_centrality","text":"centrality_straightness(): straightness centrality node average ratio Euclidean distance network distance node nodes network. ... forwarded st_network_distance compute network distance matrix. Euclidean distances computed using st_distance.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_centrality.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Compute spatial centrality measures — spatial_centrality","text":"","code":"library(tidygraph, quietly = TRUE) net = as_sfnetwork(roxel, directed = FALSE) net |> activate(nodes) |> mutate(sc = centrality_straightness()) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # An undirected multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Node data: 987 × 2 (active) #> geometry sc #> #> 1 (7.538109 51.95286) 0.738 #> 2 (7.537867 51.95282) 0.737 #> 3 (7.537815 51.95867) 0.776 #> 4 (7.537015 51.95848) 0.767 #> 5 (7.533441 51.95578) 0.768 #> 6 (7.533415 51.95561) 0.768 #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (7.538109 51.95286, 7.537867 51.95… #> 2 3 4 Stiegkamp residential (7.537815 51.95867, 7.537015 51.95… #> 3 5 6 Havixbecker Straße residential (7.533441 51.95578, 7.533467 51.95… #> # ℹ 1,212 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_measures.html","id":null,"dir":"Reference","previous_headings":"","what":"Query spatial edge measures — spatial_edge_measures","title":"Query spatial edge measures — spatial_edge_measures","text":"functions collection edge measures spatial networks.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_measures.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query spatial edge measures — spatial_edge_measures","text":"","code":"edge_azimuth(degrees = FALSE) edge_circuity(Inf_as_NaN = FALSE) edge_length() edge_displacement() edge_segment_count()"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_measures.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Query spatial edge measures — spatial_edge_measures","text":"degrees angle returned degrees instead radians? Defaults FALSE. Inf_as_NaN circuity values loop edges stored NaN instead Inf? Defaults FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_measures.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query spatial edge measures — spatial_edge_measures","text":"numeric vector length number edges graph.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_measures.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Query spatial edge measures — spatial_edge_measures","text":"Just query functions tidygraph, spatial edge measures meant called inside tidygraph verbs mutate filter, network currently worked known thus needed argument function. want use algorithm outside tidygraph framework can use with_graph set context temporarily algorithm evaluated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_measures.html","id":"functions","dir":"Reference","previous_headings":"","what":"Functions","title":"Query spatial edge measures — spatial_edge_measures","text":"edge_azimuth(): angle radians straight line edge startpoint pointing north, straight line edge startpoint edge endpoint. Calculated st_geod_azimuth. Requires geographic CRS. edge_circuity(): ratio length edge linestring geometry versus straight-line distance boundary nodes, described Giacomin & Levinson, 2015. DOI: 10.1068/b130131p. edge_length(): length edge linestring geometry calculated st_length. edges spatially implicit, straight-line distance boundary nodes computed instead, using st_distance. edge_displacement(): straight-line distance two boundary nodes edge, calculated st_distance. edge_segment_count(): number segments contained linestring geometry edge. Segments parts linestring geometry contain interior points.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_measures.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Query spatial edge measures — spatial_edge_measures","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) net = as_sfnetwork(roxel) net |> activate(edges) |> mutate(azimuth = edge_azimuth()) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 6 (active) #> from to name type geometry azimuth #> [rad] #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… -1.83 #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… -1.93 #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… -3.05 #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… 1.32 #> 5 9 10 Annette-von-Droste-Hülsho… seco… (7.532301 51.95559, 7.53… -0.315 #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… 1.00 #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows net |> activate(edges) |> mutate(azimuth = edge_azimuth(degrees = TRUE)) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 6 (active) #> from to name type geometry azimuth #> [°] #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… -105. #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… -111. #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… -175. #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… 75.5 #> 5 9 10 Annette-von-Droste-Hülsho… seco… (7.532301 51.95559, 7.53… -18.0 #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… 57.5 #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows net |> activate(edges) |> mutate(circuity = edge_circuity()) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 6 (active) #> from to name type geometry circuity #> #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… 1 #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… 1 #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… 1.04 #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… 1 #> 5 9 10 Annette-von-Droste-Hülsh… seco… (7.532301 51.95559, 7.53… 1.00 #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… 1.00 #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows net |> activate(edges) |> mutate(length = edge_length()) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 6 (active) #> from to name type geometry length #> [m] #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… 17.2 #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… 58.6 #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… 20.3 #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… 42.7 #> 5 9 10 Annette-von-Droste-Hülshof… seco… (7.532301 51.95559, 7.53… 35.3 #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… 22.9 #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows net |> activate(edges) |> mutate(displacement = edge_displacement()) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 6 (active) #> from to name type geometry displacement #> [m] #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… 17.2 #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… 58.6 #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… 19.5 #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… 42.7 #> 5 9 10 Annette-von-Droste-H… seco… (7.532301 51.95559, 7.53… 35.3 #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… 22.9 #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows net |> activate(edges) |> mutate(n_segs = edge_segment_count()) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 7.522595 ymin: 51.94151 xmax: 7.546705 ymax: 51.96119 #> # Geodetic CRS: WGS 84 #> # #> # Edge data: 1,215 × 6 (active) #> from to name type geometry n_segs #> #> 1 1 2 Hagemanns Kämpken resi… (7.538109 51.95286, 7.53… 1 #> 2 3 4 Stiegkamp resi… (7.537815 51.95867, 7.53… 1 #> 3 5 6 Havixbecker Straße resi… (7.533441 51.95578, 7.53… 3 #> 4 7 8 Holzschuhmacherweg resi… (7.525977 51.95283, 7.52… 1 #> 5 9 10 Annette-von-Droste-Hülshof… seco… (7.532301 51.95559, 7.53… 2 #> 6 11 12 NA foot… (7.543404 51.94779, 7.54… 2 #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (7.538109 51.95286) #> 2 (7.537867 51.95282) #> 3 (7.537815 51.95867) #> # ℹ 984 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_predicates.html","id":null,"dir":"Reference","previous_headings":"","what":"Query edges with spatial predicates — spatial_edge_predicates","title":"Query edges with spatial predicates — spatial_edge_predicates","text":"functions allow interpret spatial relations edges geospatial features directly inside filter mutate calls. functions return logical vector length number edges network. Element vector TRUE whenever chosen spatial predicate applies spatial relation -th edge features y.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_predicates.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query edges with spatial predicates — spatial_edge_predicates","text":"","code":"edge_intersects(y, ...) edge_is_disjoint(y, ...) edge_touches(y, ...) edge_crosses(y, ...) edge_is_within(y, ...) edge_contains(y, ...) edge_contains_properly(y, ...) edge_overlaps(y, ...) edge_equals(y, ...) edge_covers(y, ...) edge_is_covered_by(y, ...) edge_is_within_distance(y, ...) edge_is_nearest(y)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_predicates.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Query edges with spatial predicates — spatial_edge_predicates","text":"y geospatial features test edges , either object class sf sfc. ... Arguments passed corresponding spatial predicate function sf. See geos_binary_pred. argument sparse set.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_predicates.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query edges with spatial predicates — spatial_edge_predicates","text":"logical vector length number edges network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_predicates.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Query edges with spatial predicates — spatial_edge_predicates","text":"See geos_binary_pred details spatial predicate. function edge_is_nearest instead wraps around st_nearest_feature returns TRUE element -th edge nearest edge features y. Just query functions tidygraph, functions meant called inside tidygraph verbs mutate filter, network currently worked known thus needed argument function. want use algorithm outside tidygraph framework can use with_graph set context temporarily algorithm evaluated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_predicates.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Query edges with spatial predicates — spatial_edge_predicates","text":"Note edge_is_within_distance wrapper around st_is_within_distance predicate sf. Hence, based '--crow-flies' distance, distances network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_edge_predicates.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Query edges with spatial predicates — spatial_edge_predicates","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) # Create a network. net = as_sfnetwork(roxel) |> st_transform(3035) # Create a geometry to test against. p1 = st_point(c(4151358, 3208045)) p2 = st_point(c(4151340, 3207520)) p3 = st_point(c(4151756, 3207506)) p4 = st_point(c(4151774, 3208031)) poly = st_multipoint(c(p1, p2, p3, p4)) |> st_cast('POLYGON') |> st_sfc(crs = 3035) # Use predicate query function in a filter call. intersects = net |> activate(edges) |> filter(edge_intersects(poly)) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) plot(st_geometry(net, \"edges\")) plot(st_geometry(intersects, \"edges\"), col = \"red\", lwd = 2, add = TRUE) par(oldpar) # Use predicate query function in a mutate call. net |> activate(edges) |> mutate(disjoint = edge_is_disjoint(poly)) |> select(disjoint) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150707 ymin: 3206375 xmax: 4152366 ymax: 3208564 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 1,215 × 4 (active) #> from to disjoint geometry #> #> 1 1 2 TRUE (4151782 3207612, 4151765 3207609) #> 2 3 4 TRUE (4151784 3208259, 4151728 3208240) #> 3 5 6 FALSE (4151472 3207948, 4151474 3207941, 4151473 3207934, 4151… #> 4 7 8 TRUE (4150948 3207637, 4150990 3207647) #> 5 9 10 FALSE (4151393 3207929, 4151388 3207948, 4151383 3207963) #> 6 11 12 TRUE (4152127 3207036, 4152139 3207043, 4152146 3207047) #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (4151782 3207612) #> 2 (4151765 3207609) #> 3 (4151784 3208259) #> # ℹ 984 more rows # Use predicate query function directly. intersects = with_graph(net, edge_intersects(poly)) head(intersects) #> [1] FALSE FALSE TRUE FALSE TRUE FALSE"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_morphers.html","id":null,"dir":"Reference","previous_headings":"","what":"Morph spatial networks into a different structure — spatial_morphers","title":"Morph spatial networks into a different structure — spatial_morphers","text":"Spatial morphers form spatial add-ons set morphers provided tidygraph. functions change existing structure network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_morphers.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Morph spatial networks into a different structure — spatial_morphers","text":"","code":"to_spatial_contracted( x, ..., simplify = TRUE, compute_centroids = TRUE, attribute_summary = \"ignore\", summarise_attributes = deprecated(), store_original_data = FALSE ) to_spatial_directed(x) to_spatial_explicit(x, ...) to_spatial_implicit(x) to_spatial_mixed(x, directed) to_spatial_neighborhood(x, node, threshold, weights = edge_length(), ...) to_spatial_reversed(x, protect = NULL) to_spatial_shortest_paths(x, ...) to_spatial_simple( x, remove_multiple = TRUE, remove_loops = TRUE, attribute_summary = \"first\", summarise_attributes = deprecated(), store_original_data = FALSE ) to_spatial_smooth( x, protect = NULL, require_equal = NULL, attribute_summary = \"ignore\", summarise_attributes = deprecated(), store_original_data = FALSE ) to_spatial_subdivision(x, protect = NULL, all = FALSE, merge = TRUE) to_spatial_subset(x, ..., subset_by = NULL) to_spatial_transformed(x, ...) to_spatial_unique(x, attribute_summary = \"ignore\", store_original_data = FALSE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_morphers.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Morph spatial networks into a different structure — spatial_morphers","text":"x object class sfnetwork. ... Arguments passed functions. See description morpher details. simplify network simplified contraction? Defaults TRUE. means multiple edges loop edges removed. Multiple edges introduced contraction several connections groups nodes. Loop edges introduced contraction connections within group. Note however setting TRUE also removes multiple edges loop edges already existed contraction. compute_centroids new geometry contracted group nodes centroid group members? Defaults TRUE. set FALSE, geometry first node group used instead, requires considerably less computing time. attribute_summary Whenever groups nodes edges merged single feature morphing, attributes summarized? several options, see igraph-attribute-combination details. summarise_attributes Deprecated, use attribute_summary instead. store_original_data Whenever groups nodes edges merged single feature morphing, data original features stored attribute new feature, column named .orig_data. line design principles tidygraph. Defaults FALSE. directed edges directed? Evaluated evaluate_edge_query. node node neighborhood calculated. Evaluated evaluate_node_query. multiple nodes given, first one used. threshold threshold cost used. nodes reachable within threshold cost reference node included neighborhood. numeric value units given edge weights. Alternatively, units can specified explicitly providing units object. Multiple threshold values may given, result mutliple neigborhoods returned. weights edge weights used travel cost computation. Evaluated evaluate_weight_spec. default edge_length, computes geographic lengths edges. protect Nodes edges protected changed structure. Evaluated evaluate_node_query case nodes evaluate_edge_query case edges. Defaults NULL, meaning features protected. remove_multiple multiple edges merged one. Defaults TRUE. remove_loops loop edges removed. Defaults TRUE. require_equal attributes incident edges equal order pseudo node removed? Evaluated dplyr_tidy_select argument. Defaults NULL, meaning attribute equality considered pseudo node removal. edges subdivided interior points? set FALSE, edges subdivided interior points share location interior boundary point (node) edges table. Defaults FALSE. default sfnetworks rounds coordinates 12 decimal places determine spatial equality. can influence behavior explicitly setting precision network using st_set_precision. merge multiple subdivision points location merged single node, subdivision points location existing node merged node? Defaults TRUE. set FALSE, subdivision point added separately new node network. default sfnetworks rounds coordinates 12 decimal places determine spatial equality. can influence behavior explicitly setting precision network using st_set_precision. subset_by Whether create subgraphs based nodes edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_morphers.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Morph spatial networks into a different structure — spatial_morphers","text":"Either morphed_sfnetwork, list one sfnetwork objects, morphed_tbl_graph, list one tbl_graph objects. See description morpher details.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_morphers.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Morph spatial networks into a different structure — spatial_morphers","text":"Morphers meant called directly. Instead, called inside morph verb change network structure temporarily. Depending chosen morpher, results list one network objects. Single elements list can extracted directly new network calling morpher inside convert verb instead, make changes lasting rather temporary. also possible create morphers. See documentation morph requirements custom morphers.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_morphers.html","id":"functions","dir":"Reference","previous_headings":"","what":"Functions","title":"Morph spatial networks into a different structure — spatial_morphers","text":"to_spatial_contracted(): Combine groups nodes single node per group. ... forwarded group_by create groups. centroid group used default geometry contracted node. edges spatially explicit, edge geometries updated accordingly valid spatial network structure preserved. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_directed(): Make network directed direction given linestring geometries edges. Differs to_directed, makes network directed based node indices given columns. undirected networks indices may correspond endpoints linestring geometries. Returns morphed_sfnetwork containing single element class sfnetwork. morpher requires edges spatially explicit. , use to_directed. to_spatial_explicit(): Create linestring geometries source target nodes edges. edges data can directly converted object class sf using st_as_sf, extra arguments can provided ... forwarded st_as_sf internally. Otherwise, straight lines drawn source target node edge. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_implicit(): Drop edge geometries network. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_mixed(): Construct mixed network edges directed, undirected. practice implemented directed network edges meant undirected duplicated reversed. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_neighborhood(): Limit network spatial neighborhood specific node. ... forwarded st_network_cost compute travel cost specified node nodes network. Returns morphed_sfnetwork may contain multiple elements class sfnetwork, depending number given thresholds. unmorphing first instance node edge data used, node /edge can present multiple neighborhoods. to_spatial_reversed(): Reverse direction edges. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_shortest_paths(): Limit network nodes edges part shortest path two nodes. ... evaluated manner st_network_paths. Returns morphed_sfnetwork may contain multiple elements class sfnetwork, depending number requested paths. unmorphing first instance node edge data used, node /edge can present multiple paths. to_spatial_simple(): Construct simple version network. simple network defined network without loop edges multiple edges. loop edge edge starts ends node. Multiple edges different edges node pair. merging single edge, geometry first edge preserved. order edges can influenced calling arrange simplifying. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_smooth(): Construct smoothed version network iteratively removing pseudo nodes, preserving connectivity network. case directed networks, pseudo nodes nodes one incoming one outgoing edge. undirected networks, pseudo nodes nodes two incident edges. Equality attribute values among two edges can defined additional requirement setting require_equal parameter. Connectivity network preserved concatenating incident edges removed pseudo node. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_subdivision(): Construct subdivision network subdividing edges interior points. Subdividing means new node added edge, edge split two location. Interior points points shape linestring geometry feature endpoints . Returns morphed_sfnetwork containing single element class sfnetwork. morpher requires edges spatially explicit. to_spatial_subset(): Subset network applying spatial filter, .e. filter geometry column based spatial predicate. ... evaluated manner st_filter. Returns morphed_sfnetwork containing single element class sfnetwork. filters attribute column, use to_subgraph. to_spatial_transformed(): Transform geospatial coordinates network different coordinate reference system. ... evaluated manner st_transform. Returns morphed_sfnetwork containing single element class sfnetwork. to_spatial_unique(): Merge nodes equal geometries single node. Returns morphed_sfnetwork containing single element class sfnetwork. default sfnetworks rounds coordinates 12 decimal places determine spatial equality. can influence behavior explicitly setting precision network using st_set_precision.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_morphers.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Morph spatial networks into a different structure — spatial_morphers","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) net = as_sfnetwork(roxel, directed = FALSE) |> st_transform(3035) # Temporary changes with morph and unmorph. net |> activate(edges) |> morph(to_spatial_shortest_paths, from = 1, to = 10) |> mutate(in_paths = TRUE) |> unmorph() #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # An undirected multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150707 ymin: 3206375 xmax: 4152366 ymax: 3208564 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 1,215 × 6 (active) #> from to name type geometry in_paths #> #> 1 1 2 Hagemanns Kämpken resi… (4151782 3207612, 415176… TRUE #> 2 3 4 Stiegkamp resi… (4151784 3208259, 415172… NA #> 3 5 6 Havixbecker Straße resi… (4151472 3207948, 415147… NA #> 4 7 8 Holzschuhmacherweg resi… (4150948 3207637, 415099… NA #> 5 9 10 Annette-von-Droste-Hülsh… seco… (4151393 3207929, 415138… NA #> 6 11 12 NA foot… (4152127 3207036, 415213… NA #> # ℹ 1,209 more rows #> # #> # Node data: 987 × 1 #> geometry #> #> 1 (4151782 3207612) #> 2 (4151765 3207609) #> 3 (4151784 3208259) #> # ℹ 984 more rows # Lasting changes with convert. net |> activate(edges) |> convert(to_spatial_shortest_paths, from = 1, to = 10) #> # A sfnetwork: 22 nodes and 21 edges #> # #> # An unrooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4151383 ymin: 3207582 xmax: 4151782 ymax: 3207963 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Edge data: 21 × 6 (active) #> from to name type geometry .tidygraph_edge_index #> #> 1 1 2 Hagemanns K… resi… (4151782 3207612, 415176… 1 #> 2 2 3 Hagemanns K… resi… (4151765 3207609, 415174… 55 #> 3 3 4 Hagemanns K… resi… (4151747 3207604, 415172… 106 #> 4 4 5 Hagemanns K… resi… (4151710 3207595, 415166… 112 #> 5 5 6 Dorffeldstr… resi… (4151661 3207612, 415166… 780 #> 6 6 7 Dorffeldstr… resi… (4151650 3207655, 415165… 402 #> # ℹ 15 more rows #> # #> # Node data: 22 × 2 #> geometry .tidygraph_node_index #> #> 1 (4151782 3207612) 1 #> 2 (4151765 3207609) 2 #> 3 (4151747 3207604) 106 #> # ℹ 19 more rows"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_predicates.html","id":null,"dir":"Reference","previous_headings":"","what":"Query nodes with spatial predicates — spatial_node_predicates","title":"Query nodes with spatial predicates — spatial_node_predicates","text":"functions allow interpret spatial relations nodes geospatial features directly inside filter mutate calls. functions return logical vector length number nodes network. Element vector TRUE whenever chosen spatial predicate applies spatial relation -th node features y.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_predicates.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query nodes with spatial predicates — spatial_node_predicates","text":"","code":"node_intersects(y, ...) node_is_disjoint(y, ...) node_touches(y, ...) node_is_within(y, ...) node_equals(y, ...) node_is_covered_by(y, ...) node_is_within_distance(y, ...) node_is_nearest(y)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_predicates.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Query nodes with spatial predicates — spatial_node_predicates","text":"y geospatial features test nodes , either object class sf sfc. ... Arguments passed corresponding spatial predicate function sf. See geos_binary_pred. argument sparse set.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_predicates.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query nodes with spatial predicates — spatial_node_predicates","text":"logical vector length number nodes network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_predicates.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Query nodes with spatial predicates — spatial_node_predicates","text":"See geos_binary_pred details spatial predicate. function node_is_nearest instead wraps around st_nearest_feature returns TRUE element -th node nearest node features y. Just query functions tidygraph, functions meant called inside tidygraph verbs mutate filter, network currently worked known thus needed argument function. want use algorithm outside tidygraph framework can use with_graph set context temporarily algorithm evaluated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_predicates.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Query nodes with spatial predicates — spatial_node_predicates","text":"Note node_is_within_distance wrapper around st_is_within_distance predicate sf. Hence, based '--crow-flies' distance, distances network. distances network, use node_distance_to edge lengths weights argument.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_predicates.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Query nodes with spatial predicates — spatial_node_predicates","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) # Create a network. net = as_sfnetwork(roxel) |> st_transform(3035) # Create a geometry to test against. p1 = st_point(c(4151358, 3208045)) p2 = st_point(c(4151340, 3207520)) p3 = st_point(c(4151756, 3207506)) p4 = st_point(c(4151774, 3208031)) poly = st_multipoint(c(p1, p2, p3, p4)) |> st_cast('POLYGON') |> st_sfc(crs = 3035) # Use predicate query function in a filter call. within = net |> activate(nodes) |> filter(node_is_within(poly)) disjoint = net |> activate(nodes) |> filter(node_is_disjoint(poly)) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) plot(net) plot(within, col = \"red\", add = TRUE) plot(disjoint, col = \"blue\", add = TRUE) par(oldpar) # Use predicate query function in a mutate call. net |> activate(nodes) |> mutate(within = node_is_within(poly)) |> select(within) #> # A sfnetwork: 987 nodes and 1215 edges #> # #> # A directed multigraph with 9 components and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4150707 ymin: 3206375 xmax: 4152366 ymax: 3208564 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 987 × 2 (active) #> within geometry #> #> 1 FALSE (4151782 3207612) #> 2 FALSE (4151765 3207609) #> 3 FALSE (4151784 3208259) #> 4 FALSE (4151728 3208240) #> 5 TRUE (4151472 3207948) #> 6 TRUE (4151470 3207929) #> # ℹ 981 more rows #> # #> # Edge data: 1,215 × 5 #> from to name type geometry #> #> 1 1 2 Hagemanns Kämpken residential (4151782 3207612, 4151765 3207609) #> 2 3 4 Stiegkamp residential (4151784 3208259, 4151728 3208240) #> 3 5 6 Havixbecker Straße residential (4151472 3207948, 4151474 3207941,… #> # ℹ 1,212 more rows # Use predicate query function directly. within = with_graph(net, node_is_within(poly)) head(within) #> [1] FALSE FALSE FALSE FALSE TRUE TRUE"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_types.html","id":null,"dir":"Reference","previous_headings":"","what":"Query spatial node types — spatial_node_types","title":"Query spatial node types — spatial_node_types","text":"functions collection node type queries commonly used spatial network analysis, form spatial extension node type queries tidygraph.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_types.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Query spatial node types — spatial_node_types","text":"","code":"node_is_pseudo() node_is_dangling()"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_types.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Query spatial node types — spatial_node_types","text":"logical vector length number nodes network, indicating node type question.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_types.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Query spatial node types — spatial_node_types","text":"Just query functions tidygraph, functions meant called inside tidygraph verbs mutate filter, network currently worked known thus needed argument function. want use algorithm outside tidygraph framework can use with_graph set context temporarily algorithm evaluated.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_types.html","id":"functions","dir":"Reference","previous_headings":"","what":"Functions","title":"Query spatial node types — spatial_node_types","text":"node_is_pseudo(): Pseudo nodes directed networks nodes one incoming one outgoing edge. undirected networks pseudo nodes nodes two incident edges, .e. nodes degree 2. node_is_dangling(): Dangling nodes nodes one incident edge, .e. nodes degree 1.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/spatial_node_types.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Query spatial node types — spatial_node_types","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) # Create a network. net = as_sfnetwork(mozart, \"mst\", directed = FALSE) # Use query function in a filter call. pseudos = net |> activate(nodes) |> filter(node_is_pseudo()) danglers = net |> activate(nodes) |> filter(node_is_dangling()) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) plot(net, main = \"Pseudo nodes\") plot(st_geometry(pseudos), pch = 20, cex = 1.2, col = \"orange\", add = TRUE) plot(net, main = \"Dangling nodes\") plot(st_geometry(danglers), pch = 20, cex = 1.2, col = \"orange\", add = TRUE) par(oldpar) # Use query function in a mutate call. net |> activate(nodes) |> mutate(pseudo = node_is_pseudo(), dangling = node_is_dangling()) #> # A sfnetwork: 17 nodes and 16 edges #> # #> # An unrooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 6 (active) #> name type website geometry pseudo dangling #> #> 1 Mozartkino cinema https:… (4549504 2747309) FALSE TRUE #> 2 Haus für Mozart theat… NA (4549003 2747376) FALSE TRUE #> 3 Mozartsteg/Rudolfskai bus_s… NA (4549589 2747507) TRUE FALSE #> 4 Mozart Denkmal artwo… NA (4549387 2747514) TRUE FALSE #> 5 Mozartsteg/Rudolfskai bus_s… NA (4549491 2747551) FALSE FALSE #> 6 Mozartsteg bridge NA (4549473 2747624) TRUE FALSE #> # ℹ 11 more rows #> # #> # Edge data: 16 × 3 #> from to geometry #> #> 1 1 3 (4549504 2747309, 4549589 2747507) #> 2 2 7 (4549003 2747376, 4549064 2747619) #> 3 3 5 (4549589 2747507, 4549491 2747551) #> # ℹ 13 more rows # Use query function directly. danglers = with_graph(net, node_is_dangling()) head(danglers) #> Mozartkino Haus für Mozart Mozartsteg/Rudolfskai #> TRUE TRUE FALSE #> Mozart Denkmal Mozartsteg/Rudolfskai Mozartsteg #> FALSE FALSE FALSE"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_duplicated.html","id":null,"dir":"Reference","previous_headings":"","what":"Determine duplicated geometries — st_duplicated","title":"Determine duplicated geometries — st_duplicated","text":"Determine duplicated geometries","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_duplicated.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Determine duplicated geometries — st_duplicated","text":"","code":"st_duplicated(x)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_duplicated.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Determine duplicated geometries — st_duplicated","text":"x object class sf sfc.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_duplicated.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Determine duplicated geometries — st_duplicated","text":"logical vector specifying feature x geometry equal previous feature x.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_duplicated.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Determine duplicated geometries — st_duplicated","text":"","code":"library(sf, quietly = TRUE) p1 = st_sfc(st_point(c(1, 1))) p2 = st_sfc(st_point(c(0, 0))) p3 = st_sfc(st_point(c(1, 0))) st_duplicated(c(p1, p2, p2, p3, p1)) #> [1] FALSE FALSE TRUE FALSE TRUE"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_match.html","id":null,"dir":"Reference","previous_headings":"","what":"Geometry matching — st_match","title":"Geometry matching — st_match","text":"Geometry matching","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_match.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Geometry matching — st_match","text":"","code":"st_match(x)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_match.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Geometry matching — st_match","text":"x object class sf sfc.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_match.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Geometry matching — st_match","text":"numeric vector giving feature x position first feature x equal geometry.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_match.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Geometry matching — st_match","text":"","code":"library(sf, quietly = TRUE) p1 = st_sfc(st_point(c(1, 1))) p2 = st_sfc(st_point(c(0, 0))) p3 = st_sfc(st_point(c(1, 0))) st_match(c(p1, p2, p2, p3, p1)) #> [1] 1 2 2 3 1"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_bbox.html","id":null,"dir":"Reference","previous_headings":"","what":"Compute the bounding box of a spatial network — st_network_bbox","title":"Compute the bounding box of a spatial network — st_network_bbox","text":"spatial network specific bounding box creator, returning combined bounding box nodes edges network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_bbox.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Compute the bounding box of a spatial network — st_network_bbox","text":"","code":"st_network_bbox(x, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_bbox.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Compute the bounding box of a spatial network — st_network_bbox","text":"x object class sfnetwork. ... Arguments passed st_bbox.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_bbox.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Compute the bounding box of a spatial network — st_network_bbox","text":"bounding box network object class bbox.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_bbox.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Compute the bounding box of a spatial network — st_network_bbox","text":"See st_bbox details.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_bbox.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Compute the bounding box of a spatial network — st_network_bbox","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) # Create a network. n1 = st_point(c(8, 51)) n2 = st_point(c(7, 51.5)) n3 = st_point(c(8, 52)) n4 = st_point(c(9, 51)) e1 = st_sfc(st_linestring(c(n1, n2, n3))) nodes = st_as_sf(c(st_sfc(n1), st_sfc(n3), st_sfc(n4))) edges = st_as_sf(e1) edges$from = 1 edges$to = 2 net = sfnetwork(nodes, edges) #> → Checking node geometry types ... #> ✔ All nodes have geometry type POINT #> → Checking edge geometry types ... #> ✔ All edges have geometry type LINESTRING #> → Checking coordinate reference system equality ... #> ✔ Nodes and edges have the same crs #> → Checking coordinate precision equality ... #> ✔ Nodes and edges have the same precision #> → Checking if geometries match ... #> ✔ Node locations match edge boundaries #> ✔ Spatial network structure is valid # Create bounding boxes for nodes, edges and the whole network. node_bbox = st_bbox(activate(net, \"nodes\")) node_bbox #> xmin ymin xmax ymax #> 8 51 9 52 edge_bbox = st_bbox(activate(net, \"edges\")) edge_bbox #> xmin ymin xmax ymax #> 7 51 8 52 net_bbox = st_network_bbox(net) net_bbox #> xmin ymin xmax ymax #> 7 51 9 52 # Plot. plot(net, lwd = 2, cex = 4, main = \"Element bounding boxes\") plot(st_as_sfc(node_bbox), border = \"orange\", lty = 2, lwd = 4, add = TRUE) plot(st_as_sfc(edge_bbox), border = \"skyblue\", lty = 2, lwd = 4, add = TRUE) plot(net, lwd = 2, cex = 4, main = \"Network bounding box\") plot(st_as_sfc(net_bbox), border = \"orange\", lty = 2, lwd = 4, add = TRUE) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_blend.html","id":null,"dir":"Reference","previous_headings":"","what":"Blend spatial points into a spatial network — st_network_blend","title":"Blend spatial points into a spatial network — st_network_blend","text":"Blending point network combined process first projecting point onto nearest point nearest edge network, subdividing edge location projected point, finally adding projected point node network. location projected point equal existing node network, attributes point joined node, instead adding new node.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_blend.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Blend spatial points into a spatial network — st_network_blend","text":"","code":"st_network_blend(x, y, tolerance = Inf, ignore_duplicates = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_blend.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Blend spatial points into a spatial network — st_network_blend","text":"x object class sfnetwork. y spatial features blended, either object class sf sfc, POINT geometries. tolerance tolerance distance used. features least close network tolerance distance blended. non-negative number preferably given object class units. Otherwise, assumed unit meters. set Inf features blended. Defaults Inf. ignore_duplicates multiple points y projected location, first one blended network. happen others? argument set TRUE, ignored. argument set FALSE, added isolated nodes returned network. Nodes equal locations can merged using spatial morpher to_spatial_unique. Defaults TRUE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_blend.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Blend spatial points into a spatial network — st_network_blend","text":"blended network object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_blend.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Blend spatial points into a spatial network — st_network_blend","text":"projected location given point intersects one edge, blended first edges. Edges connected blending locations. Use spatial morpher to_spatial_subdivision . determine projected point equal existing node, determine multiple projected points equal , sfnetworks default rounds coordinates 12 decimal places. can influence behavior explicitly setting precision network using st_set_precision.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_blend.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Blend spatial points into a spatial network — st_network_blend","text":"Due internal rounding rational numbers, may occur intersection point line point evaluated actually intersecting line designated algorithm. Instead, intersection point lies tiny-bit away edge. Therefore, recommended set tolerance small number (example 1e-5) even want blend points intersect edge.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_blend.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Blend spatial points into a spatial network — st_network_blend","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) # Create a spatial network. n1 = st_point(c(0, 0)) n2 = st_point(c(1, 0)) n3 = st_point(c(2, 0)) e1 = st_sfc(st_linestring(c(n1, n2)), crs = 3857) e2 = st_sfc(st_linestring(c(n2, n3)), crs = 3857) net = as_sfnetwork(c(e1, e2)) # Create spatial points to blend in. p1 = st_sfc(st_point(c(0.5, 0.1))) p2 = st_sfc(st_point(c(0.5, -0.2))) p3 = st_sfc(st_point(c(1, 0.2))) p4 = st_sfc(st_point(c(1.75, 0.2))) p5 = st_sfc(st_point(c(1.25, 0.1))) pts = st_sf(foo = letters[1:5], geometry = c(p1, p2, p3, p4, p5), crs = 3857) # Blend all points into the network. b1 = st_network_blend(net, pts) #> Warning: `st_network_blend()` did not blend in all requested features. #> ! Some projected features have duplicated locations, of which all but the first #> one are ignored. #> ℹ If you want to add duplicated projection locations as isolated nodes instead, #> set `ignore_duplicates` to `FALSE`. b1 #> # A sfnetwork: 6 nodes and 5 edges #> # #> # A rooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 2 ymax: 0 #> # Projected CRS: WGS 84 / Pseudo-Mercator #> # #> # Node data: 6 × 2 (active) #> x foo #> #> 1 (0 0) NA #> 2 (1 0) c #> 3 (2 0) NA #> 4 (0.5 0) a #> 5 (1.25 0) e #> 6 (1.75 0) d #> # #> # Edge data: 5 × 3 #> from to x #> #> 1 1 4 (0 0, 0.5 0) #> 2 4 2 (0.5 0, 1 0) #> 3 2 5 (1 0, 1.25 0) #> # ℹ 2 more rows plot(net) plot(st_geometry(pts), pch = 20, col = \"orange\", add = TRUE) plot(b1) plot(st_geometry(pts), pch = 20, col = \"orange\", add = TRUE) # Blend points within a tolerance distance. tol = units::set_units(0.1, \"m\") b2 = st_network_blend(net, pts, tolerance = tol) b2 #> # A sfnetwork: 5 nodes and 4 edges #> # #> # A rooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 2 ymax: 0 #> # Projected CRS: WGS 84 / Pseudo-Mercator #> # #> # Node data: 5 × 2 (active) #> x foo #> #> 1 (0 0) NA #> 2 (1 0) NA #> 3 (2 0) NA #> 4 (0.5 0) a #> 5 (1.25 0) e #> # #> # Edge data: 4 × 3 #> from to x #> #> 1 1 4 (0 0, 0.5 0) #> 2 4 2 (0.5 0, 1 0) #> 3 2 5 (1 0, 1.25 0) #> # ℹ 1 more row plot(net) plot(st_geometry(pts), pch = 20, col = \"orange\", add = TRUE) plot(b2) plot(st_geometry(pts), pch = 20, col = \"orange\", add = TRUE) # Add points with duplicated projected location as isolated nodes. b3 = st_network_blend(net, pts, ignore_duplicates = FALSE) #> Warning: `st_network_blend()` created isolated nodes. #> ! Some projected features have duplicated locations, of which all but the first #> one are added as isolated nodes to the network. #> ℹ If you want to ignore duplicated projection locations instead, set #> `ignore_duplicates` to `TRUE`. b3 #> # A sfnetwork: 7 nodes and 5 edges #> # #> # A rooted forest with 2 trees and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 2 ymax: 0 #> # Projected CRS: WGS 84 / Pseudo-Mercator #> # #> # Node data: 7 × 2 (active) #> x foo #> #> 1 (0 0) NA #> 2 (1 0) c #> 3 (2 0) NA #> 4 (0.5 0) a #> 5 (1.25 0) e #> 6 (1.75 0) d #> # ℹ 1 more row #> # #> # Edge data: 5 × 3 #> from to x #> #> 1 1 4 (0 0, 0.5 0) #> 2 4 2 (0.5 0, 1 0) #> 3 2 5 (1 0, 1.25 0) #> # ℹ 2 more rows par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_cost.html","id":null,"dir":"Reference","previous_headings":"","what":"Compute a cost matrix of a spatial network — st_network_cost","title":"Compute a cost matrix of a spatial network — st_network_cost","text":"Compute total travel costs shortest paths nodes spatial network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_cost.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Compute a cost matrix of a spatial network — st_network_cost","text":"","code":"st_network_cost( x, from = node_ids(x), to = node_ids(x), weights = edge_length(), direction = \"out\", Inf_as_NaN = FALSE, router = getOption(\"sfn_default_router\", \"igraph\"), use_names = FALSE, ... ) st_network_distance( x, from = node_ids(x), to = node_ids(x), direction = \"out\", Inf_as_NaN = FALSE, router = getOption(\"sfn_default_router\", \"igraph\"), use_names = FALSE, ... )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_cost.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Compute a cost matrix of a spatial network — st_network_cost","text":"x object class sfnetwork. nodes paths start. Evaluated evaluate_node_query. default, nodes network included. nodes paths end. Evaluated evaluate_node_query. default, nodes network included. weights edge weights used shortest path calculation. Evaluated evaluate_weight_spec. default edge_length, computes geographic lengths edges. direction direction travel. Defaults '', meaning direction given network followed costs computed points given argument . May set '', meaning opposite direction followed costs computed towards points given argument . May also set '', meaning network considered undirected. argument ignored undirected networks. Inf_as_NaN cost values unconnected nodes stored NaN instead Inf? Defaults FALSE. router routing backend use cost matrix computation. Currently supported options 'igraph' 'dodgr'. See Details. use_names column named name present nodes table, names used row column names matrix, instead node indices? Defaults FALSE. Ignored nodes table column named name. ... Additional arguments passed underlying function chosen routing backend. See Details.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_cost.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Compute a cost matrix of a spatial network — st_network_cost","text":"n times m numeric matrix n length argument, m length argument.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_cost.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Compute a cost matrix of a spatial network — st_network_cost","text":"sfnetworks package implement routing algorithms compute cost matrices. Instead, relies \"routing backends\", .e. R packages implemented algorithms. Currently two different routing backends supported. default igraph. package supports many--many cost matrix computation distances function. igraph router support dual-weighted routing. second supported routing backend dodgr. package supports many--many cost matrix computation dodgr_dists function. also supports dual-weighted routing. dodgr package conditional dependency sfnetworks. Using dodgr router requires dodgr package installed. default router can changed setting sfn_default_router option.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_cost.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Compute a cost matrix of a spatial network — st_network_cost","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) net = as_sfnetwork(roxel, directed = FALSE) |> st_transform(3035) # Compute the network cost matrix between node pairs. # Note that geographic edge length is used as edge weights by default. st_network_cost(net, from = c(495, 121), to = c(495, 121)) #> Units: [m] #> 495 121 #> 495 0.0000 669.8584 #> 121 669.8584 0.0000 # st_network_distance is a synonym for st_network_cost with default weights. st_network_distance(net, from = c(495, 121), to = c(495, 121)) #> Units: [m] #> 495 121 #> 495 0.0000 669.8584 #> 121 669.8584 0.0000 # Compute the network cost matrix between spatial point features. # These are snapped to their nearest node before computing costs. p1 = st_geometry(net, \"nodes\")[495] + st_sfc(st_point(c(50, -50))) st_crs(p1) = st_crs(net) p2 = st_geometry(net, \"nodes\")[121] + st_sfc(st_point(c(-10, 100))) st_crs(p2) = st_crs(net) st_network_cost(net, from = c(p1, p2), to = c(p1, p2)) #> Units: [m] #> 477 216 #> 477 0.0000 586.0027 #> 216 586.0027 0.0000 # Use a node type query function to specify origins and/or destinations. st_network_cost(net, from = 499, to = node_is_connected(499)) #> Units: [m] #> 1 2 3 4 5 6 7 8 #> 499 873.5359 890.7781 454.4463 395.7263 370.4559 390.7588 1026.71 1069.539 #> 9 10 11 12 13 14 15 16 #> 499 351.2491 315.9345 1725.54 1714.639 546.2603 586.0429 1199.573 1264.65 #> 17 18 19 20 21 22 23 24 #> 499 229.0913 146.2307 501.4977 436.5051 1504.114 1547.867 1062.55 1110.435 #> 25 26 27 28 29 30 31 32 #> 499 1685.448 1783.653 1070.348 999.1489 1393.529 1413.081 1463.669 1467.738 #> 33 34 35 36 37 38 39 40 #> 499 1718.225 1114.448 1155.142 350.4034 286.7882 565.7165 504.8286 1073.319 #> 41 42 43 44 45 46 47 48 #> 499 1133.801 1112.113 1094.508 1295.444 1305.242 95.07722 76.55244 609.2674 #> 49 50 51 52 53 54 55 56 #> 499 649.819 1930.735 1975.236 1017.045 1005.434 619.4744 701.2313 1317.5 #> 57 58 59 60 61 62 63 64 #> 499 1279.314 1177.133 1090.709 769.5344 776.8791 2091.375 2107.009 1120.121 #> 65 66 67 68 69 70 71 72 #> 499 1219.012 708.9491 695.864 624.1239 1333.874 1319.891 1431.409 1392.694 #> 73 74 75 76 77 78 79 80 #> 499 666.0641 657.6485 792.224 808.1169 811.165 802.1964 1867.797 1920.723 #> 81 82 83 84 85 86 87 88 #> 499 1098.61 783.9091 774.7897 302.3767 323.6855 935.1098 949.0832 494.1647 #> 89 90 91 92 93 94 95 96 #> 499 504.297 1293.018 1322.872 275.5442 236.9272 1601.008 1614.451 1500.923 #> 97 98 99 100 101 102 103 104 #> 499 1595.084 1207.889 1262.779 226.1544 216.135 1966.568 1933.414 756.4774 #> 105 106 107 108 109 110 111 112 #> 499 803.9649 879.5799 220.5792 1304.358 1390.99 265.8059 811.4966 796.2788 #> 113 114 115 116 117 118 119 120 #> 499 559.156 583.344 700.3703 685.7695 805.7022 942.5596 794.1741 724.5884 #> 121 122 123 124 125 126 127 128 #> 499 1566.494 1599.482 718.8359 712.5437 1790.244 1748.59 2085.279 2197.803 #> 129 130 131 132 133 134 135 136 #> 499 395.7898 448.1837 1825.287 1833.432 1491.258 1661.668 1614.675 1282.273 #> 137 138 139 140 141 142 143 144 #> 499 1218.446 468.3246 528.289 926.9009 986.05 1102.083 997.9613 1179.76 #> 145 146 147 148 149 150 151 152 #> 499 1147.025 1195.977 1468.043 1502.416 787.5854 785.1026 1056.22 1042.937 #> 153 154 155 156 157 158 159 160 #> 499 729.0523 742.5479 1897.167 1978.351 1807.294 1811.299 401.87 902.3921 #> 161 162 163 164 165 166 167 168 #> 499 898.7296 734.3901 728.0375 839.2339 859.1539 172.8241 78.90951 1102.744 #> 169 170 171 172 173 174 175 176 #> 499 1137.421 1023.595 1050.153 847.2224 843.043 786.3771 716.9932 762.0341 #> 177 178 179 180 181 182 183 184 #> 499 774.468 871.3191 863.3708 1362.292 743.014 751.3349 695.3414 1242.037 #> 185 186 187 188 189 190 191 192 #> 499 1150.204 1033.579 1995.184 2092.136 1414.947 1329.204 771.6893 353.9481 #> 193 194 195 196 197 198 199 200 #> 499 382.0394 1024.415 192.3578 841.323 1765.551 1696.855 1677.519 1799.113 #> 201 202 203 204 205 206 207 208 #> 499 709.3068 681.6219 1038.633 570.1891 575.9745 798.4155 963.8589 971.197 #> 209 210 211 212 213 214 215 216 #> 499 1044.179 614.7124 1118.057 1073.895 932.7385 935.7969 1415.223 1477.426 #> 217 218 219 220 221 222 223 224 #> 499 1022.83 951.6681 235.4296 812.5915 790.7162 1788.932 1832.053 1491.298 #> 225 226 227 228 229 230 231 232 #> 499 1546.143 1461.208 758.766 707.9535 1142.598 1163.339 185.434 278.5785 #> 233 234 235 236 237 238 239 240 #> 499 706.7727 719.7412 687.0465 1149.023 1198.325 1027.229 1100.083 675.5914 #> 241 242 243 244 245 246 247 248 #> 499 504.674 922.5865 813.5493 2064.305 2122.993 560.7615 607.6151 713.3061 #> 249 250 251 252 253 254 255 256 #> 499 1794.755 1837.644 1635.943 1694.008 1244.902 1057.333 443.0819 2183.752 #> 257 258 259 260 261 262 263 264 #> 499 1972.943 533.5964 589.8798 861.3666 802.1954 798.7234 1253.264 1227.5 #> 265 266 267 268 269 270 271 272 #> 499 1245.892 1815.611 870.1464 642.7876 683.6954 572.1387 502.8064 1814.839 #> 273 274 275 276 277 278 279 280 #> 499 1663.84 1712.093 1228.727 400.3016 1137.473 1094.758 1215.157 1272.686 #> 281 282 283 284 285 286 287 288 #> 499 1789.487 716.7609 725.8832 411.8817 353.359 730.4308 745.1619 756.7788 #> 289 290 291 292 293 294 295 296 #> 499 708.4335 927.7335 1182.694 1218.035 161.0607 142.751 601.652 595.1236 #> 297 298 299 300 301 302 303 304 #> 499 634.4614 750.1124 417.9026 689.744 624.7566 333.4458 1394.947 1291.632 #> 305 306 307 308 309 310 311 312 #> 499 1315.717 1265.51 297.5152 283.5637 179.4085 554.4512 705.5108 732.8085 #> 313 314 315 316 317 318 319 320 #> 499 589.1681 1949.918 1992.497 750.6381 886.0768 261.8298 492.9583 816.1173 #> 321 322 323 324 325 326 327 328 #> 499 834.3017 1410.342 1035.057 1085.489 721.3834 731.3224 805.1009 1180.76 #> 329 330 331 332 333 334 335 336 #> 499 1207.386 1167.683 1248.034 1340.535 970.5099 956.9948 624.8838 674.8888 #> 337 338 339 340 341 342 343 344 #> 499 1911.344 1163.983 447.6591 733.1545 1343.526 1977.468 1006.863 1024.421 #> 345 346 347 348 349 350 351 352 #> 499 945.6122 975.5134 1118.792 1432.043 2019.305 2080.727 820.2956 264.9639 #> 353 354 355 356 357 358 359 360 #> 499 1818.028 1805.63 502.6757 465.9777 1988.397 1998.708 1564.662 525.9751 #> 361 362 363 364 365 366 367 368 #> 499 1429.724 1440.644 755.268 664.929 789.7645 771.3454 1359.269 1297.26 #> 369 370 371 372 373 374 375 376 #> 499 682.0728 691.9732 1010.824 989.3609 1146.893 1183.224 590.5177 697.0859 #> 377 378 379 380 381 382 383 384 #> 499 674.318 739.3548 1109.368 1118.758 921.091 2018.192 1074.6 1019.425 #> 385 386 387 388 389 390 391 392 #> 499 1204.666 1206.25 398.1214 338.4697 1389.573 1420.275 1259.403 1219.991 #> 393 394 395 396 397 398 399 400 #> 499 754.4252 1113.349 892.7151 1050.228 1010.697 778.4496 1207.405 1177.858 #> 401 402 403 404 405 406 407 408 #> 499 1639.966 1621.967 2014.519 1980.016 918.1276 213.4413 1323.652 1397.072 #> 409 410 413 414 415 416 417 418 #> 499 857.6601 810.1723 1610.574 1601.54 1477.911 1489.697 572.2393 555.5383 #> 419 420 421 422 423 424 425 426 #> 499 868.4021 731.1656 985.5966 538.034 1372.061 1426.185 428.6591 443.7392 #> 427 428 429 430 431 432 433 434 #> 499 661.5626 701.5294 1049.618 1077.23 70.89328 1015.033 1021.803 799.7069 #> 435 436 437 438 439 440 441 442 #> 499 751.6018 883.5399 863.6545 1162.006 256.1853 1357.605 1320.362 768.7192 #> 443 444 445 446 447 448 449 450 #> 499 995.7929 877.1031 963.6314 1268.604 1884.311 1948.057 790.2483 1079.821 #> 451 452 453 454 455 456 457 458 459 #> 499 614.3545 1037.168 1069.597 1891.7 1846.564 783.111 437.0745 760.5347 726.57 #> 460 461 462 463 464 465 466 467 #> 499 778.6045 541.5726 443.7159 952.8758 931.6692 912.2639 882.1958 787.7835 #> 468 469 470 471 472 473 474 475 #> 499 802.1098 688.9575 895.6581 411.3635 466.1645 950.23 990.4158 1014.519 #> 476 477 478 479 480 481 482 483 #> 499 1112.34 1143.153 1028.215 989.123 677.9555 735.1794 797.7426 765.1309 #> 484 485 486 487 488 489 490 491 #> 499 695.5624 701.8724 1167.1 928.8087 988.4196 998.7653 1299.383 753.645 #> 492 493 494 495 496 497 498 499 500 #> 499 421.6002 1068.93 968.4631 970.601 483.8035 718.4127 26.24319 0 1520.817 #> 501 502 503 504 505 506 507 508 #> 499 1485.882 1432.847 893.7283 916.1384 1410.803 1627.004 533.9837 436.2807 #> 509 510 511 512 513 514 515 516 #> 499 1268.185 2051.565 1914.639 1871.164 959.2229 981.9011 2074.433 2027.182 #> 517 518 519 520 521 522 523 524 #> 499 1685.317 1647.46 1215.887 1156.045 881.2774 798.5854 2038.379 2108.918 #> 525 526 527 528 529 530 531 532 #> 499 1261.569 224.2117 1207.469 1399.596 1013.212 88.66324 948.022 960.0364 #> 533 534 535 536 537 538 539 540 #> 499 1191.677 1194.926 2164.223 1172.918 1034.628 556.6538 1244.016 807.5977 #> 541 542 543 544 545 546 547 548 #> 499 731.7814 947.684 196.3235 1128.433 1070.533 1140.752 1511.707 1005.075 #> 549 550 551 552 553 554 555 556 #> 499 2067.482 127.8707 109.4762 1000.702 961.5858 1484.043 1306.83 704.6871 #> 557 558 559 560 561 562 563 564 #> 499 1227.932 207.7041 699.1399 679.3837 539.6218 574.364 1106.416 230.8235 #> 565 566 567 568 569 570 571 572 #> 499 800.7528 884.0467 675.1501 1207.369 1259.219 723.0045 767.3387 1068.846 #> 573 574 575 576 577 578 579 580 #> 499 1122.525 1647.363 1681.341 1186.372 739.9597 1808.023 1789.649 625.6373 #> 581 582 583 584 585 586 587 588 #> 499 1385.485 1417.895 766.1218 886.6601 787.6855 1542.166 2061.891 2120.105 #> 589 590 591 592 593 594 595 596 #> 499 1291.37 1022.637 974.9281 91.80787 1130.475 1289.641 648.7288 973.0365 #> 597 598 599 600 601 602 603 604 #> 499 435.8192 1124.679 258.3585 1403.557 1382.773 1340.972 477.7011 1211.504 #> 605 606 607 608 609 610 611 612 #> 499 1223.968 850.3333 883.7363 1129.332 2079.183 2016.091 812.6261 1244.609 #> 613 614 615 616 617 618 619 620 #> 499 1407.618 1346.475 2065.414 1288.791 1055.392 1046.531 2117.588 2124.025 #> 621 622 623 624 625 626 627 628 #> 499 1532.199 462.9961 910.2988 876.4129 1193.128 1227.285 1327.896 1816.52 #> 629 630 631 632 633 634 635 636 #> 499 882.195 1687.382 1095.329 1047.081 1158.213 1795.897 1857.86 766.2416 #> 637 638 639 640 641 642 643 644 #> 499 213.0037 203.3805 1934.558 2034.374 1695.136 1909.915 1341.518 1023.916 #> 645 646 647 648 649 650 651 652 #> 499 1030.418 234.2636 965.4015 1313.324 1307.588 933.0533 700.2591 1024.032 #> 653 654 655 656 657 658 659 660 #> 499 978.7125 584.0124 567.3972 508.6142 1508.389 794.7913 751.6468 430.5427 #> 661 662 663 664 665 666 667 668 #> 499 804.8805 773.2935 1463.782 234.5408 276.6258 674.5731 1799.23 953.4275 #> 669 670 671 672 673 674 675 676 #> 499 988.6681 878.1092 1644.942 1108.142 1996.853 504.8011 506.1029 1005.36 #> 677 678 679 680 681 682 683 684 #> 499 968.4955 1163.167 1128.56 792.1399 1027.9 731.6821 641.5734 558.6926 #> 685 686 687 688 689 690 691 692 #> 499 2021.381 1979.748 1267.286 318.0388 302.2884 481.0959 1445.202 2068.889 #> 693 694 695 696 697 698 699 700 #> 499 1840.76 605.962 1277.076 175.2124 1068.836 1101.401 1378.351 704.8933 #> 701 702 703 704 705 706 707 708 #> 499 260.6005 950.3017 2071.935 1158.668 1218.141 1635.553 1047.712 992.2682 #> 709 710 711 712 713 714 715 716 #> 499 877.1812 1114.472 634.1746 732.0683 1226.632 1787.411 1747.728 277.7143 #> 717 718 719 720 721 722 725 726 #> 499 241.2495 1782.547 1823.278 1454.134 1113.028 1320.655 2240.015 818.1879 #> 727 728 729 730 731 732 733 734 #> 499 1948.993 1966.811 1550.956 585.9248 426.6295 1265.835 821.7813 829.7346 #> 735 736 737 738 739 740 741 742 #> 499 1319.394 1274.719 64.04235 757.7018 897.6014 820.0067 1187.91 496.563 #> 743 744 745 746 747 748 749 750 #> 499 1394.653 795.5651 815.0034 1462.494 1239.723 1025 1539.497 432.6431 #> 751 752 753 754 755 756 757 758 #> 499 977.7647 1005.843 953.2313 954.8321 986.1761 1641.337 1563.292 874.2878 #> 759 760 761 762 763 764 765 766 #> 499 219.6254 281.1079 1161.28 910.5567 1445.753 784.7109 764.9534 1046.16 #> 767 768 769 770 771 772 773 774 #> 499 1060.537 1130.048 107.5825 128.8957 1510.703 1208.487 1842.702 671.6482 #> 775 776 777 778 779 780 781 782 #> 499 223.2587 1503.52 868.2117 1552.216 1708.253 1114.04 1823.167 1848.869 #> 783 784 785 786 787 788 789 792 #> 499 1534.451 1018.834 1491.916 488.2741 1226.831 808.946 1374.314 1454.677 #> 793 794 795 796 797 798 799 800 #> 499 307.4676 531.0321 754.7953 1168.374 1295.403 1347.812 1258.33 976.7465 #> 801 802 803 804 805 806 807 808 #> 499 900.8321 1322.963 1346.695 634.8554 694.3095 2002.157 2087.135 949.9061 #> 809 810 811 812 813 814 815 816 #> 499 905.9081 951.311 1277.412 382.5939 1330.126 2069.033 479.8494 473.9061 #> 817 818 819 820 821 822 823 824 #> 499 1639.596 954.6902 1169.867 1682.054 1515.118 1120.421 1250.853 1361.224 #> 825 826 827 828 829 830 831 832 #> 499 1890.399 1672.262 1957.889 70.50971 34.52996 969.0309 822.0138 306.983 #> 833 834 835 836 837 838 839 840 #> 499 1531.468 205.9225 1568.601 443.9537 1910.284 1915.773 527.5518 518.4602 #> 841 842 843 844 845 846 847 848 #> 499 606.6241 2040.418 1013.449 791.2585 381.9352 435.689 506.122 790.6733 #> 849 850 851 852 853 854 855 856 #> 499 207.035 2122.036 263.0604 509.8525 1510.887 319.9886 527.4409 591.1522 #> 857 858 859 860 861 862 863 864 #> 499 530.1348 747.5255 2083.59 736.9322 1332.059 514.678 1369.265 756.3091 #> 865 866 867 868 869 870 871 874 #> 499 919.6888 1763.417 1246.848 1188.992 1066.707 1247.632 889.2161 1191.559 #> 875 876 877 878 879 882 883 884 #> 499 542.3983 928.7408 1277.937 1339.039 1351.035 1557.681 1200.119 1230.94 #> 885 886 887 888 889 890 891 892 #> 499 2016.176 1900.649 2066.189 1119.22 930.375 944.732 915.9002 739.707 #> 893 894 895 896 897 898 899 900 #> 499 2001.624 527.5662 667.6359 2194.16 1292.515 1405.212 1460.603 462.576 #> 901 902 903 904 905 906 907 908 #> 499 137.348 1466.772 2065.266 1379.913 1416.664 1087.82 545.728 903.406 #> 909 910 911 912 913 914 917 918 #> 499 719.0583 805.8947 1817.649 1817.592 1817.655 1413.654 1161.006 2193.013 #> 919 920 921 922 923 924 925 926 #> 499 302.8186 1979.013 532.8349 1128.923 55.19123 1056.032 1537.776 1865.731 #> 927 928 929 930 931 932 933 934 #> 499 355.7311 831.0173 1807.189 1611.983 1150.719 378.8421 344.6649 930.014 #> 935 936 937 938 939 940 941 942 #> 499 973.2863 1221.223 1225.44 1407.8 235.7138 1194.315 778.1079 1162.499 #> 943 944 945 946 947 948 949 950 #> 499 1722.817 1235.034 320.6124 1844.805 599.1794 316.4717 704.0765 2062.273 #> 951 952 953 954 955 956 957 958 #> 499 733.9683 994.0074 1948.294 1482.403 794.4001 1080.372 304.5142 2184.952 #> 959 960 961 962 963 968 969 970 #> 499 511.2051 486.254 1056.011 868.6776 1355.249 249.6424 831.5113 1632.802 #> 971 972 973 974 975 976 977 978 #> 499 1491.589 1880.007 1285.894 839.9045 1510.393 931.8767 742.3722 394.0489 #> 979 980 981 982 983 984 985 986 #> 499 847.7391 90.92951 748.3793 1992.011 1293.83 512.1374 1552.246 1315.151 #> 987 #> 499 1196.929 # Use a spatial edge measure to specify edge weights. # By default edge_length() is used. st_network_cost(net, c(p1, p2), c(p1, p2), weights = edge_displacement()) #> Units: [m] #> 477 216 #> 477 0.0000 583.9299 #> 216 583.9299 0.0000 # Use a column in the edges table to specify edge weights. # This uses tidy evaluation. net |> activate(\"edges\") |> mutate(foo = runif(n(), min = 0, max = 1)) |> st_network_cost(c(p1, p2), c(p1, p2), weights = foo) #> 477 216 #> 477 0.000000 4.625577 #> 216 4.625577 0.000000 # Compute the cost matrix without edge weights. # Here the cost is defined by the number of edges, ignoring space. st_network_cost(net, c(p1, p2), c(p1, p2), weights = NA) #> 477 216 #> 477 0 10 #> 216 10 0 # Use the dodgr router for dual-weighted routing. paths = st_network_cost(net, from = c(p1, p2), to = c(p1, p2), weights = dual_weights(edge_segment_count(), edge_length()), router = \"dodgr\" ) # Not providing any from or to points includes all nodes by default. with_graph(net, graph_order()) # Our network has 701 nodes. #> [1] 987 cost_matrix = st_network_cost(net) dim(cost_matrix) #> [1] 987 987"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_faces.html","id":null,"dir":"Reference","previous_headings":"","what":"Extract the faces of a spatial network — st_network_faces","title":"Extract the faces of a spatial network — st_network_faces","text":"faces spatial network areas bounded edges, without edge crossing . special face outer face, area bounded set edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_faces.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Extract the faces of a spatial network — st_network_faces","text":"","code":"st_network_faces(x, boundary = NULL)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_faces.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Extract the faces of a spatial network — st_network_faces","text":"x object class sfnetwork. boundary boundary used outer face, object class sf sfc containing single POLYGON geometry. Note boundary always larger bounding box network. NULL (default) network bounding box extended 0.1 times diameter used.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_faces.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Extract the faces of a spatial network — st_network_faces","text":"object class sfc POLYGON geometries, feature represents one face network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_faces.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Extract the faces of a spatial network — st_network_faces","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) pts = st_transform(mozart, 3035) net = as_sfnetwork(pts, \"delaunay\") faces = st_network_faces(net) plot(faces, col = sf.colors(length(faces), categorical = TRUE)) plot(net, add = TRUE) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_iso.html","id":null,"dir":"Reference","previous_headings":"","what":"Compute isolines around nodes in a spatial network — st_network_iso","title":"Compute isolines around nodes in a spatial network — st_network_iso","text":"Isolines curves along function constant value. spatial networks, used delineate areas reachable given node within given travel cost. travel cost distance, known isodistances, travel cost time, known isochrones. function finds network nodes lie inside isoline around specified node.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_iso.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Compute isolines around nodes in a spatial network — st_network_iso","text":"","code":"st_network_iso( x, node, cost, weights = edge_length(), ..., delineate = TRUE, ratio = 1, allow_holes = FALSE )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_iso.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Compute isolines around nodes in a spatial network — st_network_iso","text":"x object class sfnetwork. node node around isolines drawn. Evaluated evaluate_node_query. multiple nodes given, first one used. cost constant cost value isoline. numeric value units given edge weights. Alternatively, units can specified explicitly providing units object. Multiple values may given, result multiple isolines drawn. weights edge weights used shortest path calculation. Evaluated evaluate_weight_spec. default edge_length, computes geographic lengths edges. ... Additional arguments passed st_network_cost compute cost matrix specified node nodes network. delineate nodes inside isoline delineated? FALSE, nodes inside isoline returned MULTIPOINT geometry. TRUE, concave hull geometry returned instead. Defaults TRUE. ratio ratio concave hull. Defaults 1, meaning convex hull computed. See st_concave_hull details. Ignored delineate = FALSE. Setting value smaller 1 requires GEOS version least 3.11. allow_holes May concave hull holes? Defaults FALSE. Ignored delineate = FALSE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_iso.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Compute isolines around nodes in a spatial network — st_network_iso","text":"object class sf one row per requested isoline. object contains following columns: cost: constant cost value isoline. geometry: delineate = TRUE, concave hull nodes lie inside isoline. Otherwise, nodes combined single MULTIPOINT geometry.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_iso.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Compute isolines around nodes in a spatial network — st_network_iso","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) center = st_centroid(st_combine(st_geometry(roxel))) net = as_sfnetwork(roxel, directed = FALSE) iso = net |> st_network_iso(node_is_nearest(center), c(1000, 500, 250)) colors = c(\"#fee6ce90\", \"#fdae6b90\", \"#e6550d90\") plot(net) plot(st_geometry(iso), col = colors, add = TRUE) # The level of detail can be increased with the ratio argument. # This requires GEOS >= 3.11. if (compareVersion(sf_extSoftVersion()[[\"GEOS\"]], \"3.11.0\") > -1) { iso = net |> st_network_iso(node_is_nearest(center), c(1000, 500, 250), ratio = 0.3) colors = c(\"#fee6ce90\", \"#fdae6b90\", \"#e6550d90\") plot(net) plot(st_geometry(iso), col = colors, add = TRUE) } par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_join.html","id":null,"dir":"Reference","previous_headings":"","what":"Join two spatial networks based on equality of node geometries — st_network_join","title":"Join two spatial networks based on equality of node geometries — st_network_join","text":"spatial network specific join function makes spatial full join geometries nodes data. Edge data combined using bind_rows semantic, meaning data matched column name values filled NA missing either networks. columns edge data updated match new node indices resulting network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_join.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Join two spatial networks based on equality of node geometries — st_network_join","text":"","code":"st_network_join(x, y, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_join.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Join two spatial networks based on equality of node geometries — st_network_join","text":"x object class sfnetwork. y object class sfnetwork, directly convertible using as_sfnetwork. ... Arguments passed graph_join.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_join.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Join two spatial networks based on equality of node geometries — st_network_join","text":"joined networks object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_join.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Join two spatial networks based on equality of node geometries — st_network_join","text":"default sfnetworks rounds coordinates 12 decimal places determine spatial equality. can influence behavior explicitly setting precision networks using st_set_precision.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_join.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Join two spatial networks based on equality of node geometries — st_network_join","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) # Create two networks. n1 = st_point(c(0, 0)) n2 = st_point(c(1, 0)) n3 = st_point(c(1,1)) n4 = st_point(c(0,1)) e1 = st_sfc(st_linestring(c(n1, n2))) e2 = st_sfc(st_linestring(c(n2, n3))) e3 = st_sfc(st_linestring(c(n3, n4))) neta = as_sfnetwork(c(e1, e2)) netb = as_sfnetwork(c(e2, e3)) # Join the networks based on spatial equality of nodes. net = st_network_join(neta, netb) net #> # A sfnetwork: 4 nodes and 4 edges #> # #> # A directed acyclic multigraph with 1 component and spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 0 ymin: 0 xmax: 1 ymax: 1 #> # CRS: NA #> # #> # Node data: 4 × 1 (active) #> x #> #> 1 (0 0) #> 2 (1 0) #> 3 (1 1) #> 4 (0 1) #> # #> # Edge data: 4 × 3 #> from to x #> #> 1 1 2 (0 0, 1 0) #> 2 2 3 (1 0, 1 1) #> 3 2 3 (1 0, 1 1) #> # ℹ 1 more row # Plot. plot(neta, pch = 15, cex = 2, lwd = 4) plot(netb, col = \"orange\", pch = 18, cex = 2, lty = 3, lwd = 4, add = TRUE) plot(net, cex = 2, lwd = 4) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_paths.html","id":null,"dir":"Reference","previous_headings":"","what":"Find shortest paths between nodes in a spatial network — st_network_paths","title":"Find shortest paths between nodes in a spatial network — st_network_paths","text":"Find shortest paths nodes spatial network","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_paths.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Find shortest paths between nodes in a spatial network — st_network_paths","text":"","code":"st_network_paths( x, from, to = node_ids(x), weights = edge_length(), all = FALSE, k = 1, direction = \"out\", router = getOption(\"sfn_default_router\", \"igraph\"), use_names = FALSE, return_cost = TRUE, return_geometry = TRUE, ... )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_paths.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Find shortest paths between nodes in a spatial network — st_network_paths","text":"x object class sfnetwork. node paths start. Evaluated evaluate_node_query. nodes paths end. Evaluated evaluate_node_query. default, nodes network included. weights edge weights used shortest path calculation. Evaluated evaluate_weight_spec. default edge_length, computes geographic lengths edges. shortest paths returned pair nodes? set FALSE, one shortest path returned pair nodes, even multiple shortest paths exist. Defaults FALSE. k number paths find. Setting integer higher 1 returns shortest path, also next k - 1 loopless shortest paths, may longer shortest path. Currently, supported one--one routing, meaning argument length 1. argument ignored set TRUE. direction direction travel. Defaults '', meaning direction given network followed paths found node given argument . May set '', meaning opposite direction followed paths found towards node given argument . May also set '', meaning network considered undirected. argument ignored undirected networks. router routing backend use shortest path computation. Currently supported options 'igraph' 'dodgr'. See Details. use_names column named name present nodes table, names used encode nodes path, instead node indices? Defaults FALSE. Ignored nodes table column named name. return_cost total cost path computed? Defaults TRUE. return_geometry linestring geometry constructed path? Defaults TRUE. geometries constructed calling st_line_merge linestring geometries edges path. Ignored networks spatially implicit edges. ... Additional arguments passed underlying function chosen routing backend. See Details.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_paths.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Find shortest paths between nodes in a spatial network — st_network_paths","text":"object class sf one row per requested path. return_geometry = FALSE edges spatially implicit, tbl_df returned instead. requested path found, included output empty path. Depending argument settings, output may include following columns: : index node start path. : index node end path. node_path: vector containing indices nodes path, order visit. edge_path: vector containing indices edges path, order visit. path_found: boolean describing requested path exists. cost: total cost path, obtained summing weights visited edges. Included return_cost = TRUE. geometry: geometry path, obtained merging geometries visited edges. Included return_geometry = TRUE network spatially explicit edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_paths.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Find shortest paths between nodes in a spatial network — st_network_paths","text":"sfnetworks package implement routing algorithms find shortest paths. Instead, relies \"routing backends\", .e. R packages implemented algorithms. Currently two different routing backends supported. default igraph. package supports one--many shortest path calculation shortest_paths function. Note multiple nodes supported. multiple nodes given, first one taken. igraph router also supports computation shortest path (see argument) all_shortest_paths function k shortest paths (see k argument) k_shortest_paths function. latter case, one--one routing supported, meaning also one node provided. igraph router support dual-weighted routing. second supported routing backend dodgr. package supports many--many shortest path calculation dodgr_paths function. also supports dual-weighted routing. computation shortest paths k shortest paths currently supported dodgr router. dodgr package conditional dependency sfnetworks. Using dodgr router requires dodgr package installed. default router can changed setting sfn_default_router option.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_paths.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Find shortest paths between nodes in a spatial network — st_network_paths","text":"","code":"library(sf, quietly = TRUE) library(tidygraph, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) net = as_sfnetwork(roxel, directed = FALSE) |> st_transform(3035) # Compute the shortest path between two nodes. # Note that geographic edge length is used as edge weights by default. paths = st_network_paths(net, from = 495, to = 121) paths #> Simple feature collection with 1 feature and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4152025 ymin: 3207259 xmax: 4152176 ymax: 3207843 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 495 121 TRUE 670. (4152096 3207259, 4152130 3… plot(net, col = \"grey\") plot(st_geometry(net)[paths$from], pch = 20, cex = 2, add = TRUE) plot(st_geometry(paths), col = \"orange\", lwd = 3, add = TRUE) # Compute the shortest paths from one to multiple nodes. # This will return a tibble with one row per path. paths = st_network_paths(net, from = 495, to = c(121, 131, 141)) paths #> Simple feature collection with 3 features and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4151719 ymin: 3206620 xmax: 4152176 ymax: 3207957 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 3 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 495 121 TRUE 670. (4152096 3207259, 4152130 … #> 2 495 131 TRUE 1496. (4151720 3206620, 4151719 … #> 3 495 141 TRUE 214. (4152055 3207957, 4151998 … plot(net, col = \"grey\") plot(st_geometry(net)[paths$from], pch = 20, cex = 2, add = TRUE) plot(st_geometry(paths), col = \"orange\", lwd = 3, add = TRUE) # Compute the shortest path between two spatial point features. # These are snapped to their nearest node before finding the path. p1 = st_geometry(net, \"nodes\")[495] + st_sfc(st_point(c(50, -50))) st_crs(p1) = st_crs(net) p2 = st_geometry(net, \"nodes\")[121] + st_sfc(st_point(c(-10, 100))) st_crs(p2) = st_crs(net) paths = st_network_paths(net, from = p1, to = p2) paths #> Simple feature collection with 1 feature and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4152060 ymin: 3207348 xmax: 4152221 ymax: 3207784 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 477 216 TRUE 586. (4152060 3207348, 4152122 3… plot(net, col = \"grey\") plot(c(p1, p2), pch = 20, cex = 2, add = TRUE) plot(st_geometry(net)[paths$from], pch = 4, cex = 2, add = TRUE) plot(st_geometry(paths), col = \"orange\", lwd = 3, add = TRUE) # Use a node type query function to specify destinations. st_network_paths(net, 1, node_is_adjacent(1)) #> Simple feature collection with 4 features and 6 fields (with 1 geometry empty) #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4151754 ymin: 3207609 xmax: 4151785 ymax: 3207727 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 4 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 1 1 TRUE 0 EMPTY #> 2 1 2 TRUE 17.2 (4151782 3207612, 4151765 3… #> 3 1 393 TRUE 119. (4151757 3207727, 4151754 3… #> 4 1 624 TRUE 2.88 (4151785 3207613, 4151782 3… # Use a spatial edge measure to specify edge weights. # By default edge_length() is used. st_network_paths(net, p1, p2, weights = edge_displacement()) #> Simple feature collection with 1 feature and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4152060 ymin: 3207348 xmax: 4152221 ymax: 3207784 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 7 #> from to node_path edge_path path_found cost geometry #> [m] #> 1 477 216 TRUE 584. (4152060 3207348, 4152122 3… # Use a column in the edges table to specify edge weights. # This uses tidy evaluation. net |> activate(\"edges\") |> mutate(foo = runif(n(), min = 0, max = 1)) |> st_network_paths(p1, p2, weights = foo) #> Simple feature collection with 1 feature and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4152060 ymin: 3207348 xmax: 4152244 ymax: 3207784 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 7 #> from to node_path edge_path path_found cost geometry #> #> 1 477 216 TRUE 4.57 (4152060 3207348, 4152122 … # Compute the shortest paths without edge weights. # This is the path with the fewest number of edges, ignoring space. st_network_paths(net, p1, p2, weights = NA) #> Simple feature collection with 1 feature and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4152060 ymin: 3207348 xmax: 4152180 ymax: 3207784 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 1 × 7 #> from to node_path edge_path path_found cost geometry #> #> 1 477 216 TRUE 10 (4152060 3207348, 4152122 … # Use the dodgr router for many-to-many routing. paths = st_network_paths(net, from = c(1, 2), to = c(10, 11), router = \"dodgr\" ) # Use the dodgr router for dual-weighted routing. paths = st_network_paths(net, from = c(1, 2), to = c(10, 11), weights = dual_weights(edge_segment_count(), edge_length()), router = \"dodgr\" ) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_travel.html","id":null,"dir":"Reference","previous_headings":"","what":"Find the optimal route through a set of nodes in a spatial network — st_network_travel","title":"Find the optimal route through a set of nodes in a spatial network — st_network_travel","text":"Solve travelling salesman problem finding shortest route set nodes visits nodes .","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_travel.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Find the optimal route through a set of nodes in a spatial network — st_network_travel","text":"","code":"st_network_travel( x, nodes, weights = edge_length(), optimizer = \"TSP\", router = getOption(\"sfn_default_router\", \"igraph\"), return_paths = TRUE, use_names = FALSE, return_cost = TRUE, return_geometry = TRUE, ... )"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_travel.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Find the optimal route through a set of nodes in a spatial network — st_network_travel","text":"x object class sfnetwork. nodes Nodes visited. Evaluated evaluate_node_query. weights edge weights used shortest path calculation. Evaluated evaluate_weight_spec. default edge_length, computes geographic lengths edges. optimizer optimization backend use defining optimal visiting order given nodes. Currently supported option 'TSP'. See Details. router routing backend use cost matrix computation path computation. Currently supported options 'igraph' 'dodgr'. See Details. return_paths defining optimal visiting order nodes, actual paths connecting nodes computed returned? Defaults TRUE. set FALSE, vector indices visiting order returned instead, index specifying position visited node argument. use_names column named name present nodes table, names used encode nodes route, instead node indices? Defaults FALSE. Ignored nodes table column named name return_paths = FALSE. return_cost total cost path two subsequent nodes computed? Defaults TRUE. Ignored return_paths = FALSE. return_geometry linestring geometry constructed path two subsequent nodes? Defaults TRUE. geometries constructed calling st_line_merge linestring geometries edges path. Ignored return_paths = FALSE networks spatially implicit edges. ... Additional arguments passed underlying function chosen optimization backend. See Details.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_travel.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Find the optimal route through a set of nodes in a spatial network — st_network_travel","text":"object class sf one row per leg optimal route, containing path leg. return_geometry = FALSE edges spatially implicit, tbl_df returned instead. See documentation st_network_paths details. return_paths = FALSE, vector indices visiting order returned, index specifying position visited node argument.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_travel.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Find the optimal route through a set of nodes in a spatial network — st_network_travel","text":"sfnetworks package implement route optimization algorithms. Instead, relies \"optimization backends\", .e. R packages implemented algorithms. Currently supported optimization backend solve travelling salesman problem TSP package, provides solve_TSP function task. input route optimization algorithms matrix containing travel costs nodes visited. computed using st_network_cost. output route optimization algorithms optimal order given nodes visited. compute actual paths connect nodes order, st_network_paths function used. cost matrix computation shortest paths computation allow specify \"routing backend\", .e. R package implements algorithms solve tasks. See documentation corresponding functions details.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_network_travel.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Find the optimal route through a set of nodes in a spatial network — st_network_travel","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) net = as_sfnetwork(roxel, directed = FALSE) |> st_transform(3035) # Compute the optimal route through three nodes. # Note that geographic edge length is used as edge weights by default. route = st_network_travel(net, c(1, 10, 100)) route #> Simple feature collection with 3 features and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4151359 ymin: 3207582 xmax: 4151782 ymax: 3208051 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 3 × 7 #> from to node_path edge_path path_found cost geometry #> * [m] #> 1 100 10 TRUE 89.8 (4151383 3207963, 4151368 … #> 2 10 1 TRUE 667. (4151383 3207963, 4151413 … #> 3 1 100 TRUE 728. (4151359 3208049, 4151364 … plot(net, col = \"grey\") plot(st_geometry(net)[route$from], pch = 20, cex = 2, add = TRUE) plot(st_geometry(route), col = \"orange\", lwd = 3, add = TRUE) # Instead of returning a path we can return a vector of visiting order. st_network_travel(net, c(1, 10, 100), return_paths = FALSE) #> [1] 3 2 1 # Use spatial point features to specify the visiting locations. # These are snapped to their nearest node before finding the path. p1 = st_geometry(net, \"nodes\")[1] + st_sfc(st_point(c(50, -50))) p2 = st_geometry(net, \"nodes\")[10] + st_sfc(st_point(c(-10, 100))) p3 = st_geometry(net, \"nodes\")[100] + st_sfc(st_point(c(-10, 100))) pts = c(p1, p2, p3) st_crs(pts) = st_crs(net) route = st_network_travel(net, pts) route #> Simple feature collection with 3 features and 6 fields #> Geometry type: LINESTRING #> Dimension: XY #> Bounding box: xmin: 4151325 ymin: 3207456 xmax: 4151850 ymax: 3208205 #> Projected CRS: ETRS89-extended / LAEA Europe #> # A tibble: 3 × 7 #> from to node_path edge_path path_found cost geometry #> * [m] #> 1 544 107 TRUE 936. (4151364 3208051, 4151370 … #> 2 107 737 TRUE 232. (4151364 3208051, 4151359 … #> 3 737 544 TRUE 1168. (4151378 3208168, 4151369 … plot(net, col = \"grey\") plot(pts, pch = 20, cex = 2, add = TRUE) plot(st_geometry(net)[route$from], pch = 4, cex = 2, add = TRUE) plot(st_geometry(route), col = \"orange\", lwd = 3, add = TRUE) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_project_on_network.html","id":null,"dir":"Reference","previous_headings":"","what":"Project spatial points on a spatial network — st_project_on_network","title":"Project spatial points on a spatial network — st_project_on_network","text":"Project spatial points spatial network","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_project_on_network.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Project spatial points on a spatial network — st_project_on_network","text":"","code":"st_project_on_network(x, network, on = \"edges\")"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_project_on_network.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Project spatial points on a spatial network — st_project_on_network","text":"x spatial features projected, either object class sf sfc, POINT geometries. network object class sfnetwork. component network points projected? Setting 'edges' (default) find nearest point nearest edge point x. Setting 'nodes' find nearest node point x.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_project_on_network.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Project spatial points on a spatial network — st_project_on_network","text":"object x geometries replaced projections.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_project_on_network.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Project spatial points on a spatial network — st_project_on_network","text":"function uses st_nearest_feature find nearest edge node feature x. projecting edges, finds nearest point nearest edge calling st_nearest_points pairwise manner.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_project_on_network.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Project spatial points on a spatial network — st_project_on_network","text":"Due internal rounding rational numbers, even point projected edge may evaluated actually intersecting edge calling st_intersects.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_project_on_network.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Project spatial points on a spatial network — st_project_on_network","text":"","code":"library(sf, quietly = TRUE) oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1)) # Create a spatial network. n1 = st_point(c(0, 0)) n2 = st_point(c(1, 0)) n3 = st_point(c(2, 0)) e1 = st_sfc(st_linestring(c(n1, n2)), crs = 3857) e2 = st_sfc(st_linestring(c(n2, n3)), crs = 3857) net = as_sfnetwork(c(e1, e2)) # Create spatial points to project in. p1 = st_sfc(st_point(c(0.25, 0.1))) p2 = st_sfc(st_point(c(1, 0.2))) p3 = st_sfc(st_point(c(1.75, 0.15))) pts = st_sf(foo = letters[1:3], geometry = c(p1, p2, p3), crs = 3857) # Project points to the edges of the network. p1 = st_project_on_network(pts, net) plot(net) plot(st_geometry(pts), pch = 20, col = \"orange\", add = TRUE) plot(st_geometry(p1), pch = 4, col = \"orange\", add = TRUE) # Project points to the nodes of the network. p2 = st_project_on_network(pts, net, on = \"nodes\") plot(net) plot(st_geometry(pts), pch = 20, col = \"orange\", add = TRUE) plot(st_geometry(p2), pch = 4, col = \"orange\", add = TRUE) par(oldpar)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_round.html","id":null,"dir":"Reference","previous_headings":"","what":"Rounding of geometry coordinates — st_round","title":"Rounding of geometry coordinates — st_round","text":"Rounding geometry coordinates","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_round.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Rounding of geometry coordinates — st_round","text":"","code":"st_round(x, digits = 0)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_round.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Rounding of geometry coordinates — st_round","text":"x object class sf sfc. digits Integer indicating number decimal places used.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_round.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Rounding of geometry coordinates — st_round","text":"object class sf sfc rounded coordinates.","code":""},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/st_round.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Rounding of geometry coordinates — st_round","text":"","code":"library(sf, quietly = TRUE) p1 = st_sfc(st_point(c(1.123, 1.123))) p2 = st_sfc(st_point(c(0.789, 0.789))) p3 = st_sfc(st_point(c(1.123, 0.789))) st_round(st_as_sf(c(p1, p2, p2, p3, p1)), digits = 1) #> Simple feature collection with 5 features and 0 fields #> Geometry type: POINT #> Dimension: XY #> Bounding box: xmin: 0.8 ymin: 0.8 xmax: 1.1 ymax: 1.1 #> CRS: NA #> x #> 1 POINT (1.1 1.1) #> 2 POINT (0.8 0.8) #> 3 POINT (0.8 0.8) #> 4 POINT (1.1 0.8) #> 5 POINT (1.1 1.1)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/subdivide_edges.html","id":null,"dir":"Reference","previous_headings":"","what":"Subdivide edges at interior points — subdivide_edges","title":"Subdivide edges at interior points — subdivide_edges","text":"Construct subdivision network subdividing edges interior points. Subdividing means new node added edge, edge split two location. Interior points points shape linestring geometry feature endpoints .","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/subdivide_edges.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Subdivide edges at interior points — subdivide_edges","text":"","code":"subdivide_edges(x, protect = NULL, all = FALSE, merge = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/subdivide_edges.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Subdivide edges at interior points — subdivide_edges","text":"x object class sfnetwork spatially explicit edges. protect integer vector edge indices specifying edges protected subdivided. Defaults NULL, meaning none edges protected. edges subdivided interior points? set FALSE, edges subdivided interior points share location interior boundary point (node) edges table. Defaults FALSE. merge multiple subdivision points location merged single node, subdivision points location existing node merged node? Defaults TRUE. set FALSE, subdivision point added separately new node network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/subdivide_edges.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Subdivide edges at interior points — subdivide_edges","text":"subdivision x object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/subdivide_edges.html","id":"note","dir":"Reference","previous_headings":"","what":"Note","title":"Subdivide edges at interior points — subdivide_edges","text":"default sfnetworks rounds coordinates 12 decimal places determine spatial equality. can influence behavior explicitly setting precision network using st_set_precision.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/tidygraph_methods.html","id":null,"dir":"Reference","previous_headings":"","what":"tidygraph methods for sfnetworks — tidygraph_methods","title":"tidygraph methods for sfnetworks — tidygraph_methods","text":"Normally tidygraph functions work box sfnetwork objects, cases special treatment needed especially geometry column, requiring specific method.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/tidygraph_methods.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"tidygraph methods for sfnetworks — tidygraph_methods","text":"","code":"# S3 method for class 'sfnetwork' as_tbl_graph(x, ...) # S3 method for class 'sfnetwork' reroute(.data, ...) # S3 method for class 'sfnetwork' morph(.data, ...) # S3 method for class 'morphed_sfnetwork' unmorph(.data, ...)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/tidygraph_methods.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"tidygraph methods for sfnetworks — tidygraph_methods","text":"x object class sfnetwork. ... Arguments passed corresponding tidygraph function. .data object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/tidygraph_methods.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"tidygraph methods for sfnetworks — tidygraph_methods","text":"method as_tbl_graph returns object class tbl_graph. method morph returns morphed_sfnetwork morphed network still spatial, morphed_tbl_graph otherwise. methods return object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/tidygraph_methods.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"tidygraph methods for sfnetworks — tidygraph_methods","text":"See tidygraph documentation. following methods special behavior: reroute: preserve valid spatial network structure, method replace boundaries edge geometries location node edges rerouted . Note goal reverse edges spatial network, reroute simply reverse edge geometries. case recommended use sfnetwork method st_reverse instead. morph: method checks morphed network still spatially embedded nodes. case morphed_sfnetwork returned. , morphed_tbl_graph returned instead. unmorph: method makes sure geometry list column correctly handled unmorphing process.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/validate_network.html","id":null,"dir":"Reference","previous_headings":"","what":"Validate the structure of a sfnetwork — validate_network","title":"Validate the structure of a sfnetwork — validate_network","text":"Validate structure sfnetwork","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/validate_network.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Validate the structure of a sfnetwork — validate_network","text":"","code":"validate_network(x, message = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/validate_network.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Validate the structure of a sfnetwork — validate_network","text":"x object class sfnetwork. message messages printed validation? Defaults TRUE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/validate_network.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Validate the structure of a sfnetwork — validate_network","text":"Nothing network valid. Otherwise, error thrown.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/validate_network.html","id":"details","dir":"Reference","previous_headings":"","what":"Details","title":"Validate the structure of a sfnetwork — validate_network","text":"valid sfnetwork structure means nodes POINT geometries, - edges spatially explicit - edges LINESTRING geometries, nodes edges coordinate reference system coordinate precision, coordinates edge boundaries match coordinates corresponding nodes.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/wrap_igraph.html","id":null,"dir":"Reference","previous_headings":"","what":"Run an igraph function on an sfnetwork object — wrap_igraph","title":"Run an igraph function on an sfnetwork object — wrap_igraph","text":"Since sfnetwork objects inherit igraph objects, igraph function can called sfnetwork. However, function returns network, igraph object rather sfnetwork object. wrap_igraph, function preserve sfnetwork class, checking network returned igraph still valid spatial network structure.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/wrap_igraph.html","id":"ref-usage","dir":"Reference","previous_headings":"","what":"Usage","title":"Run an igraph function on an sfnetwork object — wrap_igraph","text":"","code":"wrap_igraph(.data, .f, ..., .force = FALSE, .message = TRUE)"},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/wrap_igraph.html","id":"arguments","dir":"Reference","previous_headings":"","what":"Arguments","title":"Run an igraph function on an sfnetwork object — wrap_igraph","text":".data object class sfnetwork. .f function igraph package accepts graph first argument, returns graph. ... Arguments passed .f. .force network validity checks skipped? Defaults FALSE, meaning network validity checks executed returning new network. checks guarantee valid spatial network structure. nodes, means POINT geometries. case spatially explicit edges, also checked edges LINESTRING geometries, nodes edges CRS boundary points edges match corresponding node coordinates. checks important, also time consuming. already sure input data meet requirements, checks unnecessary can turned improve performance. .message informational messages (messages neither warnings errors) printed constructing network? Defaults TRUE.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/wrap_igraph.html","id":"value","dir":"Reference","previous_headings":"","what":"Value","title":"Run an igraph function on an sfnetwork object — wrap_igraph","text":"object class sfnetwork.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/reference/wrap_igraph.html","id":"ref-examples","dir":"Reference","previous_headings":"","what":"Examples","title":"Run an igraph function on an sfnetwork object — wrap_igraph","text":"","code":"oldpar = par(no.readonly = TRUE) par(mar = c(1,1,1,1), mfrow = c(1,2)) net = as_sfnetwork(mozart, \"delaunay\", directed = FALSE) mst = wrap_igraph(net, igraph::mst, .message = FALSE) mst #> # A sfnetwork: 17 nodes and 16 edges #> # #> # An unrooted tree with spatially explicit edges #> # #> # Dimension: XY #> # Bounding box: xmin: 4548664 ymin: 2747309 xmax: 4549589 ymax: 2748537 #> # Projected CRS: ETRS89-extended / LAEA Europe #> # #> # Node data: 17 × 4 (active) #> name type website geometry #> #> 1 Mozartkino cinema https://www.mozartki… (4549504 2747309) #> 2 Haus für Mozart theatre NA (4549003 2747376) #> 3 Mozartsteg/Rudolfskai bus_stop NA (4549589 2747507) #> 4 Mozart Denkmal artwork NA (4549387 2747514) #> 5 Mozartsteg/Rudolfskai bus_stop NA (4549491 2747551) #> 6 Mozartsteg bridge NA (4549473 2747624) #> # ℹ 11 more rows #> # #> # Edge data: 16 × 3 #> from to geometry #> #> 1 1 2 (4549504 2747309, 4549003 2747376) #> 2 1 3 (4549504 2747309, 4549589 2747507) #> 3 1 4 (4549504 2747309, 4549387 2747514) #> # ℹ 13 more rows plot(net) plot(mst) par(oldpar)"},{"path":[]},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"network-creation-1-0-0","dir":"Changelog","previous_headings":"","what":"Network creation","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"Creating networks directly linestring geometries now implemented new function create_from_spatial_lines(). as_sfnetwork() method sf objects call function geometries linestrings, forward ... arguments . now also allows already subdivide edges locations interior points shared, setting subdivide = TRUE. Creating networks directly point geometries now implemented new function create_from_spatial_points(). as_sfnetwork() method sf objects call function geometries points, forward ... arguments . now many options create spatial networks directly spatial point data. nodes connected can specified providing logical adjacency matrix addition point data. adjacency matrix can also sparse, e.g. output spatial predicate function sf. Furthermore, sfnetworks can create adjacency matrix according specified method. case, need specify name method. Supported options : complete graph, sequence, minimum spanning tree, delaunay triangulation, Gabriel graph, relative nearest neighbor graph, k nearest neighbor graph. See detailed explanation examples. new function play_geometric() can create random geometric networks. new method as_sfnetwork() create dodgr_streetnet objects {dodgr} package directly sfnetwork. internally calls dodgr_to_sfnetwork(). conversion direction, use sfnetwork_to_dodgr(). now also possible convert sfnetwork objects neighbor lists, using new functions nb_to_sfnetwork() sfnetwork_to_nb(). Neighbor lists sparse adjacency matrices can found e.g. spdep package sf package (output spatial predicate functions). Since interpretation weights argument weights = NULL changed (see ), argument length_as_weight sfnetwork() construction function deprecated. Instead, can now set compute_length = TRUE store edge lengths attribute named length. However, attribute anymore automatically recognized edge weights routing functions.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"routing-1-0-0","dir":"Changelog","previous_headings":"","what":"Routing","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"mentioned , interpretation setting weights = NULL changed routing functions. , edge attribute named weight automatically recognized edge weights, just like igraph. Although convenient, proved confusing since tidygraph, setting weights = NULL meaning. always means edge weights used, matter weight attribute present. now decided (since primarily integrating tidygraph sf) follow tidygraph design choice, meaning weights = NULL always means edge weights used. However, routing functions sfnetworks default longer weights = NULL, weights = edge_length(). Hence, geographic length default edge weight routing functions sfnetworks way edge weights can specified routing functions updated better fit tidy data analysis workflows. can now directly provide edge measure functions value weight argument. also allows provide custom edge measure functions, example ones time-dependent. Furthermore, reference column edges table, can now using tidy evaluation, .e. unquoted column names rather quoted ones. dual weighted routing, new dual_weights() function can used. See full overview possible specification formats. way nodes routing functions can specified updated better fit tidy data analysis workflows. can now directly provide node query node measure functions value arguments. Furthermore, reference column nodes table, can now using tidy evaluation, .e. unquoted column names rather quoted ones. See full overview possible specification formats. now possible choose different “routing backends” router argument routing functions. default routing backend igraph, meaning routing functions igraph package called internally. second supported routing backend now dodgr, call routing functions dodgr package instead. conversion happens internally, user can use functions arguments independent routing engine choose. See details. output returned st_network_paths() restructured. Instead tbl_df, function now return sf object, course path stored linestring geometry. also return total cost path column named cost. Columns node_paths edge_paths renamed node_path edge_path, respectively. boolean column path_found specifies requested path found. , path assigned infinite cost empty geometry. New boolean arguments return_cost return_geometry can set FALSE want cost /geometry columns returned. type argument st_network_paths() deprecated. compute shortest paths instead single shortest path, set = TRUE instead. Support computing simple paths dropped. st_network_paths() function now supports one--one k shortest paths routing. implemented new k argument, can set integer higher 1. use_names argument st_network_paths() now default value FALSE. means even nodes name column, encoded integer indices output object. use_names argument now also added st_network_cost(), letting specify want node names used column rownames returned matrix. Also , defaults FALSE. new function st_network_distance() added synonym st_network_cost() edge weights fixed geographic distance. done provide intuitive network-specific alternative sf::st_distance(). new function st_network_travel() now provides interface TSP package solve traveling salesman problems. requires TSP installed. See example. new function st_network_iso() now implements computation isodistance/isochrone polygons around given source node. first computes neighborhood node, draws concave hull around . See example. concave hulls detailed convex hull, .e. ratio smaller 1, GEOS >= 3.11 required.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"morphers-1-0-0","dir":"Changelog","previous_headings":"","what":"Morphers","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"new morpher to_spatial_unique() allows contract nodes equal spatial locations, specifying attributes combined. new morpher to_spatial_mixed() allows mimic mixed network representation (.e. network directed undirected edges) duplicating reversing edges undirected. new morpher to_spatial_reversed() reverses edges, including linestring geometries. Selected edges can protected reversion using protect argument. new morpher to_spatial_implicit() drops edge geometries. summarise_attributes argument appears several morphers renamed attribute_summary, avoid differences UK US spelling. now, summarise_attributes automatically converted attribute_summary, giving soft deprecation warning. to_spatial_subdivision() morpher now argument . set TRUE, edges subdivided interior point (.e. creating one edge per segment), instead interior points shared multiple edges. to_spatial_subdivision() morpher now argument merge_equal. set TRUE, edges subvidived, subdivision points shared multiple edges merged single node. to_spatial_subdivision() moprher now argument protect, allows protect specified edges subdivided. edges protected can specified several ways, e.g. integer index, using edge query functions, referencing column using tidy evaluation. protect argument to_spatial_smooth() morpher now updated fit better tidy data analysis workflows. Nodes protected smoothed can specified way origins destination nodes routing functions, see . require_equal argument to_spatial_smooth() morpher now updated fit better tidy data analysis workflows. Attributes check equality can now specified using tidy selection. means can also use tidy selection helpers dplyr. to_spatial_contracted() morpher now argument compute_centroid. set FALSE, contracted groups nodes centroid new geometry, simply geometry first node group. can improve performance significantly large networks. simplify argument to_spatial_contracted() morpher now TRUE default value. means default contracted network simplified. to_spatial_shortest_paths() morpher now automatically orders nodes edges returned network match order visited path. argument to_spatial_neighborhood() renamed node. now, automatically converted node, giving soft deprecation warning. to_spatial_neighborhood() morpher now internally calls st_network_cost(), forwards ... arguments . to_spatial_neighborhood() morpher now accepts multiple threshold values, returning one network per specified threshold. internal workers morphers dedicated network cleaning now exported well, make possibe perform data cleaning outside tidygraph framework. simplify_network() to_spatial_simple(), subdivide_edges() to_spatial_subdivision(), smooth_pseudo_nodes() to_spatial_smooth(), contract nodes to_spatial_contracted().","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"spatial-grouping-1-0-0","dir":"Changelog","previous_headings":"","what":"Spatial grouping","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"new function group_spatial_dbscan() provides tidy interface dbscan package group nodes spatially using DBSCAN spatial clustering algorithm, based network distances nodes.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"blending-1-0-0","dir":"Changelog","previous_headings":"","what":"Blending","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"st_network_blend() now allows blend points projected location network, setting ignore_duplicates = FALSE. first one added isolated nodes, can merged using new morpher to_spatial_unique().","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"node-specific-functions-1-0-0","dir":"Changelog","previous_headings":"","what":"Node specific functions","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"new centrality function centrality_straightness() allows compute straightness centrality nodes. new node query function node_is_pseudo() node_is_dangling() allow easily query pseudo (nodes one incoming one outgoing edges) dangling (nodes degree centrality 1) nodes. new node predicate function node_is_nearest() defines node nearest node feature given set spatial features.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"edge-specific-functions-1-0-0","dir":"Changelog","previous_headings":"","what":"Edge specific functions","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"new edge measure function edge_segment_count() returns number segments edge. new edge predicate function edge_is_nearest() defines edge nearest edge feature given set spatial features. make_edges_valid() makes edge geometries fit spatial network structure either replacing endpoints nodes referenced columns (preserve_geometries = FALSE), adding unmatched endpoints new nodes network updating columns (preserve_geometries = TRUE). make_edges_directed() turns undirected network directed network updating columns according direction given linestring geometries. internal worker morpher to_spatial_directed(). make_edges_mixed() duplicates reverses edges directed network undirected. internal worker morpher to_spatial_mixed(). make_edges_explicit() adds geometry column spatially implicit edges. internal worker morpher to_spatial_explicit(). make_edges_implicit() drops geometry column spatially explicit edges. internal worker morpher to_spatial_implicit(). make_edges_follow_indices() updates edge geometries undirected networks match node indices specified columns, case swapped.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"other-new-functions-1-0-0","dir":"Changelog","previous_headings":"","what":"Other new functions","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"new function st_network_faces() allows extract faces spatial network sf object polygons geometries. new function st_project_on_network() replaces geometries sf objects projection spatial network. new functions bind_spatial_nodes() bind_spatial_edges() allow bind additional nodes edges network. spatial alternatives tidygraph::bind_nodes() tidygraph::bind_edges(), handle geometry list columns.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"methods-for-sf-1-0-0","dir":"Changelog","previous_headings":"","what":"Methods for sf","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"now sfnetwork method sf::st_segmentize(), allowing add interior points edge geometries fixed intervals. sfnetwork methods sf::st_intersection(), sf::st_difference(), sf::st_crop() now also work expected undirected networks. st_geometry<- method sfnetwork objects now allows replace node geometries set points, edge geometries set lines. Internally, network structure kept valid replacing endpoints edge geometries (replacing nodes), adding unmatched edge endpoints new nodes network (replacing edges). sf::st_join() method sfnetwork objects now allows multiple matches node. case, node duplicated per additional match, duplicates added isolated nodes resulting network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"upkeep-with-tidygraph-1-0-0","dir":"Changelog","previous_headings":"","what":"Upkeep with tidygraph","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"Functions sfnetworks now work well new concept focused graphs, recently implemented tidygraph. See details. now sfnetwork method tidygraph::reroute(). However, want reverse edges, recommend use morpher to_spatial_reversed() instead, reroute replace endpoints edge geometries, reverse complete linestring geometries. tidygraph verbs morph(), unmorph(), crystallize(), convert() now re-exported sfnetworks, needed anymore load tidygraph explicitly order use spatial morphers. Furthermore, utility function tidygraph::with_graph() now re-exported.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"plotting-1-0-0","dir":"Changelog","previous_headings":"","what":"Plotting","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"plot() method sfnetwork objects now allows different style settings nodes edges, using new node_args edge_args arguments. plot() method sfnetwork objects now allows plot multiple networks top .","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"data-extraction-utilities-1-0-0","dir":"Changelog","previous_headings":"","what":"Data extraction utilities","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"functions node_data() edge_data() extract node edge table, respectively. Nodes always extracted sf object. Edges extracted sf object spatially explicit, regular tbl_df spatially implicit. functions node_ids() edge_ids() extract indices nodes edges, respectively. indices correspond rownumbers node edge tables. functions nearest_nodes() nearest_edges() return respectively nearest nodes nearest edges set spatial features. functions nearest_node_ids() nearest_edge_ids() return respectively indices nearest nodes nearest edges set spatial features. indices correspond rownumbers node edge tables. functions n_nodes() n_edges() return respectively number nodes edges network.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"other-utilities-1-0-0","dir":"Changelog","previous_headings":"","what":"Other utilities","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"Added is_sfnetwork() alias .sfnetwork(). new function validate_network() allows validate spatial network structure sfnetwork object. new function wrap_igraph() allows wrap function igraph returns network, make return sfnetwork object instead igraph object. functions st_duplicated(), st_match() st_round() added spatial variations common base R functions, respectively determining spatial duplicates, geometry matching, coordinate rounding.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"other-updates-1-0-0","dir":"Changelog","previous_headings":"","what":"Other updates","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"determining spatial equality nodes, sfnetworks now default uses 12-digit precision. gives considerable performance improvement especially large networks. Precision can changed explicitly setting coordinate precision using sf::st_set_precision(). messages, warnings errors sfnetworks now raised using cli rlang packages.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"bug-fixes-1-0-0","dir":"Changelog","previous_headings":"","what":"Bug fixes","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"print method now works correctly aligning updates tidygraph. morpher to_spatial_contracted() now correctly handles group indices ordered. plot() method sfnetwork objects now correctly plots networks spatially implicit edges active. st_network_bbox() now also computes bounding boxes networks spatially implicit edges.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"dependencies-1-0-0","dir":"Changelog","previous_headings":"","what":"Dependencies","title":"sfnetworks v1.0.0 “Itzling” (in progress)","text":"minimum required version sf now 1.0-11 minimum required version tidygraph now 1.3.0 minimum required version igraph now 2.1.0 crayon package dependency anymore. Base R packages {methods} {stats} added new dependencies. Additional packages cli, lifecycle, pillar tidyselect added new dependencies.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v064","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.6.4","title":"sfnetworks v0.6.4","text":"CRAN release: 2024-04-09","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"new-features-0-6-4","dir":"Changelog","previous_headings":"","what":"New features","title":"sfnetworks v0.6.4","text":"sfnetwork() construction function now argument message can set FALSE network validity checks print informational messages console. Refs #261.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"maintenance-0-6-4","dir":"Changelog","previous_headings":"","what":"Maintenance","title":"sfnetworks v0.6.4","text":"Code documentation updated needed align changes base R /package dependencies. changes program logic behavior.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v063","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.6.3","title":"sfnetworks v0.6.3","text":"CRAN release: 2023-03-22","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"bug-fixes-0-6-3","dir":"Changelog","previous_headings":"","what":"Bug fixes","title":"sfnetworks v0.6.3","text":"Argument names sfnetwork S3 methods sf::st_geometry(), sf::st_bbox(), sf::st_m_range() sf::st_set_precision() updated consistent corresponding generic functions sf. Arguments active ... removed sfnetwork S3 method sf::st_precision() consistent corresponding generic function sf. Argument active removed sfnetwork S3 method sf::st_crs() consistent -mentioned change regarding sf::st_precision() (since CRS precision can differ nodes edges).","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v062","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.6.2","title":"sfnetworks v0.6.2","text":"CRAN release: 2023-02-26","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"bug-fixes-0-6-2","dir":"Changelog","previous_headings":"","what":"Bug fixes","title":"sfnetworks v0.6.2","text":"to_spatial_contracted() morpher now correctly handles cases undirected networks loop edges created contraction. Refs #237.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"refactoring-0-6-2","dir":"Changelog","previous_headings":"","what":"Refactoring","title":"sfnetworks v0.6.2","text":"to_spatial_contracted() morpher now directly returns original network none contraction groups contain one node.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"other-0-6-2","dir":"Changelog","previous_headings":"","what":"Other","title":"sfnetworks v0.6.2","text":"Umbrella packages tidyverse spatstat longer suggested packages. individual members packages now suggested packages. Updated unit tests.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v061","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.6.1","title":"sfnetworks v0.6.1","text":"CRAN release: 2022-10-27","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"bug-fixes-0-6-1","dir":"Changelog","previous_headings":"","what":"Bug fixes","title":"sfnetworks v0.6.1","text":"Unit tests test_join.R now successfully run also R-devel.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"refactoring-0-6-1","dir":"Changelog","previous_headings":"","what":"Refactoring","title":"sfnetworks v0.6.1","text":"Updated plot algorithm faster efficient. Refs #226.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v060-coerde","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.6.0 “Coerde”","title":"sfnetworks v0.6.0 “Coerde”","text":"CRAN release: 2022-08-19","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"new-features-0-6-0","dir":"Changelog","previous_headings":"","what":"New features","title":"sfnetworks v0.6.0 “Coerde”","text":"Argument summarise_attributes added summarise attribute values concatenated edges. Refs #120. Argument require_equal added specify attributes checked equality removing pseudo node. Refs #124. Argument protect added specify nodes never removed, even pseudo node. Refs #177. Concatenated edges smoothing now allowed cross . Refs #117. Duplicated nodes now accepted argument. Refs #183. Cost matrix output now contains units. Refs #119. Argument direction added specify outbound, inbound edges considered. replaces argument mode igraph::distances(). default “”, “”. undirected networks argument ignored. Edge measure function edge_azimuth() gained argument degrees can set TRUE return angles degrees instead radians. default st_network_paths() now encodes nodes name, whenever name attribute present nodes table. can disabled setting use_names = FALSE. Refs #154. Functions sf::st_precision() sf::st_set_precision() now method sfnetwork objects, coordinate precision can queried set. Refs #209. Functions sf::st_intersection() sf::st_difference() now method sfnetwork objects, networks can spatially clipped. method sf::st_crop() now uses workflow. functions work yet edges undirected networks. Refs #133. Function sf::st_drop_geometry() now generic therefore got sfnetwork method. Several sf functions got sfnetwork method, merely consistent type functions provide method . functions mutate geometry column sf object way break valid spatial network structure supported. Methods sf::st_coordinates(), sf::st_bbox() sf::st_crs() gained active argument information can extracted network element without first activating . Refs #215.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"bug-fixes-0-6-0","dir":"Changelog","previous_headings":"","what":"Bug fixes","title":"sfnetworks v0.6.0 “Coerde”","text":"Rd files contain code anymore incompatible HTML5. Refs #221. Print methods now return x invisibly. Refs #217.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"refactoring-0-6-0","dir":"Changelog","previous_headings":"","what":"Refactoring","title":"sfnetworks v0.6.0 “Coerde”","text":"Error messages edge measure query functions applied network active nodes, node measure query functions applied network active edges, now informative. Refs #216. Calculating straight-line distances edges now performant. Refs #180. Edge measure function edge_circuity() return units objects anymore, since circuity unitless.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"community-0-6-0","dir":"Changelog","previous_headings":"","what":"Community","title":"sfnetworks v0.6.0 “Coerde”","text":"Vignettes updated showcase new features. Code conduct updated according newer template. Contributing guidelines extended templates commit messages. Master branch renamed main, protected directed pushes.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v055","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.5.5","title":"sfnetworks v0.5.5","text":"CRAN release: 2022-02-16 Adjusted code used check version PROJ attach. particular, new approach tests sf::sf_extSoftVersion()[\"proj.4\"] since sf::sf_extSoftVersion()[\"PROJ\"] might defined sf < 1.0. Refs #198 #200. Adjusted one vignettes following changes dplyr 1.0.8. Ref #202. Thanks @romainfrancois. Removed conflicting URL package documentation spatial_edge_measures","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v054","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.5.4","title":"sfnetworks v0.5.4","text":"CRAN release: 2021-12-17 startup message included urge users PROJ <= 6 recreate CRS Roxel dataset. Refs #190 fixed #193. Example using GraphML vignette 1 removed provisionally address #194.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v053","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.5.3","title":"sfnetworks v0.5.3","text":"CRAN release: 2021-11-26 Addition n_active n_inactive arguments print method sfnetwork object. arguments define many rows printed respectively active inactive network element. values arguments can also set globally running e.g. options(sfn_max_print_active = 1, sfn_max_print_inactive = 2). Refs #157 example dataset Roxel updated comply recent updates way CRS specified sf object. Refs #167 GitHub Actions workflows updated comply new developments. Vignette file names updated appear correct order CRAN. Refs #162 Example section plot method sfnetwork objects now includes example add graticules axes. Refs #159","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v052","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.5.2","title":"sfnetworks v0.5.2","text":"CRAN release: 2021-05-13 Compatibility s2 adding s2::as_s2_geography() method sfnetwork objects. new version sf, s2 package used geometric operations involving longitude-latitude coordinates, see . setting length_as_weight = TRUE sfnetwork construction function, added weight column now preserves specification units. st_network_blend() now internally uses sf::st_cast() instead sfheaders::sfc_cast() avoid errors CRS specifications. Extended documentation shortest paths functions. Clear mention vignettes tidygraph behavior regarding weight attribute settings sometimes differing igraph.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v051","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.5.1","title":"sfnetworks v0.5.1","text":"CRAN release: 2021-03-28 Compatibility spatstat v2, now splitted multiple sub-packages. See details. sfnetworks, affected functions as_sfnetwork.linnet(), as_sfnetwork.psp() .linnet.sfnetwork(). Using functions now requires spatstat >= 2.0.0 sf >= 0.9.8. Usage match checking coordinate equality replaced new st_match function specifically designed task. fixes bugs related numeric approximations detailed coordinates. See #130 now clearly documented using sf::st_reverse() reverse edge linestrings possible GEOS versions >= 3.7.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v050-nienberge","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.5.0 “Nienberge”","title":"sfnetworks v0.5.0 “Nienberge”","text":"CRAN release: 2021-03-11 Addition to_spatial_contracted() morpher, contract groups nodes based given grouping variables. Refs #104 Addition to_spatial_neighborhood() morpher, limit network neighborhood given node, based given cost threshold. Refs #90 New implementation st_network_blend(), faster reliable. sort argument deprecated, since returned network now always sorted. Addition summarise_attributes argument to_spatial_simple() morpher, allowing specify per-attribute basis attribute values merged multiple edges inferred original ones. Refs #113. argument also part new to_spatial_contracted() morpher, can used specify per-attribute basis attribute values contracted groups nodes inferred original ones. argument remove_parallels to_spatial_simple() morpher renamed remove_multiples better fit naming conventions igraph. argument store_orig_data to_spatial_smooth() morpher renamed store_original_data better interpretable. argument also added morphers to_spatial_simple() to_spatial_contracted(), allowing store original node edge data .orig_data column, matching design standards tidygraph. Addition Inf_as_NaN argument st_network_cost(), store cost values paths unconnected edges NaN instead Inf. default value argument FALSE. Refs #111 default Inf_as_NaN argument edge_circuity() changed TRUE FALSE, better fit change mentioned , make sure changes R defaults made without user explicitly specifying . Whenever multiple matches spatially joining information nodes network sf::st_join(), information first match now joined. , used throw error. Refs #108 Removal morphed_sfnetwork method sf::st_geometry<-, since geometries replaced morphed state. warning ‘.. assumes attributes constant geometries’ now raised attribute-geometry relationships set ‘constant’. Refs #123 attribute-geometry relationships edge attributes now preserved network construction. Fixes #123 st_network_blend() now correctly blends points close network. Fixes #98 st_network_blend() now preserves directedness input network. Fixes #127 st_network_blend() now runs even network contains edges length 0. Fixes #125 sfnetwork method sf::st_crop() now correctly updates nodes table cropping edges. Fixes #109 to_spatial_smooth() now returns original network pseudo nodes present. Fixes #112 to_spatial_subdivision() now returns original network locations subdivision. to_spatial_subdivision() now returns correct node indices undirected networks. Several new examples applications added vignettes.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v041","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.4.1","title":"sfnetworks v0.4.1","text":"Addition edge measure function edge_azimuth(), calculate azimuth (.e. bearing) edges. Refs #107 Addition to_spatial_transformed() morpher, temporarily transform sfnetwork different CRS. Addition sfnetwork methods linnet objects, enhance interoperability sfnetworks spatstat package spatial point patterns linear networks. Addition Inf_as_NaN argument edge_circuity() function, store circuity values loop edges NaN instead Inf. default value argument TRUE. Addition new argument type, lets set type paths calculation performed. calculate shortest paths nodes, now set type = 'all_shortest' instead = TRUE. latter argument deprecated. Besides shortest paths, now also possibility calculate simple paths nodes, setting type = 'all_simple'. aware computation time gets high providing lot ‘’ nodes, network large dense. Refs #105 Whenever weights = NULL column named ‘weight’ edges table, geographic edge length calculated internally used weights shortest path calculation. , paths calculated without edge weights case. Refs #106 Whenever given ‘’ /‘’ nodes contain NA values /empty point geometries, igraph behaviour now replicated throwing error. , values simply ignored. Performance improvement to_spatial_smooth() morpher. result store original edge data anymore ‘.orig_data’ column. Instead, non-merged edges keep attributes, merged edges loose attributes. ‘.orig_data’ column can still added setting store_orig_data = TRUE, default. st_network_paths() now correctly handles cases unexisting column passed weights argument, throwing error. Fixes #99 sfnetwork method sf::st_join() now correctly handles inner joins (.e. joins left = FALSE). Addition extra examples routing spatial morphers vignettes. Test coverage increased +/- 86%.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v040-hiltrup","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.4.0 “Hiltrup”","title":"sfnetworks v0.4.0 “Hiltrup”","text":"Function st_shortest_paths() st_all_shortest_paths() now merged single function st_network_paths(). default call igraph::shortest_paths() internally. Setting = TRUE make call igraph::all_shortest_paths() instead. output format st_network_paths() function different predecessors. returns tibble instead list, fit better tidyverse workflows. See #77 snap argument removed shortest paths related functions, now always snap geospatial points provides locations nearest node network calculating paths. keep argument removed to_spatial_simple() morpher. now recommended first sort data dplyr::arrange() calling morpher. spatial morpher to_spatial_coordinates() deprecated. Use new node coordinate query functions instead. spatial morpher to_spatial_dense_graph() deprecated. new morpher to_spatial_subdivision(), slightly different functionality, added instead. spatial morpher to_spatial_implicit_edges() deprecated. Use sf::st_set_geometry() instead, activated edges value NULL. Functions st_network_distance(), edge_straight_length() to_spatial_explicit_edges() renamed respectively st_network_cost(), edge_displacement() to_spatial_explicit(), either reflects purpose better fits better naming conventions within package. Function arguments named graph renamed x, consistency across package. construction function sfnetwork() now argument length_as_weight , set TRUE, add lengths edges weight attribute edges data. Refs #65 now as_sfnetwork() method sfc objects. Refs #41 existing st_network_* functions sfnetwork now generic, can easily modified extensions sfnetwork objects. Refs #80 to_spatial_explicit_edges() morpher now accepts arguments forwarded directly sf::st_as_sf(). Refs #83 Functions split edges now give warning attributes assumed constant. Refs #84 edge_length() function can now also applied spatially implicit edges. sfnetwork methods sf::st_as_sf(), sf::st_geometry() sf::st_agr() now argument active directly retrieve information network element without activating . Use st_as_sf(x, active = \"nodes\"), et cetera. Character encoded node names can now provided locations shortest path functions. new function st_network_blend() implements process called ‘blending points network’. functions accepts network set points. point p set given points, finds projection p* p network, splits edges network location p*, finally adds p* along attributes p node network. Refs #27 #54 new function st_network_join() network specific join two sfnetworks. combines spatial full join nodes data bind_rows operation edges data, updates indices edges accordingly. Refs #22 new function st_network_bbox() calculates bounding box whole network combining bounding boxes nodes edges. new spatial morpher to_spatial_subdivision() subdivides edges locations interior point shared either another interior point endpoint another edge. Refs #73 new spatial morpher to_spatial_smooth() iteratively removes pseudo-nodes network. Refs #70 Several spatial predicate functions implemented node edge query functions, interpret spatial relations network elements geospatial features directly inside tidy filter mutate calls. Refs #60 Node coordinate query functions node_X(), node_Y(), node_Z() node_M() implemented query specific coordinate values nodes. now ggplot2::autoplot() method sfnetworks, allowing easily plot sfnetwork ggplot2 object. Refs #86 now print method morphed sfnetworks. Refs #88 now morphed sfnetworks method sf::st_geometry<-(), sf::st_join(), sf::st_filter() sf::st_crop(). Refs #85 Networks can now constructed providing nodes, edges. Fixes #81 print method sfnetwork objects now correctly handles networks without edges well completely empty networks. Fixes #69 #89 shortest path functions now correctly handle empty geometries. Fixes #87 Examples added function documentations. Refs #45 existing vignettes reorganized, combined lot new information five new vignettes. Refs #92 Together documentation improvements, several new units tests brought test coverage +/- 80%. internal code base completely restructured, performant easier read, debug extend.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v031","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.3.1","title":"sfnetworks v0.3.1","text":"as_sfnetwork() now handles circular linestrings. Fixes #59 Addition “node_key” argument construction functions, line recent update tidygraph. Refs #53 Better integration Z M coordinates adding coordinate columns calling spatial morpher to_spatial_coordinates(). Refs #62 Improved pkgdown structure. Refs #44 First implementation continuous benchmarking. Refs #6","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v030-gievenbeck","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.3.0 “Gievenbeck”","title":"sfnetworks v0.3.0 “Gievenbeck”","text":"Spatial wrappers around igraph shortest paths functions. Refs #28 Various spatial morpher functions. Refs #19 Various edge measure algorithms, including edge circuity. Refs #51 Support sfNetwork stplanr Support linnet psp spatstat Preserving sf attributes nodes edges inside sfnetwork object. Refs #24 Construction checks run needed, adding force argument skip validity tests. Allowing choose spatially explicit implicit edges construction, adding edges_as_lines argument. Refs #47 Using st_boundary find line endpoints increases performance sfnetwork construction sf objects. Refs #30 Cleaning sf methods sfnetwork objects. Relying internally stored attributes rather first extracting sf objects. Option plot without making edges explicit. Improved function documentation. additional vignette “Extensions” included.","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v020-neutor","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.2.0 “Neutor”","title":"sfnetworks v0.2.0 “Neutor”","text":"Major stable release Basic construction function initial foreign objects conversion. Refs #9 Methods sf functions Roxel data lazyData Internal checks construction ghactions sf pkgdown Basic print plot methods First vignette Code conduct, contribution license files","code":""},{"path":"https://luukvdmeer.github.io/sfnetworks/news/index.html","id":"sfnetworks-v010-altstadt","dir":"Changelog","previous_headings":"","what":"sfnetworks v0.1.0 “Altstadt”","title":"sfnetworks v0.1.0 “Altstadt”","text":"Initial release","code":""}]