## This vignette is work in progress - watch this space!

``````library(stplanr)
library(sf)``````

# Introduction

Route networks represent the network of highways, cycleways, footways and other ways along which transport happens. Unlike routes, each segment geometry the network can only appear once in a single route network.

stplanr can be used to convert a series of routes into a route network, using the function `overline2()`, as illustrated below:

``````sample_routes <- routes_fast_sf[2:6, 1]
sample_routes\$value <- rep(1:3, length.out = 5)
rnet <- overline2(sample_routes, attrib = "value")
plot(sample_routes["value"], lwd = sample_routes\$value, main = "Routes")
plot(rnet["value"], lwd = rnet\$value, main = "Route network")``````  The above figure shows how `overline2()` breaks the routes into segments with the same values and removes overlapping segments. It is a form of geographic aggregation.

# SpatialLineNetworks

An important feature of route networks is that they are simultaneously spatial and graph entities. This duality is captured in `sfNetwork` objects, which can be created by the function `SpatialLinesNetwork()`:

``````sln <- SpatialLinesNetwork(rnet)
class(sln)
#>  "sfNetwork"
#> attr(,"package")
#>  "stplanr"``````

`sln` has both spatial and graph components, with the number of lines equal to the number graph edges:

``````class(sln@sl)
#>  "sf"         "tbl_df"     "tbl"        "data.frame"
nrow(sln@sl)
#>  8
class(sln@g)
#>  "igraph"
length(igraph::edge.attributes(sln@g)[["weight"]])
#>  8
class(sln@nb)
#>  "list"
length(unique(unlist(sln@nb)))
#>  8
identical(sln@sl\$geometry, rnet\$geometry)
#>  TRUE``````
``````sln_nodes <- sln2points(sln)
nrow(sln_nodes)
#>  9
length(sln@nb)
#>  9``````
``````rnet_coordinates <- sf::st_coordinates(rnet)
set.seed(85)
x <- runif(n = 2, min = min(rnet_coordinates[, 1]), max = max(rnet_coordinates[, 1]))
y <- runif(n = 2, min = min(rnet_coordinates[, 2]), max = max(rnet_coordinates[, 2]))
crs <- sf::st_crs(rnet)
xy_sf <- sf::st_as_sf(data.frame(n = 1:2, x, y), coords = c("x", "y"), crs = crs)
xy_nodes <- stplanr::find_network_nodes(sln = sln, x = x, y = y)``````

# Routing on route networks

``````plot(rnet\$geometry)
xy_path <- sum_network_routes(sln = sln, start = xy_nodes, end = xy_nodes, sumvars = "length")
# xy_path = sum_network_links(sln = sln, start = xy_nodes, end = xy_nodes)
plot(rnet\$geometry)
plot(xy_path\$geometry, add = TRUE, lwd = 5)``````

New nodes can be added to the network, although this should be done before the graph representation is created. Imagine we want to create a point half way along the the most westerly route segment in the network, near the coordinates -1.540, 53.826:

``````new_point_coordinates <- c(-1.540, 53.826)
p <- sf::st_sf(geometry = sf::st_sfc(sf::st_point(new_point_coordinates)), crs = crs)``````

We can identify the nearest point on the network at this point and use that to split the associated linestring:

``````sln_new <- sln_add_node(sln = sln, p = p)
#> although coordinates are longitude/latitude, st_nearest_feature assumes that they are planar
route_new <- route_local(sln = sln_new, from = p, to = xy_sf[1, ])
plot(sln_new)
plot(route_new, lwd = 5, add = TRUE)
#> Warning in plot.sf(route_new, lwd = 5, add = TRUE): ignoring all but the first
#> attribute`````` # Other approaches

Other approaches to working with route networks include:

• sDNA, an open source C++ library for analysing route networks and estimating flows at segments across network segments
• sfnetworks, an R package that provides an alternative igraph/sf spatial network class
• dodgr, an R package providing functions for calculating distances on directed graphs
• cppRouting, a package for routing in C++
• Chapter 10 of Geocomputation with R, which provides context and demonstrates a transport planning workflow in R.