class: center, middle, inverse, title-slide #
sfnetworks
: Tidy Geospatial Networks in R ## FOSS4g 2022 | Workshop ### Lucas van der Meer, Lorena Abad, Andrea Gilardi, Robin Lovelace ### 2022-08-22 --- class: center, middle, hide-logo <STYLE type='text/css' scoped> PRE.fansi SPAN {padding-top: .25em; padding-bottom: .25em}; </STYLE> ## About us... Maybe add a pic of all of us? --- class: center, middle, hide-logo ## Let's start! The slides can be found here: https://sfnetworks.github.io/foss4g-workshop/slides/slides All the R code can be found here: https://github.com/sfnetworks/foss4g-workshop --- class: center, top, hide-logo ## <span style="color:#b3b3b3">Tidy</span> <span style="color:#ffa500">Geospatial Networks</span> <span style="color:#b3b3b3">in R</span> .left[ .pull-left-70[ ![](https://raw.githubusercontent.com/sfnetworks/rladies-gye/main/figs/river_network.png) ] ] .pull-right-30[ Graphs embedded in geographical space Nodes usually associated with **POINT** geometries Edges usually associated with **LINESTRING** geometries The network topology does not contain *all* information of a geospatial network Both topological *and* spatial information are essential when analyzing them ] --- class: center, top, hide-logo ## <span style="color:#ffa500">Tidy</span> <span style="color:#b3b3b3">Geospatial Networks</span> <span style="color:#ffa500">in R</span> .left[ .pull-left-60[ ```r library(tidyverse) library(sfnetworks) roxel %>% as_tibble() %>% select(name, type) ``` <PRE class="fansi fansi-output"><CODE><span style='color: #555555;'># A tibble: 851 x 2</span> name type <span style='color: #555555; font-style: italic;'><chr></span> <span style='color: #555555; font-style: italic;'><fct></span> <span style='color: #555555;'>1</span> Havixbecker Strasse residential <span style='color: #555555;'>2</span> Pienersallee secondary <span style='color: #555555;'>3</span> Schulte-Bernd-Strasse residential <span style='color: #555555;'>4</span> <span style='color: #BB0000;'>NA</span> path <span style='color: #555555;'>5</span> Welsingheide residential <span style='color: #555555;'># ... with 846 more rows</span> </CODE></PRE> ] ] .pull-right-40[ ![:scale 20%](https://raw.githubusercontent.com/tidyverse/tidyverse/master/man/figures/logo.png) **The tidyverse** Collection of R packages for data science Shared design philosophy Tidy data structures ] --- class: center, top, hide-logo ## <span style="color:#b3b3b3">Tidy</span> <span style="color:#ffa500">Geospatial</span> <span style="color:#b3b3b3">Networks</span> <span style="color:#ffa500">in R</span> .left[ .pull-left-70[ ```r library(sf) roxel ``` <PRE class="fansi fansi-output"><CODE>Simple feature collection with 851 features and 2 fields Geometry type: LINESTRING Dimension: XY Bounding box: xmin: 7.523 ymin: 51.94 xmax: 7.547 ymax: 51.96 Geodetic CRS: WGS 84 <span style='color: #555555;'># A tibble: 851 x 3</span> name type geometry <span style='color: #555555;'>*</span> <span style='color: #555555; font-style: italic;'><chr></span> <span style='color: #555555; font-style: italic;'><fct></span> <span style='color: #555555; font-style: italic;'><LINESTRING [°]></span> <span style='color: #555555;'>1</span> Havixbecker Strasse residential (7.534 51.96, 7.533 51.96) <span style='color: #555555;'>2</span> Pienersallee secondary (7.532 51.95, 7.532 51.95, 7.532 ~ <span style='color: #555555;'>3</span> Schulte-Bernd-Strasse residential (7.533 51.95, 7.533 51.95, 7.533 ~ <span style='color: #555555;'>4</span> <span style='color: #BB0000;'>NA</span> path (7.54 51.94, 7.54 51.94, 7.539 51~ <span style='color: #555555;'>5</span> Welsingheide residential (7.538 51.95, 7.538 51.95) <span style='color: #555555;'># ... with 846 more rows</span> </CODE></PRE> ] ] .pull-right-30[ ![:scale 50%](https://user-images.githubusercontent.com/520851/34887433-ce1d130e-f7c6-11e7-83fc-d60ad4fae6bd.gif) **The sf package** R package for spatial data science Standardized storage of geographic features (points, lines, polygons) Geometric operations (intersections, unions, ..) Compatible with the tidyverse New specific *verbs* for spatial data ] --- class: top, center, hide-logo ## <span style="color:#b3b3b3">Tidy</span> <span style="color:#ffa500">Geospatial</span> <span style="color:#b3b3b3">Networks</span> <span style="color:#ffa500">in R</span> .pull-left-30[ .left[ ```r lines = roxel %>% st_transform(3035) plot(st_geometry(lines)) ``` ] ] .pull-left-70[ <img src="slides_files/figure-html/unnamed-chunk-3-1.png" width="864" /> ] --- class: top, hide-logo ## <span style="color:#b3b3b3">Tidy</span> <span style="color:#ffa500">Geospatial</span> <span style="color:#b3b3b3">Networks</span> <span style="color:#ffa500">in R</span> .pull-left-40[ ```r points = c(st_point(c(4151358, 3208045)), st_point(c(4151340, 3207520)), st_point(c(4151756, 3207506)), st_point(c(4151774, 3208031))) polygon = st_multipoint(points) %>% st_cast("POLYGON") %>% st_sfc(crs = 3035) plot(polygon) ``` ] .pull-right-60[ <img src="slides_files/figure-html/unnamed-chunk-5-1.png" width="864" /> ] --- class: top, hide-logo ## <span style="color:#b3b3b3">Tidy</span> <span style="color:#ffa500">Geospatial</span> <span style="color:#b3b3b3">Networks</span> <span style="color:#ffa500">in R</span> .pull-left-40[ ```r plot(st_geometry(lines)) plot( polygon, border = "red", lty = 4, lwd = 4, add = TRUE ) ``` ] .pull-right-60[ <img src="slides_files/figure-html/unnamed-chunk-7-1.png" width="864" /> ] --- class: top, hide-logo ## <span style="color:#b3b3b3">Tidy</span> <span style="color:#ffa500">Geospatial</span> <span style="color:#b3b3b3">Networks</span> <span style="color:#ffa500">in R</span> .pull-left-30[ .left[ ```r lines %>% st_filter( polygon, .pred = st_intersects ) %>% st_geometry() %>% plot() ``` ] ] .pull-right-70[ <img src="slides_files/figure-html/unnamed-chunk-9-1.png" width="864" /> ] --- class: center, top, hide-logo ## <span style="color:#b3b3b3">Tidy Geospatial</span> <span style="color:#ffa500">Networks in R</span> .pull-left-60[ .left[ ```r library(tidygraph) nodes = tibble(name = letters[1:4]) edges = tibble(from = c(1,2,3,4), to = c(2,3,4,1)) tbl_graph(nodes, edges) ``` <PRE class="fansi fansi-output"><CODE><span style='color: #555555;'># A tbl_graph: 4 nodes and 4 edges # # A directed simple graph with 1 component # # Node Data: 4 x 1 (active)</span> name <span style='color: #555555; font-style: italic;'><chr></span> <span style='color: #555555;'>1</span> a <span style='color: #555555;'>2</span> b <span style='color: #555555;'>3</span> c <span style='color: #555555;'>4</span> d <span style='color: #555555;'># # Edge Data: 4 x 2</span> from to <span style='color: #555555; font-style: italic;'><int></span> <span style='color: #555555; font-style: italic;'><int></span> <span style='color: #555555;'>1</span> 1 2 <span style='color: #555555;'>2</span> 2 3 <span style='color: #555555;'>3</span> 3 4 <span style='color: #555555;'># ... with 1 more row</span> </CODE></PRE> ] ] .pull-right-40[ ![:scale 20%](https://raw.githubusercontent.com/thomasp85/tidygraph/master/man/figures/logo.png) **The tidygraph package** Tidy interface to the **igraph** library for graph analysis Models a graph as a collection of two tibbles Graph algorithms (centralities, clustering, shortest paths, ..) Compatible with the tidyverse New specific *verbs* for graph structures ] --- class: top, center, hide-logo ## <span style="color:#b3b3b3">Tidy Geospatial</span> <span style="color:#ffa500">Networks in R</span> .pull-left[ .left[ ```r graph = tbl_graph(nodes, edges) %>% activate(nodes) %>% mutate(degree = centrality_degree()) %>% activate(edges) %>% mutate(btwn = centrality_edge_betweenness()) %>% arrange(btwn) graph ``` ] ] .pull-right[ .left[ <PRE class="fansi fansi-output"><CODE><span style='color: #555555;'># A tbl_graph: 4 nodes and 4 edges # # A directed simple graph with 1 component # # Edge Data: 4 x 3 (active)</span> from to btwn <span style='color: #555555; font-style: italic;'><int></span> <span style='color: #555555; font-style: italic;'><int></span> <span style='color: #555555; font-style: italic;'><dbl></span> <span style='color: #555555;'>1</span> 1 2 6 <span style='color: #555555;'>2</span> 2 3 6 <span style='color: #555555;'>3</span> 3 4 6 <span style='color: #555555;'>4</span> 4 1 6 <span style='color: #555555;'># # Node Data: 4 x 2</span> name degree <span style='color: #555555; font-style: italic;'><chr></span> <span style='color: #555555; font-style: italic;'><dbl></span> <span style='color: #555555;'>1</span> a 1 <span style='color: #555555;'>2</span> b 1 <span style='color: #555555;'>3</span> c 1 <span style='color: #555555;'># ... with 1 more row</span> </CODE></PRE> ] ] --- class: top, center, hide-logo ## <span style="color:#b3b3b3">Tidy Geospatial</span> <span style="color:#ffa500">Networks in R</span> .pull-left[ .left[ ```r geoms = roxel[1:4, ] %>% st_geometry() %>% st_transform(3035) %>% st_centroid() nodes = st_sf(name = letters[1:4], geometry = geoms) edges = tibble(from = c(1,2,3,4), to = c(2,3,4,1)) graph = tbl_graph(nodes, edges) graph ``` ] ] .pull-right[ .left[ <PRE class="fansi fansi-output"><CODE><span style='color: #555555;'># A tbl_graph: 4 nodes and 4 edges # # A directed simple graph with 1 component # # Node Data: 4 x 2 (active)</span> name geometry <span style='color: #555555; font-style: italic;'><chr></span> <span style='color: #555555; font-style: italic;'><POINT [m]></span> <span style='color: #555555;'>1</span> a (4151482 3207934) <span style='color: #555555;'>2</span> b (4151387 3207724) <span style='color: #555555;'>3</span> c (4151415 3207565) <span style='color: #555555;'>4</span> d (4151824 3206744) <span style='color: #555555;'># # Edge Data: 4 x 2</span> from to <span style='color: #555555; font-style: italic;'><int></span> <span style='color: #555555; font-style: italic;'><int></span> <span style='color: #555555;'>1</span> 1 2 <span style='color: #555555;'>2</span> 2 3 <span style='color: #555555;'>3</span> 3 4 <span style='color: #555555;'># ... with 1 more row</span> </CODE></PRE> ] ] --- class: top, center, hide-logo ## <span style="color:#b3b3b3">Tidy Geospatial</span> <span style="color:#ffa500">Networks in R</span> .left[ ```r plot(geoms, pch = 20, cex = 4, col = "#ffa500", axes = TRUE) ``` <img src="slides_files/figure-html/unnamed-chunk-16-1.png" width="864" /> ] --- class: top, center, hide-logo ## <span style="color:#b3b3b3">Tidy Geospatial</span> <span style="color:#ffa500">Networks in R</span> .left[ ```r plot(graph) ``` <img src="slides_files/figure-html/unnamed-chunk-18-1.png" width="864" /> ] --- class: top, center, hide-logo ## <span style="color:#b3b3b3">Tidy </span><span style="color:#ffa500">Geospatial Networks in R</span> .pull-left[ ![](https://raw.githubusercontent.com/ropensci/stplanr/master/man/figures/logo.png) ] .pull-right[ ![](https://atfutures.github.io/dodgr/articles/fig2.png) ] -- ![:scale 15%](https://upload.wikimedia.org/wikipedia/commons/thumb/9/98/Ellipsis.svg/1280px-Ellipsis.svg.png) --- class: center, top, hide-logo ## Tidy Geospatial Networks in R? <center><blockquote class="twitter-tweet"><p lang="en" dir="ltr">One of the biggest reasons we still have ArcGIS licenses is for Network Analysis (drive times, service areas etc). Does anyone have <a href="https://twitter.com/hashtag/foss4g?src=hash&ref_src=twsrc%5Etfw">#foss4g</a> tools for this they like? Last time we tried pgRouting (yrs ago) it didn't feel fully formed yet, <a href="https://twitter.com/hashtag/gischat?src=hash&ref_src=twsrc%5Etfw">#gischat</a></p>— Zev Ross (@zevross) <a href="https://twitter.com/zevross/status/1089908839816794118?ref_src=twsrc%5Etfw">January 28, 2019</a></blockquote></center> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> --- class: center, top, hide-logo ## Tidy Geospatial Networks in R! .pull-left[ ![](https://user-images.githubusercontent.com/520851/34887433-ce1d130e-f7c6-11e7-83fc-d60ad4fae6bd.gif) ] .pull-right[ ![:scale 38%](https://raw.githubusercontent.com/thomasp85/tidygraph/master/man/figures/logo.png) ] .center[ ![:scale 20%](https://raw.githubusercontent.com/luukvdmeer/sfnetworks/master/man/figures/logo.png) ] --- class: center, top, hide-logo ## Tidy Geospatial Networks in R! **tidygraph:** > Relational data cannot in any meaningful way be encoded as a single tidy data frame. On the other hand, both node and edge data by itself fits very well within the tidy concept as each node and edge is, in a sense, a single observation. Thus, a close approximation of tidyness for relational data is two tidy data frames, one describing the node data and one describing the edge data. **sfnetworks:** > A close approximation of tidyness for relational geospatial data is two sf objects, one describing the node data and one describing the edge data --- class: top, hide-logo ## The sfnetwork class .pull-left-40[ ```r roxel %>% st_geometry() %>% plot() ``` ] .pull-right-60[ <img src="slides_files/figure-html/unnamed-chunk-20-1.png" width="864" /> ] --- class: top, hide-logo ## The sfnetwork class .pull-left-40[ ```r roxel %>% as_sfnetwork() %>% plot() ``` ] .pull-right-60[ <img src="slides_files/figure-html/unnamed-chunk-22-1.png" width="864" /> ] --- class: top, hide-logo ## The sfnetwork class .pull-left-40[ ```r roxel ``` ] .pull-right-60[ <PRE class="fansi fansi-output"><CODE>Simple feature collection with 851 features and 2 fields Geometry type: LINESTRING Dimension: XY Bounding box: xmin: 7.523 ymin: 51.94 xmax: 7.547 ymax: 51.96 Geodetic CRS: WGS 84 <span style='color: #555555;'># A tibble: 851 x 3</span> name type geometry <span style='color: #555555;'>*</span> <span style='color: #555555; font-style: italic;'><chr></span> <span style='color: #555555; font-style: italic;'><fct></span> <span style='color: #555555; font-style: italic;'><LINESTRING [°]></span> <span style='color: #555555;'>1</span> Havixbecker Strasse residential (7.534 51.96, 7.533 51.96) <span style='color: #555555;'>2</span> Pienersallee secondary (7.532 51.95, 7.532 51.95, 7.532 ~ <span style='color: #555555;'>3</span> Schulte-Bernd-Strasse residential (7.533 51.95, 7.533 51.95, 7.533 ~ <span style='color: #555555;'>4</span> <span style='color: #BB0000;'>NA</span> path (7.54 51.94, 7.54 51.94, 7.539 51~ <span style='color: #555555;'>5</span> Welsingheide residential (7.538 51.95, 7.538 51.95) <span style='color: #555555;'># ... with 846 more rows</span> </CODE></PRE> ] --- class: top, hide-logo ## The sfnetwork class .pull-left-40[ ```r roxel %>% as_sfnetwork() ``` ] .pull-right-60[ <PRE class="fansi fansi-output"><CODE><span style='color: #555555;'># A sfnetwork with</span> <span style='color: #555555;'>701</span> <span style='color: #555555;'>nodes and</span> <span style='color: #555555;'>851</span> <span style='color: #555555;'>edges # # CRS: </span> <span style='color: #555555;'>EPSG:4326</span> <span style='color: #555555;'> # # A directed multigraph with 14 components with spatially explicit edges # # Node Data: 701 x 1 (active)</span> <span style='color: #555555;'># Geometry type: POINT</span> <span style='color: #555555;'># Dimension: XY</span> <span style='color: #555555;'># Bounding box: xmin: 7.523 ymin: 51.94 xmax: 7.547 ymax: 51.96</span> geometry <span style='color: #555555; font-style: italic;'><POINT [°]></span> <span style='color: #555555;'>1</span> (7.534 51.96) <span style='color: #555555;'>2</span> (7.533 51.96) <span style='color: #555555;'>3</span> (7.532 51.95) <span style='color: #555555;'># ... with 698 more rows</span> <span style='color: #555555;'># # Edge Data: 851 x 5</span> <span style='color: #555555;'># Geometry type: LINESTRING</span> <span style='color: #555555;'># Dimension: XY</span> <span style='color: #555555;'># Bounding box: xmin: 7.523 ymin: 51.94 xmax: 7.547 ymax: 51.96</span> from to name type geometry <span style='color: #555555; font-style: italic;'><int></span> <span style='color: #555555; font-style: italic;'><int></span> <span style='color: #555555; font-style: italic;'><chr></span> <span style='color: #555555; font-style: italic;'><fct></span> <span style='color: #555555; font-style: italic;'><LINESTRING [°]></span> <span style='color: #555555;'>1</span> 1 2 Havixbecker Strasse reside~ (7.534 51.96, 7.533 51.96) <span style='color: #555555;'>2</span> 3 4 Pienersallee second~ (7.532 51.95, 7.532 51.95, ~ <span style='color: #555555;'># ... with 849 more rows</span> </CODE></PRE> ] --- class: top, hide-logo ## The sfnetwork class .pull-left-40[ ```r roxel %>% as_sfnetwork() %>% activate(nodes) %>% st_as_sf() ``` ] .pull-right-60[ <PRE class="fansi fansi-output"><CODE>Simple feature collection with 701 features and 0 fields Geometry type: POINT Dimension: XY Bounding box: xmin: 7.523 ymin: 51.94 xmax: 7.547 ymax: 51.96 Geodetic CRS: WGS 84 <span style='color: #555555;'># A tibble: 701 x 1</span> geometry <span style='color: #555555; font-style: italic;'><POINT [°]></span> <span style='color: #555555;'>1</span> (7.534 51.96) <span style='color: #555555;'>2</span> (7.533 51.96) <span style='color: #555555;'>3</span> (7.532 51.95) <span style='color: #555555;'>4</span> (7.532 51.95) <span style='color: #555555;'>5</span> (7.533 51.95) <span style='color: #555555;'># ... with 696 more rows</span> </CODE></PRE> ] --- class: top, hide-logo ## The sfnetwork class .pull-left-40[ ```r roxel %>% as_sfnetwork() %>% activate(edges) %>% st_geometry() ``` ] .pull-right-60[ ``` Geometry set for 851 features Geometry type: LINESTRING Dimension: XY Bounding box: xmin: 7.523 ymin: 51.94 xmax: 7.547 ymax: 51.96 Geodetic CRS: WGS 84 First 5 geometries: ``` ``` LINESTRING (7.534 51.96, 7.533 51.96) ``` ``` LINESTRING (7.532 51.95, 7.532 51.95, 7.532 51.95) ``` ``` LINESTRING (7.533 51.95, 7.533 51.95, 7.533 51.95) ``` ``` LINESTRING (7.54 51.94, 7.54 51.94, 7.539 51.94... ``` ``` LINESTRING (7.538 51.95, 7.538 51.95) ``` ] --- class: top, hide-logo ## The sfnetwork class .pull-left-30[ ```r roxel %>% as_sfnetwork() %>% st_transform(3035) ``` ] .pull-right-70[ <PRE class="fansi fansi-output"><CODE><span style='color: #555555;'># A sfnetwork with</span> <span style='color: #555555;'>701</span> <span style='color: #555555;'>nodes and</span> <span style='color: #555555;'>851</span> <span style='color: #555555;'>edges # # CRS: </span> <span style='color: #555555;'>EPSG:3035</span> <span style='color: #555555;'> # # A directed multigraph with 14 components with spatially explicit edges # # Node Data: 701 x 1 (active)</span> <span style='color: #555555;'># Geometry type: POINT</span> <span style='color: #555555;'># Dimension: XY</span> <span style='color: #555555;'># Bounding box: xmin: 4151000 ymin: 3206000 xmax: 4152000 ymax: # 3209000</span> geometry <span style='color: #555555; font-style: italic;'><POINT [m]></span> <span style='color: #555555;'>1</span> (4151491 3207923) <span style='color: #555555;'>2</span> (4151474 3207946) <span style='color: #555555;'>3</span> (4151398 3207777) <span style='color: #555555;'># ... with 698 more rows</span> <span style='color: #555555;'># # Edge Data: 851 x 5</span> <span style='color: #555555;'># Geometry type: LINESTRING</span> <span style='color: #555555;'># Dimension: XY</span> <span style='color: #555555;'># Bounding box: xmin: 4151000 ymin: 3206000 xmax: 4152000 ymax: # 3209000</span> from to name type geometry <span style='color: #555555; font-style: italic;'><int></span> <span style='color: #555555; font-style: italic;'><int></span> <span style='color: #555555; font-style: italic;'><chr></span> <span style='color: #555555; font-style: italic;'><fct></span> <span style='color: #555555; font-style: italic;'><LINESTRING [m]></span> <span style='color: #555555;'>1</span> 1 2 Havixbecker Strasse resid~ (4151491 3207923, 4151474 32~ <span style='color: #555555;'>2</span> 3 4 Pienersallee secon~ (4151398 3207777, 4151390 32~ <span style='color: #555555;'># ... with 849 more rows</span> </CODE></PRE> ] --- class: top, hide-logo ## Apply sf functions .pull-left-40[ ```r net = roxel %>% as_sfnetwork() %>% st_transform(3035) plot(net) ``` ] .pull-right-60[ <img src="slides_files/figure-html/unnamed-chunk-34-1.png" width="864" /> ] --- class: top, hide-logo ## Apply sf functions .pull-left-40[ ```r plot(net) plot( polygon, border = "red", lty = 4, lwd = 4, add = TRUE ) ``` ] .pull-right-60[ <img src="slides_files/figure-html/unnamed-chunk-36-1.png" width="864" /> ] --- class: top, hide-logo ## Apply sf functions .pull-left-40[ ```r net %>% st_filter( polygon, .pred = st_intersects ) %>% plot() ``` ] .pull-right-60[ <img src="slides_files/figure-html/unnamed-chunk-38-1.png" width="864" /> ] --- class: top, hide-logo ## Apply tidygraph functions .pull-left-40[ ```r net = as_sfnetwork(roxel) %>% activate(nodes) %>% mutate( btwn = centrality_betweenness() ) %>% activate(edges) %>% mutate( length = edge_length() ) net ``` ] .pull-right-60[ <PRE class="fansi fansi-output"><CODE><span style='color: #555555;'># A sfnetwork with</span> <span style='color: #555555;'>701</span> <span style='color: #555555;'>nodes and</span> <span style='color: #555555;'>851</span> <span style='color: #555555;'>edges # # CRS: </span> <span style='color: #555555;'>EPSG:4326</span> <span style='color: #555555;'> # # A directed multigraph with 14 components with spatially explicit edges # # Edge Data: 851 x 6 (active)</span> <span style='color: #555555;'># Geometry type: LINESTRING</span> <span style='color: #555555;'># Dimension: XY</span> <span style='color: #555555;'># Bounding box: xmin: 7.523 ymin: 51.94 xmax: 7.547 ymax: 51.96</span> from to name type geometry length <span style='color: #555555; font-style: italic;'><int></span> <span style='color: #555555; font-style: italic;'><int></span> <span style='color: #555555; font-style: italic;'><chr></span> <span style='color: #555555; font-style: italic;'><fct></span> <span style='color: #555555; font-style: italic;'><LINESTRING [°]></span> <span style='color: #555555;'>[m]</span> <span style='color: #555555;'>1</span> 1 2 Havixbecke~ reside~ (7.534 51.96, 7.533 51.96) 28.8 <span style='color: #555555;'>2</span> 3 4 Pienersall~ second~ (7.532 51.95, 7.532 51.95, 7~ 108. <span style='color: #555555;'>3</span> 5 6 Schulte-Be~ reside~ (7.533 51.95, 7.533 51.95, 7~ 54.3 <span style='color: #555555;'># ... with 848 more rows</span> <span style='color: #555555;'># # Node Data: 701 x 2</span> <span style='color: #555555;'># Geometry type: POINT</span> <span style='color: #555555;'># Dimension: XY</span> <span style='color: #555555;'># Bounding box: xmin: 7.523 ymin: 51.94 xmax: 7.547 ymax: 51.96</span> geometry btwn <span style='color: #555555; font-style: italic;'><POINT [°]></span> <span style='color: #555555; font-style: italic;'><dbl></span> <span style='color: #555555;'>1</span> (7.534 51.96) <span style='text-decoration: underline;'>12</span>936. <span style='color: #555555;'>2</span> (7.533 51.96) <span style='text-decoration: underline;'>11</span>824 <span style='color: #555555;'># ... with 699 more rows</span> </CODE></PRE> ] --- class: top, hide-logo ## Apply tidygraph functions .pull-left-40[ ```r ggplot() + geom_sf( data = st_as_sf(net, "edges"), col = "grey50" ) + geom_sf( data = st_as_sf(net, "nodes"), aes(size = btwn) ) + ggtitle("Betweenness centrality") ``` ] .pull-right-60[ <img src="slides_files/figure-html/unnamed-chunk-42-1.png" width="864" /> ] --- class: center, middle ### What can we do? #### Network pre-processing and cleaning --- class: middle ### Network pre-processing and cleaning #### Initial network <img src="slides_files/figure-html/clean2-1.png" width="864" /> --- class: middle ### Network pre-processing and cleaning #### Simplifying edges: `to_spatial_simple()` <img src="slides_files/figure-html/clean3-1.png" width="864" /> --- class: middle ### Network pre-processing and cleaning #### Subdividing edges: `to_spatial_subdivision()` <img src="slides_files/figure-html/clean4-1.png" width="864" /> --- class: middle ### Network pre-processing and cleaning #### Removing pseudo-nodes: `to_spatial_smooth()` <img src="slides_files/figure-html/clean5-1.png" width="864" /> --- class: middle ### Network pre-processing and cleaning #### Simplifying intersections: `to_spatial_contracted()` <img src="slides_files/figure-html/clean6-1.png" width="864" /> --- class: center, middle ### What can we do? #### Snapping --- class: middle count: false ### Snapping #### Snapping points to their nearest node <img src="slides_files/figure-html/snap_user_01_output-1.png" width="864" /> --- count: false ### Snapping #### Snapping points to their nearest node <img src="slides_files/figure-html/snap_user_02_output-1.png" width="864" /> --- count: false ### Snapping #### Snapping points to their nearest node <img src="slides_files/figure-html/snap_user_03_output-1.png" width="864" /> --- count: false ### Snapping #### Snapping points to their nearest node <img src="slides_files/figure-html/snap_user_04_output-1.png" width="864" /> <style> .panel1-snap-user { color: black; width: 99%; hight: 32%; float: left; padding-left: 1%; font-size: 80% } .panel2-snap-user { color: black; width: NA%; hight: 32%; float: left; padding-left: 1%; font-size: 80% } .panel3-snap-user { color: black; width: NA%; hight: 33%; float: left; padding-left: 1%; font-size: 80% } </style> --- class: middle count: false ### Snapping #### Blending points into a network <img src="slides_files/figure-html/blend_user_01_output-1.png" width="864" /> --- count: false ### Snapping #### Blending points into a network <img src="slides_files/figure-html/blend_user_02_output-1.png" width="864" /> --- count: false ### Snapping #### Blending points into a network <img src="slides_files/figure-html/blend_user_03_output-1.png" width="864" /> <style> .panel1-blend-user { color: black; width: 99%; hight: 32%; float: left; padding-left: 1%; font-size: 80% } .panel2-blend-user { color: black; width: NA%; hight: 32%; float: left; padding-left: 1%; font-size: 80% } .panel3-blend-user { color: black; width: NA%; hight: 33%; float: left; padding-left: 1%; font-size: 80% } </style> --- class: center, middle ### What can we do? #### Routing --- class: top count: false ### Routing #### Calculating shortest paths <img src="slides_files/figure-html/plotpath_user_01_output-1.png" width="864" /> --- count: false ### Routing #### Calculating shortest paths <img src="slides_files/figure-html/plotpath_user_02_output-1.png" width="864" /> --- count: false ### Routing #### Calculating shortest paths <img src="slides_files/figure-html/plotpath_user_03_output-1.png" width="864" /> --- count: false ### Routing #### Calculating shortest paths <img src="slides_files/figure-html/plotpath_user_04_output-1.png" width="864" /> --- count: false ### Routing #### Calculating shortest paths <img src="slides_files/figure-html/plotpath_user_05_output-1.png" width="864" /> --- count: false ### Routing #### Calculating shortest paths <img src="slides_files/figure-html/plotpath_user_06_output-1.png" width="864" /> <style> .panel1-plotpath-user { color: black; width: 99%; hight: 32%; float: left; padding-left: 1%; font-size: 80% } .panel2-plotpath-user { color: black; width: NA%; hight: 32%; float: left; padding-left: 1%; font-size: 80% } .panel3-plotpath-user { color: black; width: NA%; hight: 33%; float: left; padding-left: 1%; font-size: 80% } </style> --- class: top ### Routing #### Retrieving an OD cost matrix ```r st_network_cost( net, from = c(p1, p2, p3), to = c(p1, p2, p3) ) ``` ``` Units: [m] [,1] [,2] [,3] [1,] 0 1614 2095 [2,] 1614 0 1316 [3,] 2095 1316 0 ``` --- class: top ### What more? #### Much more...! <img src="https://luukvdmeer.github.io/sfnetworks/articles/sfn04_routing_files/figure-html/unnamed-chunk-8-1.png" width="31%" /><img src="https://luukvdmeer.github.io/sfnetworks/articles/sfn04_routing_files/figure-html/unnamed-chunk-12-1.png" width="31%" /><img src="https://luukvdmeer.github.io/sfnetworks/articles/sfn04_routing_files/figure-html/unnamed-chunk-15-1.png" width="31%" /> --- class: top ### More to come... .center[ ![](https://r-spatial.github.io/spdep/articles/nb_files/figure-html/unnamed-chunk-5-1.png) ] --- class: center, middle ## Installation Install from CRAN: ```r install.packages("sfnetworks") ``` Install the development version from GitHub: ```r remotes::install_github("luukvdmeer/sfnetworks") ``` --- class: center, middle ### Want more? -- See the docs and find more examples [in the package website](https://luukvdmeer.github.io/sfnetworks/index.html) -- ### Have your own examples or ideas for the package? -- Join the [Discussion on GitHub](https://github.com/luukvdmeer/sfnetworks/discussions) -- ### Found a bug? -- Let us know with an [issue here](https://github.com/luukvdmeer/sfnetworks/issues)! --- class: center, middle ### Thank you! #### Q&A GitHub repo: https://github.com/sfnetworks/foss4g-workshop .note[ .pull-left-70[ .pull-left[ <img src="https://raw.githubusercontent.com/RConsortium/artwork/main/r_consortium/R_Consortium-logo-horizontal-color.png" width="50%" /> ] .pull-right[ Slides powered by [xaringan](https://github.com/yihui/xaringan), [xaringanthemer](https://github.com/gadenbuie/xaringanthemer) and [flipbookr](https://github.com/EvaMaeRey/flipbookr). <br><br> ] ] .pull-right-30[ <img src="https://2022.foss4g.org/img/logo/logo-dark.png" width="100%" /> ] ]