Package 'dodgr'

Title: Distances on Directed Graphs
Description: Distances on dual-weighted directed graphs using priority-queue shortest paths (Padgham (2019) <doi:10.32866/6945>). Weighted directed graphs have weights from A to B which may differ from those from B to A. Dual-weighted directed graphs have two sets of such weights. A canonical example is a street network to be used for routing in which routes are calculated by weighting distances according to the type of way and mode of transport, yet lengths of routes must be calculated from direct distances.
Authors: Mark Padgham [aut, cre], Andreas Petutschnig [aut], David Cooley [aut], Robin Lovelace [ctb], Andrew Smith [ctb], Malcolm Morgan [ctb], Andrea Gilardi [ctb] , Shane Saunders [cph] (Original author of included code for priority heaps), Stanislaw Adaszewski [cph] (author of include concaveman-cpp code)
Maintainer: Mark Padgham <[email protected]>
License: GPL-3
Version: 0.4.1.037
Built: 2024-11-14 06:17:17 UTC
Source: https://github.com/UrbanAnalyst/dodgr

Help Index


Insert new nodes into a graph, breaking edges at point of nearest intersection.

Description

Note that this routine presumes graphs to be dodgr_streetnet object, with geographical coordinates.

Usage

add_nodes_to_graph(graph, xy, dist_tol = 0.000001, intersections_only = FALSE)

Arguments

graph

A dodgr graph with spatial coordinates, such as a dodgr_streetnet object.

xy

coordinates of points to be matched to the vertices, either as matrix or sf-formatted data.frame.

dist_tol

Only insert new nodes if they are further from existing nodes than this distance, expressed in units of the distance column of graph.

intersections_only

If FALSE

Details

This inserts new nodes by extending lines from each input point to the edge with the closest point of perpendicular intersection. That edge is then split at that point of intersection, creating two new edges (or four for directed edges). If intersections_only = FALSE (default), then additional edges are inserted from those intersection points to the input points. If intersections_only = TRUE, then nodes are added by splitting graph edges at points of nearest perpendicular intersection, without adding additional edges out to the actual input points.

In the former case, the properties of those new edges, such as distance and time weightings, are inherited from the edges which are intersected, and may need to be manually modified after calling this function.

Value

A modified version of graph, with additional edges formed by breaking previous edges at nearest perpendicular intersections with the points, xy.

See Also

Other match: match_points_to_graph(), match_points_to_verts(), match_pts_to_graph(), match_pts_to_verts()

Examples

graph <- weight_streetnet (hampi, wt_profile = "foot")
dim (graph)

verts <- dodgr_vertices (graph)
set.seed (2)
npts <- 10
xy <- data.frame (
    x = min (verts$x) + runif (npts) * diff (range (verts$x)),
    y = min (verts$y) + runif (npts) * diff (range (verts$y))
)

graph <- add_nodes_to_graph (graph, xy)
dim (graph) # more edges than original

Remove cached versions of dodgr graphs.

Description

This function should generally not be needed, except if graph structure has been directly modified other than through dodgr functions; for example by modifying edge weights or distances. Graphs are cached based on the vector of edge IDs, so manual changes to any other attributes will not necessarily be translated into changes in dodgr output unless the cached versions are cleared using this function. See https://github.com/UrbanAnalyst/dodgr/wiki/Caching-of-streetnets-and-contracted-graphs for details of caching process.

Usage

clear_dodgr_cache()

Value

Nothing; the function silently clears any cached objects

See Also

Other cache: dodgr_cache_off(), dodgr_cache_on(), dodgr_load_streetnet(), dodgr_save_streetnet()


Compare timings of different sort heaps for a given input graph.

Description

Perform timing comparison between different kinds of heaps as well as with equivalent routines from the igraph package. To do this, a random sub-graph containing a defined number of vertices is first selected. Alternatively, this random sub-graph can be pre-generated with the dodgr_sample function and passed directly.

Usage

compare_heaps(graph, nverts = 100, replications = 2)

Arguments

graph

data.frame object representing the network graph (or a sub-sample selected with dodgr_sample)

nverts

Number of vertices used to generate random sub-graph. If a non-numeric value is given, the whole graph will be used.

replications

Number of replications to be used in comparison

Value

Result of bench::mark comparison.

See Also

Other misc: dodgr_flowmap(), dodgr_full_cycles(), dodgr_fundamental_cycles(), dodgr_insert_vertex(), dodgr_sample(), dodgr_sflines_to_poly(), dodgr_vertices(), merge_directed_graph(), summary.dodgr_dists_categorical(), write_dodgr_wt_profile()

Examples

graph <- weight_streetnet (hampi)
## Not run: 
compare_heaps (graph, nverts = 1000, replications = 1)

## End(Not run)

Distances On Directed GRaphs ("dodgr")

Description

Distances on dual-weighted directed graphs using priority-queue shortest paths. Weighted directed graphs have weights from A to B which may differ from those from B to A. Dual-weighted directed graphs have two sets of such weights. A canonical example is a street network to be used for routing in which routes are calculated by weighting distances according to the type of way and mode of transport, yet lengths of routes must be calculated from direct distances.

The Main Function

  • dodgr_dists(): Calculate pair-wise distances between specified pairs of points in a graph.

Functions to Obtain Graphs

  • dodgr_streetnet(): Extract a street network in Simple Features (sf) form.

  • weight_streetnet(): Convert an sf-formatted street network to a dodgr graph through applying specified weights to all edges.

Functions to Modify Graphs

Miscellaneous Functions

  • dodgr_sample(): Randomly sample a graph, returning a single connected component of a defined number of vertices.

  • dodgr_vertices(): Extract all vertices of a graph.

  • compare_heaps(): Compare the performance of different priority queue heap structures for a given type of graph.

Author(s)

Maintainer: Mark Padgham [email protected]

Authors:

  • Andreas Petutschnig

  • David Cooley

Other contributors:

  • Robin Lovelace [contributor]

  • Andrew Smith [contributor]

  • Malcolm Morgan [contributor]

  • Shane Saunders (Original author of included code for priority heaps) [copyright holder]

  • Stanislaw Adaszewski (author of include concaveman-cpp code) [copyright holder]

See Also

Useful links:


Turn off all dodgr caching in current session.

Description

This function is useful is speed is paramount, and if graph contraction is not needed. Caching can be switched back on with dodgr_cache_on.

Usage

dodgr_cache_off()

Value

Nothing; the function invisibly returns TRUE if successful.

See Also

Other cache: clear_dodgr_cache(), dodgr_cache_on(), dodgr_load_streetnet(), dodgr_save_streetnet()


Turn on all dodgr caching in current session.

Description

This will only have an effect after caching has been turned off with dodgr_cache_off.

Usage

dodgr_cache_on()

Value

Nothing; the function invisibly returns TRUE if successful.

See Also

Other cache: clear_dodgr_cache(), dodgr_cache_off(), dodgr_load_streetnet(), dodgr_save_streetnet()


Calculate betweenness centrality for a 'dodgr' network.

Description

Centrality can be calculated in either vertex- or edge-based form.

Usage

dodgr_centrality(
  graph,
  contract = TRUE,
  edges = TRUE,
  column = "d_weighted",
  vert_wts = NULL,
  dist_threshold = NULL,
  heap = "BHeap",
  check_graph = TRUE
)

Arguments

graph

'data.frame' or equivalent object representing the network graph (see Details)

contract

If 'TRUE', centrality is calculated on contracted graph before mapping back on to the original full graph. Note that for street networks, in particular those obtained from the osmdata package, vertex placement is effectively arbitrary except at junctions; centrality for such graphs should only be calculated between the latter points, and thus 'contract' should always be 'TRUE'.

edges

If 'TRUE', centrality is calculated for graph edges, returning the input 'graph' with an additional 'centrality' column; otherwise centrality is calculated for vertices, returning the equivalent of 'dodgr_vertices(graph)', with an additional vertex-based 'centrality' column.

column

Column of graph defining the edge properties used to calculate centrality (see Note).

vert_wts

Optional vector of length equal to number of vertices (nrow(dodgr_vertices(graph))), to enable centrality to be calculated in weighted form, such that centrality measured from each vertex will be weighted by the specified amount.

dist_threshold

If not 'NULL', only calculate centrality for each point out to specified threshold. Setting values for this will result in approximate estimates for centrality, yet with considerable gains in computational efficiency. For sufficiently large values, approximations will be accurate to within some constant multiplier. Appropriate values can be established via the estimate_centrality_threshold function.

heap

Type of heap to use in priority queue. Options include Fibonacci Heap (default; 'FHeap'), Binary Heap ('BHeap'), Trinomial Heap ('TriHeap'), Extended Trinomial Heap ('TriHeapExt', and 2-3 Heap ('Heap23').

check_graph

If TRUE, graph is first checked for duplicate edges, which can cause incorrect centrality calculations. If duplicate edges are detected in an interactive session, a prompt will ask whether you want to proceed or rectify edges first. This value may be set to FALSE to skip this check and the interactive prompt.

Value

Modified version of graph with additional 'centrality' column added.

Note

The column parameter is by default d_weighted, meaning centrality is calculated by routing according to weighted distances. Other possible values for this parameter are

  • d for unweighted distances

  • time for unweighted time-based routing

  • time_weighted for weighted time-based routing

Centrality is calculated by default using parallel computation with the maximal number of available cores or threads. This number can be reduced by specifying a value via ⁠RcppParallel::setThreadOptions (numThreads = <desired_number>)⁠.

See Also

Other centrality: estimate_centrality_threshold(), estimate_centrality_time()

Examples

## Not run: 
graph_full <- weight_streetnet (hampi)
graph <- dodgr_contract_graph (graph_full)
graph <- dodgr_centrality (graph)
# 'graph' is then the contracted graph with an additional 'centrality' column
# Same calculation via 'igraph':
igr <- dodgr_to_igraph (graph)
library (igraph)
cent <- edge_betweenness (igr)
identical (cent, graph$centrality) # TRUE
# Values of centrality between all junctions in the contracted graph can then
# be mapped back onto the original full network by "uncontracting":
graph_full <- dodgr_uncontract_graph (graph)
# For visualisation, it is generally necessary to merge the directed edges to
# form an equivalent undirected graph. Conversion to 'sf' format via
# 'dodgr_to_sf()' is also useful for many visualisation routines.
graph_sf <- merge_directed_graph (graph_full) %>%
    dodgr_to_sf ()

## End(Not run)

## Not run: 
library (mapview)
centrality <- graph_sf$centrality / max (graph_sf$centrality)
ncols <- 30
cols <- c ("lawngreen", "red")
cols <- colorRampPalette (cols) (ncols) [ceiling (ncols * centrality)]
mapview (graph_sf, color = cols, lwd = 10 * centrality)

## End(Not run)

# An example of flow aggregation across a generic (non-OSM) highway,
# represented as the 'routes_fast' object of the \pkg{stplanr} package,
# which is a SpatialLinesDataFrame containing commuter densities along
# components of a street network.
## Not run: 
library (stplanr)
# merge all of the 'routes_fast' lines into a single network
r <- overline (routes_fast, attrib = "length", buff_dist = 1)
r <- sf::st_as_sf (r)
# Convert to a 'dodgr' network, for which we need to specify both a 'type'
# and 'id' column.
r$type <- 1
r$id <- seq (nrow (r))
graph_full <- weight_streetnet (
    r,
    type_col = "type",
    id_col = "id",
    wt_profile = 1
)
# convert to contracted form, retaining junction vertices only, and append
# 'centrality' column
graph <- dodgr_contract_graph (graph_full) %>%
    dodgr_centrality ()
#' expand back to full graph; merge directed flows; and convert result to
# 'sf'-format for plotting
graph_sf <- dodgr_uncontract_graph (graph) %>%
    merge_directed_graph () %>%
    dodgr_to_sf ()
plot (graph_sf ["centrality"])

## End(Not run)

Identify connected components of graph.

Description

Identify connected components of graph and add corresponding component column to data.frame.

Usage

dodgr_components(graph)

Arguments

graph

A data.frame of edges

Value

Equivalent graph with additional component column, sequentially numbered from 1 = largest component.

See Also

Other modification: dodgr_contract_graph(), dodgr_uncontract_graph()

Examples

graph <- weight_streetnet (hampi)
graph <- dodgr_components (graph)

Contract graph to junction vertices only.

Description

Removes redundant (straight-line) vertices from graph, leaving only junction vertices.

Usage

dodgr_contract_graph(graph, verts = NULL, nocache = FALSE)

Arguments

graph

A flat table of graph edges. Must contain columns labelled from and to, or start and stop. May also contain similarly labelled columns of spatial coordinates (for example from_x) or stop_lon).

verts

Optional list of vertices to be retained as routing points. These must match the from and to columns of graph.

nocache

If FALSE (default), load cached version of contracted graph if previously calculated and cached. If TRUE, then re-contract graph even if previously calculated version has been stored in cache.

Value

A contracted version of the original graph, containing the same number of columns, but with each row representing an edge between two junction vertices (or between the submitted verts, which may or may not be junctions).

See Also

Other modification: dodgr_components(), dodgr_uncontract_graph()

Examples

graph <- weight_streetnet (hampi)
nrow (graph) # 5,973
graph <- dodgr_contract_graph (graph)
nrow (graph) # 662

Deduplicate edges in a graph

Description

Graph may have duplicated edges, particularly when extracted as dodgr_streetnet objects. This function de-duplicates any repeated edges, reducing weighted distances and times to the minimal values from all duplicates.

Usage

dodgr_deduplicate_graph(graph)

Arguments

graph

Any 'dodgr' graph or network.

Value

A potentially modified version of graph, with any formerly duplicated edges reduces to single rows containing minimal weighted distances and times.

See Also

Other conversion: dodgr_to_igraph(), dodgr_to_sf(), dodgr_to_sfc(), dodgr_to_tidygraph(), igraph_to_dodgr()


Calculate matrix of pair-wise distances between points.

Description

Alias for dodgr_dists

Usage

dodgr_distances(
  graph,
  from = NULL,
  to = NULL,
  shortest = TRUE,
  pairwise = FALSE,
  heap = "BHeap",
  parallel = TRUE,
  quiet = TRUE
)

Arguments

graph

data.frame or equivalent object representing the network graph (see Notes). For dodgr street networks, this may be a network derived from either sf or silicate ("sc") data, generated with weight_streetnet.

The from and to columns of graph may be either single columns of numeric or character values specifying the numbers or names of graph vertices, or combinations to two columns specifying geographical (longitude and latitude,) coordinates. In the latter case, almost any sensible combination of names will be accepted (for example, ⁠fromx, fromy⁠, ⁠from_x, from_y⁠, or ⁠fr_lat, fr_lon⁠.)

Note that longitude and latitude values are always interpreted in 'dodgr' to be in EPSG:4326 / WSG84 coordinates. Any other kinds of coordinates should first be reprojected to EPSG:4326 before submitting to any 'dodgr' routines.

See further information in Details.

from

Vector or matrix of points from which route distances are to be calculated, specified as one of the following:

  • Single character vector precisely matching node numbers or names given in graph$from or graph$to.

  • Single vector of integer-ish values, in which case these will be presumed to specify indices into dodgr_vertices, and NOT to correspond to values in the 'from' or 'to' columns of the graph. See the example below for a demonstration.

  • Matrix or equivalent of longitude and latitude coordinates, in which case these will be matched on to the nearest coordinates of 'from' and 'to' points in the graph.

to

Vector or matrix of points to which route distances are to be calculated. If to is NULL, pairwise distances will be calculated from all from points to all other nodes in graph. If both from and to are NULL, pairwise distances are calculated between all nodes in graph.

shortest

If FALSE, calculate distances along the fastest rather than shortest routes. For street networks produced with weight_streetnet, distances may also be calculated along the fastest routes with the shortest = FALSE option. Graphs must in this case have columns of time and time_weighted. Note that the fastest routes will only be approximate when derived from sf-format data generated with the osmdata function osmdata_sf(), and will be much more accurate when derived from sc-format data generated with osmdata_sc(). See weight_streetnet for details.

pairwise

If TRUE, calculate distances only between the ordered pairs of from and to.

heap

Type of heap to use in priority queue. Options include Fibonacci Heap (default; FHeap), Binary Heap (BHeap), ⁠Trinomial Heap (⁠TriHeap⁠), Extended Trinomial Heap (⁠TriHeapExt⁠, and 2-3 Heap (⁠Heap23').

parallel

If TRUE, perform routing calculation in parallel. Calculations in parallel ought very generally be advantageous. For small graphs, calculating distances in parallel is likely to offer relatively little gain in speed, but increases from parallel computation will generally markedly increase with increasing graph sizes. By default, parallel computation uses the maximal number of available cores or threads. This number can be reduced by specifying a value via ⁠RcppParallel::setThreadOptions (numThreads = <desired_number>)⁠. Parallel calculations are, however, not able to be interrupted (for example, by Ctrl-C), and can only be stopped by killing the R process.

quiet

If FALSE, display progress messages on screen.

Details

graph must minimally contain three columns of from, to, dist. If an additional column named weight or wt is present, shortest paths are calculated according to values specified in that column; otherwise according to dist values. Either way, final distances between from and to points are calculated by default according to values of dist. That is, paths between any pair of points will be calculated according to the minimal total sum of weight values (if present), while reported distances will be total sums of dist values.

Value

square matrix of distances between nodes

See Also

Other distances: dodgr_dists(), dodgr_dists_categorical(), dodgr_dists_nearest(), dodgr_flows_aggregate(), dodgr_flows_disperse(), dodgr_flows_si(), dodgr_isochrones(), dodgr_isodists(), dodgr_isoverts(), dodgr_paths(), dodgr_times()

Examples

# A simple graph
graph <- data.frame (
    from = c ("A", "B", "B", "B", "C", "C", "D", "D"),
    to = c ("B", "A", "C", "D", "B", "D", "C", "A"),
    d = c (1, 2, 1, 3, 2, 1, 2, 1)
)
dodgr_dists (graph)

# Example of "from" and "to" as integer-ish values, in which case they are
# interpreted to index into "dodgr_vertices()":
graph <- data.frame (
    from = c (1, 3, 2, 2, 3, 3, 4, 4),
    to = c (2, 1, 3, 4, 2, 4, 3, 1),
    d = c (1, 2, 1, 3, 2, 1, 2, 1)
)
dodgr_dists (graph, from = 1, to = 2)
# That then gives distance from "1" to "3" because the vertices are built
# sequentially along "graph$from":
dodgr_vertices (graph)
# And vertex$id [2] is "3"

# A larger example from the included [hampi()] data.
graph <- weight_streetnet (hampi)
from <- sample (graph$from_id, size = 100)
to <- sample (graph$to_id, size = 50)
d <- dodgr_dists (graph, from = from, to = to)
# d is a 100-by-50 matrix of distances between `from` and `to`

## Not run: 
# a more complex street network example, thanks to @chrijo; see
# https://github.com/UrbanAnalyst/dodgr/issues/47

xy <- rbind (
    c (7.005994, 51.45774), # limbeckerplatz 1 essen germany
    c (7.012874, 51.45041)
) # hauptbahnhof essen germany
xy <- data.frame (lon = xy [, 1], lat = xy [, 2])
essen <- dodgr_streetnet (pts = xy, expand = 0.2, quiet = FALSE)
graph <- weight_streetnet (essen, wt_profile = "foot")
d <- dodgr_dists (graph, from = xy, to = xy)
# First reason why this does not work is because the graph has multiple,
# disconnected components.
table (graph$component)
# reduce to largest connected component, which is always number 1
graph <- graph [which (graph$component == 1), ]
d <- dodgr_dists (graph, from = xy, to = xy)
# should work, but even then note that
table (essen$level)
# There are parts of the network on different building levels (because of
# shopping malls and the like). These may or may not be connected, so it may
# be necessary to filter out particular levels
index <- which (!(essen$level == "-1" | essen$level == "1")) # for example
library (sf) # needed for following sub-select operation
essen <- essen [index, ]
graph <- weight_streetnet (essen, wt_profile = "foot")
graph <- graph [which (graph$component == 1), ]
d <- dodgr_dists (graph, from = xy, to = xy)

## End(Not run)

Calculate matrix of pair-wise distances between points.

Description

Calculate matrix of pair-wise distances between points.

Usage

dodgr_dists(
  graph,
  from = NULL,
  to = NULL,
  shortest = TRUE,
  pairwise = FALSE,
  heap = "BHeap",
  parallel = TRUE,
  quiet = TRUE
)

Arguments

graph

data.frame or equivalent object representing the network graph (see Notes). For dodgr street networks, this may be a network derived from either sf or silicate ("sc") data, generated with weight_streetnet.

The from and to columns of graph may be either single columns of numeric or character values specifying the numbers or names of graph vertices, or combinations to two columns specifying geographical (longitude and latitude,) coordinates. In the latter case, almost any sensible combination of names will be accepted (for example, ⁠fromx, fromy⁠, ⁠from_x, from_y⁠, or ⁠fr_lat, fr_lon⁠.)

Note that longitude and latitude values are always interpreted in 'dodgr' to be in EPSG:4326 / WSG84 coordinates. Any other kinds of coordinates should first be reprojected to EPSG:4326 before submitting to any 'dodgr' routines.

See further information in Details.

from

Vector or matrix of points from which route distances are to be calculated, specified as one of the following:

  • Single character vector precisely matching node numbers or names given in graph$from or graph$to.

  • Single vector of integer-ish values, in which case these will be presumed to specify indices into dodgr_vertices, and NOT to correspond to values in the 'from' or 'to' columns of the graph. See the example below for a demonstration.

  • Matrix or equivalent of longitude and latitude coordinates, in which case these will be matched on to the nearest coordinates of 'from' and 'to' points in the graph.

to

Vector or matrix of points to which route distances are to be calculated. If to is NULL, pairwise distances will be calculated from all from points to all other nodes in graph. If both from and to are NULL, pairwise distances are calculated between all nodes in graph.

shortest

If FALSE, calculate distances along the fastest rather than shortest routes. For street networks produced with weight_streetnet, distances may also be calculated along the fastest routes with the shortest = FALSE option. Graphs must in this case have columns of time and time_weighted. Note that the fastest routes will only be approximate when derived from sf-format data generated with the osmdata function osmdata_sf(), and will be much more accurate when derived from sc-format data generated with osmdata_sc(). See weight_streetnet for details.

pairwise

If TRUE, calculate distances only between the ordered pairs of from and to.

heap

Type of heap to use in priority queue. Options include Fibonacci Heap (default; FHeap), Binary Heap (BHeap), ⁠Trinomial Heap (⁠TriHeap⁠), Extended Trinomial Heap (⁠TriHeapExt⁠, and 2-3 Heap (⁠Heap23').

parallel

If TRUE, perform routing calculation in parallel. Calculations in parallel ought very generally be advantageous. For small graphs, calculating distances in parallel is likely to offer relatively little gain in speed, but increases from parallel computation will generally markedly increase with increasing graph sizes. By default, parallel computation uses the maximal number of available cores or threads. This number can be reduced by specifying a value via ⁠RcppParallel::setThreadOptions (numThreads = <desired_number>)⁠. Parallel calculations are, however, not able to be interrupted (for example, by Ctrl-C), and can only be stopped by killing the R process.

quiet

If FALSE, display progress messages on screen.

Details

graph must minimally contain three columns of from, to, dist. If an additional column named weight or wt is present, shortest paths are calculated according to values specified in that column; otherwise according to dist values. Either way, final distances between from and to points are calculated by default according to values of dist. That is, paths between any pair of points will be calculated according to the minimal total sum of weight values (if present), while reported distances will be total sums of dist values.

Value

square matrix of distances between nodes

See Also

Other distances: dodgr_distances(), dodgr_dists_categorical(), dodgr_dists_nearest(), dodgr_flows_aggregate(), dodgr_flows_disperse(), dodgr_flows_si(), dodgr_isochrones(), dodgr_isodists(), dodgr_isoverts(), dodgr_paths(), dodgr_times()

Examples

# A simple graph
graph <- data.frame (
    from = c ("A", "B", "B", "B", "C", "C", "D", "D"),
    to = c ("B", "A", "C", "D", "B", "D", "C", "A"),
    d = c (1, 2, 1, 3, 2, 1, 2, 1)
)
dodgr_dists (graph)

# Example of "from" and "to" as integer-ish values, in which case they are
# interpreted to index into "dodgr_vertices()":
graph <- data.frame (
    from = c (1, 3, 2, 2, 3, 3, 4, 4),
    to = c (2, 1, 3, 4, 2, 4, 3, 1),
    d = c (1, 2, 1, 3, 2, 1, 2, 1)
)
dodgr_dists (graph, from = 1, to = 2)
# That then gives distance from "1" to "3" because the vertices are built
# sequentially along "graph$from":
dodgr_vertices (graph)
# And vertex$id [2] is "3"

# A larger example from the included [hampi()] data.
graph <- weight_streetnet (hampi)
from <- sample (graph$from_id, size = 100)
to <- sample (graph$to_id, size = 50)
d <- dodgr_dists (graph, from = from, to = to)
# d is a 100-by-50 matrix of distances between `from` and `to`

## Not run: 
# a more complex street network example, thanks to @chrijo; see
# https://github.com/UrbanAnalyst/dodgr/issues/47

xy <- rbind (
    c (7.005994, 51.45774), # limbeckerplatz 1 essen germany
    c (7.012874, 51.45041)
) # hauptbahnhof essen germany
xy <- data.frame (lon = xy [, 1], lat = xy [, 2])
essen <- dodgr_streetnet (pts = xy, expand = 0.2, quiet = FALSE)
graph <- weight_streetnet (essen, wt_profile = "foot")
d <- dodgr_dists (graph, from = xy, to = xy)
# First reason why this does not work is because the graph has multiple,
# disconnected components.
table (graph$component)
# reduce to largest connected component, which is always number 1
graph <- graph [which (graph$component == 1), ]
d <- dodgr_dists (graph, from = xy, to = xy)
# should work, but even then note that
table (essen$level)
# There are parts of the network on different building levels (because of
# shopping malls and the like). These may or may not be connected, so it may
# be necessary to filter out particular levels
index <- which (!(essen$level == "-1" | essen$level == "1")) # for example
library (sf) # needed for following sub-select operation
essen <- essen [index, ]
graph <- weight_streetnet (essen, wt_profile = "foot")
graph <- graph [which (graph$component == 1), ]
d <- dodgr_dists (graph, from = xy, to = xy)

## End(Not run)

Cumulative distances along different edge categories

Description

Cumulative distances along different edge categories

Usage

dodgr_dists_categorical(
  graph,
  from = NULL,
  to = NULL,
  proportions_only = FALSE,
  pairwise = FALSE,
  dlimit = NULL,
  heap = "BHeap",
  quiet = TRUE
)

Arguments

graph

data.frame or equivalent object representing the network graph which must have a column named "edge_type" which labels categories of edge types along which categorical distances are to be aggregated (see Note).

from

Vector or matrix of points from which route distances are to be calculated, specified as one of the following:

  • Single character vector precisely matching node numbers or names given in graph$from or graph$to.

  • Single vector of integer-ish values, in which case these will be presumed to specify indices into dodgr_vertices, and NOT to correspond to values in the 'from' or 'to' columns of the graph. See the example below for a demonstration.

  • Matrix or equivalent of longitude and latitude coordinates, in which case these will be matched on to the nearest coordinates of 'from' and 'to' points in the graph.

to

Vector or matrix of points to which route distances are to be calculated. If to is NULL, pairwise distances will be calculated from all from points to all other nodes in graph. If both from and to are NULL, pairwise distances are calculated between all nodes in graph.

proportions_only

If FALSE, return distance matrices for full distances and for each edge category; if TRUE, return single vector of proportional distances, like the summary function applied to full results. See Note.

pairwise

If TRUE, calculate distances only between the ordered pairs of from and to. In this case, neither the proportions_only nor dlimit parameters have any effect, and the result is a single matrix with one row for each pair of from-to points, and one column for each category.

dlimit

If no value to to is given, distances are aggregated from each from point out to the specified distance limit (in the same units as the edge distances of the input graph). dlimit only has any effect if to is not specified, in which case the proportions_only argument has no effect.

heap

Type of heap to use in priority queue. Options include Fibonacci Heap (default; FHeap), Binary Heap (BHeap), ⁠Trinomial Heap (⁠TriHeap⁠), Extended Trinomial Heap (⁠TriHeapExt⁠, and 2-3 Heap (⁠Heap23').

quiet

If FALSE, display progress messages on screen.

Value

If to is specified, a list of distance matrices of equal dimensions (length(from), length(to)), the first of which ("distance") holds the final distances, while the rest are one matrix for each unique value of "edge_type", holding the distances traversed along those types of edges only. Otherwise, a single matrix of total distances along all ways from each point out to the specified value of dlimit, along with distances along each of the different kinds of ways specified in the "edge_type" column of the input graph.

Note

The "edge_type" column in the graph can contain any kind of discrete or categorical values, although integer values of 0 are not permissible. NA values are ignored. The function requires one full distance matrix to be stored for each category of "edge_type" (unless proportions_only = TRUE). It is wise to keep numbers of discrete types as low as possible, especially for large distance matrices.

Setting the proportions_only flag to TRUE may be advantageous for large jobs, because this avoids construction of the full matrices. This may speed up calculations, but perhaps more importantly it may make possible calculations which would otherwise require distance matrices too large to be directly stored.

Calculations are not able to be interrupted (for example, by Ctrl-C), and can only be stopped by killing the R process.

See Also

Other distances: dodgr_distances(), dodgr_dists(), dodgr_dists_nearest(), dodgr_flows_aggregate(), dodgr_flows_disperse(), dodgr_flows_si(), dodgr_isochrones(), dodgr_isodists(), dodgr_isoverts(), dodgr_paths(), dodgr_times()

Examples

# Prepare a graph for categorical routing by including an "edge_type" column
graph <- weight_streetnet (hampi, wt_profile = "foot")
graph <- graph [graph$component == 1, ]
graph$edge_type <- graph$highway
# Define start and end points for categorical distances; using all vertices
# here.
length (unique (graph$edge_type)) # Number of categories
v <- dodgr_vertices (graph)
from <- to <- v$id [1:100]
d <- dodgr_dists_categorical (graph, from, to)
class (d)
length (d)
sapply (d, dim)
# 9 distance matrices, all of same dimensions, first of which is standard
# distance matrix
s <- summary (d) # print summary as proportions along each "edge_type"
# or directly calculate proportions only
dodgr_dists_categorical (graph, from, to,
    proportions_only = TRUE
)

# Pairwise distances return single matrix with number of rows equal to 'from'
# / 'to', and number of columns equal to number of edge types plus one for
# total distances.
d <- dodgr_dists_categorical (graph, from, to, pairwise = TRUE)
class (d)
dim (d)

# The 'dlimit' parameter can be used to calculate total distances along each
# category of edges from a set of points out to specified threshold:
dlimit <- 2000 # in metres
d <- dodgr_dists_categorical (graph, from, dlimit = dlimit)
dim (d) # length(from), length(unique(edge_type)) + 1

Calculate vector of shortest distances from a series of 'from' points to nearest one of series of 'to' points.

Description

Calculate vector of shortest distances from a series of 'from' points to nearest one of series of 'to' points.

Usage

dodgr_dists_nearest(
  graph,
  from = NULL,
  to = NULL,
  shortest = TRUE,
  heap = "BHeap",
  quiet = TRUE
)

Arguments

graph

data.frame or equivalent object representing the network graph (see Notes). For dodgr street networks, this may be a network derived from either sf or silicate ("sc") data, generated with weight_streetnet.

The from and to columns of graph may be either single columns of numeric or character values specifying the numbers or names of graph vertices, or combinations to two columns specifying geographical (longitude and latitude,) coordinates. In the latter case, almost any sensible combination of names will be accepted (for example, ⁠fromx, fromy⁠, ⁠from_x, from_y⁠, or ⁠fr_lat, fr_lon⁠.)

Note that longitude and latitude values are always interpreted in 'dodgr' to be in EPSG:4326 / WSG84 coordinates. Any other kinds of coordinates should first be reprojected to EPSG:4326 before submitting to any 'dodgr' routines.

See further information in Details.

from

Vector or matrix of points from which route distances are to be calculated, specified as one of the following:

  • Single character vector precisely matching node numbers or names given in graph$from or graph$to.

  • Single vector of integer-ish values, in which case these will be presumed to specify indices into dodgr_vertices, and NOT to correspond to values in the 'from' or 'to' columns of the graph. See the example below for a demonstration.

  • Matrix or equivalent of longitude and latitude coordinates, in which case these will be matched on to the nearest coordinates of 'from' and 'to' points in the graph.

to

Vector or matrix of points to which route distances are to be calculated. If to is NULL, pairwise distances will be calculated from all from points to all other nodes in graph. If both from and to are NULL, pairwise distances are calculated between all nodes in graph.

shortest

If FALSE, calculate distances along the fastest rather than shortest routes. For street networks produced with weight_streetnet, distances may also be calculated along the fastest routes with the shortest = FALSE option. Graphs must in this case have columns of time and time_weighted. Note that the fastest routes will only be approximate when derived from sf-format data generated with the osmdata function osmdata_sf(), and will be much more accurate when derived from sc-format data generated with osmdata_sc(). See weight_streetnet for details.

heap

Type of heap to use in priority queue. Options include Fibonacci Heap (default; FHeap), Binary Heap (BHeap), ⁠Trinomial Heap (⁠TriHeap⁠), Extended Trinomial Heap (⁠TriHeapExt⁠, and 2-3 Heap (⁠Heap23').

quiet

If FALSE, display progress messages on screen.

Value

Vector of distances, one element for each 'from' point giving the distance to the nearest 'to' point.

Note

graph must minimally contain three columns of from, to, dist. If an additional column named weight or wt is present, shortest paths are calculated according to values specified in that column; otherwise according to dist values. Either way, final distances between from and to points are calculated by default according to values of dist. That is, paths between any pair of points will be calculated according to the minimal total sum of weight values (if present), while reported distances will be total sums of dist values.

For street networks produced with weight_streetnet, distances may also be calculated along the fastest routes with the shortest = FALSE option. Graphs must in this case have columns of time and time_weighted. Note that the fastest routes will only be approximate when derived from sf-format data generated with the osmdata function osmdata_sf(), and will be much more accurate when derived from sc-format data generated with osmdata_sc(). See weight_streetnet for details.

The from and to columns of graph may be either single columns of numeric or character values specifying the numbers or names of graph vertices, or combinations to two columns specifying geographical (longitude and latitude) coordinates. In the latter case, almost any sensible combination of names will be accepted (for example, ⁠fromx, fromy⁠, ⁠from_x, from_y⁠, or ⁠fr_lat, fr_lon⁠.)

from and to values can be either two-column matrices or equivalent of longitude and latitude coordinates, or else single columns precisely matching node numbers or names given in graph$from or graph$to. If to is NULL, pairwise distances are calculated from all from points to all other nodes in graph. If both from and to are NULL, pairwise distances are calculated between all nodes in graph.

Calculations are always calculated in parallel, using multiple threads.

See Also

Other distances: dodgr_distances(), dodgr_dists(), dodgr_dists_categorical(), dodgr_flows_aggregate(), dodgr_flows_disperse(), dodgr_flows_si(), dodgr_isochrones(), dodgr_isodists(), dodgr_isoverts(), dodgr_paths(), dodgr_times()

Examples

# A simple graph
graph <- data.frame (
    from = c ("A", "B", "B", "B", "C", "C", "D", "D"),
    to = c ("B", "A", "C", "D", "B", "D", "C", "A"),
    d = c (1, 2, 1, 3, 2, 1, 2, 1)
)
dodgr_dists (graph)

# A larger example from the included [hampi()] data.
graph <- weight_streetnet (hampi)
from <- sample (graph$from_id, size = 100)
to <- sample (graph$to_id, size = 50)
d <- dodgr_dists (graph, from = from, to = to)
# d is a 100-by-50 matrix of distances between `from` and `to`

## Not run: 
# a more complex street network example, thanks to @chrijo; see
# https://github.com/UrbanAnalyst/dodgr/issues/47

xy <- rbind (
    c (7.005994, 51.45774), # limbeckerplatz 1 essen germany
    c (7.012874, 51.45041)
) # hauptbahnhof essen germany
xy <- data.frame (lon = xy [, 1], lat = xy [, 2])
essen <- dodgr_streetnet (pts = xy, expand = 0.2, quiet = FALSE)
graph <- weight_streetnet (essen, wt_profile = "foot")
d <- dodgr_dists (graph, from = xy, to = xy)
# First reason why this does not work is because the graph has multiple,
# disconnected components.
table (graph$component)
# reduce to largest connected component, which is always number 1
graph <- graph [which (graph$component == 1), ]
d <- dodgr_dists (graph, from = xy, to = xy)
# should work, but even then note that
table (essen$level)
# There are parts of the network on different building levels (because of
# shopping malls and the like). These may or may not be connected, so it may
# be necessary to filter out particular levels
index <- which (!(essen$level == "-1" | essen$level == "1")) # for example
library (sf) # needed for following sub-select operation
essen <- essen [index, ]
graph <- weight_streetnet (essen, wt_profile = "foot")
graph <- graph [which (graph$component == 1), ]
d <- dodgr_dists (graph, from = xy, to = xy)

## End(Not run)

Create a map of dodgr flows.

Description

Create a map of the output of dodgr_flows_aggregate or dodgr_flows_disperse

Usage

dodgr_flowmap(net, bbox = NULL, linescale = 1)

Arguments

net

A street network with a flow column obtained from dodgr_flows_aggregate or dodgr_flows_disperse

bbox

If given, scale the map to this bbox, otherwise use entire extend of net

linescale

Maximal thickness of plotted lines

Note

net should be first passed through merge_directed_graph prior to plotting, otherwise lines for different directions will be overlaid.

See Also

Other misc: compare_heaps(), dodgr_full_cycles(), dodgr_fundamental_cycles(), dodgr_insert_vertex(), dodgr_sample(), dodgr_sflines_to_poly(), dodgr_vertices(), merge_directed_graph(), summary.dodgr_dists_categorical(), write_dodgr_wt_profile()

Examples

graph <- weight_streetnet (hampi)
from <- sample (graph$from_id, size = 10)
to <- sample (graph$to_id, size = 5)
to <- to [!to %in% from]
flows <- matrix (
    10 * runif (length (from) * length (to)),
    nrow = length (from)
)
graph <- dodgr_flows_aggregate (graph, from = from, to = to, flows = flows)
# graph then has an additonal 'flows` column of aggregate flows along all
# edges. These flows are directed, and can be aggregated to equivalent
# undirected flows on an equivalent undirected graph with:
graph_undir <- merge_directed_graph (graph)
## Not run: 
dodgr_flowmap (graph_undir)

## End(Not run)

Aggregate flows throughout a network.

Description

Aggregate flows throughout a network based on an input matrix of flows between all pairs of from and to points.

Usage

dodgr_flows_aggregate(
  graph,
  from,
  to,
  flows,
  pairwise = FALSE,
  contract = TRUE,
  heap = "BHeap",
  tol = 0.000000000001,
  norm_sums = TRUE,
  quiet = TRUE
)

Arguments

graph

data.frame or equivalent object representing the network graph (see Details)

from

Vector or matrix of points from which route distances are to be calculated, specified as one of the following:

  • Single character vector precisely matching node numbers or names given in graph$from or graph$to.

  • Single vector of integer-ish values, in which case these will be presumed to specify indices into dodgr_vertices, and NOT to correspond to values in the 'from' or 'to' columns of the graph. See the example below for a demonstration.

  • Matrix or equivalent of longitude and latitude coordinates, in which case these will be matched on to the nearest coordinates of 'from' and 'to' points in the graph.

to

Vector or matrix of points to which route distances are to be calculated. If to is NULL, pairwise distances will be calculated from all from points to all other nodes in graph. If both from and to are NULL, pairwise distances are calculated between all nodes in graph.

flows

Matrix of flows with nrow(flows)==length(from) and ncol(flows)==length(to).

pairwise

If TRUE, aggregate flows only only paths connecting the ordered pairs of from and to. In this case, both from and to must be of the same length, and flows must be either a vector of the same length, or a matrix with only one column and same number of rows. flows then quantifies the flows between each pair of from and to points.

contract

If TRUE (default), calculate flows on contracted graph before mapping them back on to the original full graph (recommended as this will generally be much faster). FALSE should only be used if the graph has already been contracted.

heap

Type of heap to use in priority queue. Options include Fibonacci Heap (default; FHeap), Binary Heap (BHeap), Trinomial Heap (TriHeap), Extended Trinomial Heap (TriHeapExt, and 2-3 Heap (Heap23).

tol

Relative tolerance below which flows towards to vertices are not considered. This will generally have no effect, but can provide speed gains when flow matrices represent spatial interaction models, in which case this parameter effectively reduces the radius from each from point over which flows are aggregated. To remove any such effect, set tol = 0.

norm_sums

Standardise sums from all origin points, so sum of flows throughout entire network equals sum of densities from all origins (see Note).

quiet

If FALSE, display progress messages on screen.

Value

Modified version of graph with additional flow column added.

Note

Spatial Interaction models are often fitted through trialling a range of values of 'k'. The specification above allows fitting multiple values of 'k' to be done with a single call, in a way that is far more efficient than making multiple calls. A matrix of 'k' values may be entered, with each column holding a different vector of values, one for each 'from' point. For a matrix of 'k' values having 'n' columns, the return object will be a modified version in the input 'graph', with an additional 'n' columns, named 'flow1', 'flow2', ... up to 'n'. These columns must be subsequently matched by the user back on to the corresponding columns of the matrix of 'k' values.

The norm_sums parameter should be used whenever densities at origins and destinations are absolute values, and ensures that the sum of resultant flow values throughout the entire network equals the sum of densities at all origins. For example, with norm_sums = TRUE (the default), a flow from a single origin with density one to a single destination along two edges will allocate flows of one half to each of those edges, such that the sum of flows across the network will equal one, or the sum of densities from all origins. The norm_sums = TRUE option is appropriate where densities are relative values, and ensures that each edge maintains relative proportions. In the above example, flows along each of two edges would equal one, for a network sum of two, or greater than the sum of densities.

Flows are calculated by default using parallel computation with the maximal number of available cores or threads. This number can be reduced by specifying a value via ⁠RcppParallel::setThreadOptions (numThreads = <desired_number>)⁠.

See Also

Other distances: dodgr_distances(), dodgr_dists(), dodgr_dists_categorical(), dodgr_dists_nearest(), dodgr_flows_disperse(), dodgr_flows_si(), dodgr_isochrones(), dodgr_isodists(), dodgr_isoverts(), dodgr_paths(), dodgr_times()

Examples

graph <- weight_streetnet (hampi)
from <- sample (graph$from_id, size = 10)
to <- sample (graph$to_id, size = 5)
to <- to [!to %in% from]
flows <- matrix (10 * runif (length (from) * length (to)),
    nrow = length (from)
)
graph <- dodgr_flows_aggregate (graph, from = from, to = to, flows = flows)
# graph then has an additonal 'flows' column of aggregate flows along all
# edges. These flows are directed, and can be aggregated to equivalent
# undirected flows on an equivalent undirected graph with:
graph_undir <- merge_directed_graph (graph)
# This graph will only include those edges having non-zero flows, and so:
nrow (graph)
nrow (graph_undir) # the latter is much smaller

# The following code can be used to convert the resultant graph to an `sf`
# object suitable for plotting
## Not run: 
gsf <- dodgr_to_sf (graph_undir)

# example of plotting with the 'mapview' package
library (mapview)
flow <- gsf$flow / max (gsf$flow)
ncols <- 30
cols <- c ("lawngreen", "red")
colranmp <- colorRampPalette (cols) (ncols) [ceiling (ncols * flow)]
mapview (gsf, color = colranmp, lwd = 10 * flow)

## End(Not run)

# An example of flow aggregation across a generic (non-OSM) highway,
# represented as the `routes_fast` object of the \pkg{stplanr} package,
# which is a SpatialLinesDataFrame containing commuter densities along
# components of a street network.
## Not run: 
library (stplanr)
# merge all of the 'routes_fast' lines into a single network
r <- overline (routes_fast, attrib = "length", buff_dist = 1)
r <- sf::st_as_sf (r)
# then extract the start and end points of each of the original 'routes_fast'
# lines and use these for routing with `dodgr`
l <- lapply (routes_fast@lines, function (i) {
    c (
        sp::coordinates (i) [[1]] [1, ],
        tail (sp::coordinates (i) [[1]], 1)
    )
})
l <- do.call (rbind, l)
xy_start <- l [, 1:2]
xy_end <- l [, 3:4]
# Then just specify a generic OD matrix with uniform values of 1:
flows <- matrix (1, nrow = nrow (l), ncol = nrow (l))
# We need to specify both a `type` and `id` column for the
# \link{weight_streetnet} function.
r$type <- 1
r$id <- seq (nrow (r))
graph <- weight_streetnet (
    r,
    type_col = "type",
    id_col = "id",
    wt_profile = 1
)
f <- dodgr_flows_aggregate (
    graph,
    from = xy_start,
    to = xy_end,
    flows = flows
)
# Then merge directed flows and convert to \pkg{sf} for plotting as before:
f <- merge_directed_graph (f)
geoms <- dodgr_to_sfc (f)
gc <- dodgr_contract_graph (f)
gsf <- sf::st_sf (geoms)
gsf$flow <- gc$flow
# sf plot:
plot (gsf ["flow"])

## End(Not run)

Aggregate flows dispersed from each point in a network.

Description

Disperse flows throughout a network based on a input vectors of origin points and associated densities

Usage

dodgr_flows_disperse(
  graph,
  from,
  dens,
  k = 500,
  contract = TRUE,
  heap = "BHeap",
  tol = 0.000000000001,
  quiet = TRUE
)

Arguments

graph

data.frame or equivalent object representing the network graph (see Details)

from

Vector or matrix of points from which aggregate dispersed flows are to be calculated (see Details)

dens

Vectors of densities corresponding to the from points

k

Width coefficient of exponential diffusion function defined as exp(-d/k), in units of distance column of graph (metres by default). Can also be a vector with same length as from, giving dispersal coefficients from each point. If value of k<0 is given, a standard logistic polynomial will be used.

contract

If TRUE (default), calculate flows on contracted graph before mapping them back on to the original full graph (recommended as this will generally be much faster). FALSE should only be used if the graph has already been contracted.

heap

Type of heap to use in priority queue. Options include Fibonacci Heap (default; FHeap), Binary Heap (BHeap), Trinomial Heap (TriHeap), Extended Trinomial Heap (TriHeapExt, and 2-3 Heap (Heap23).

tol

Relative tolerance below which dispersal is considered to have finished. This parameter can generally be ignored; if in doubt, its effect can be removed by setting tol = 0.

quiet

If FALSE, display progress messages on screen.

Value

Modified version of graph with additional flow column added.

Note

Spatial Interaction models are often fitted through trialling a range of values of 'k'. The specification above allows fitting multiple values of 'k' to be done with a single call, in a way that is far more efficient than making multiple calls. A matrix of 'k' values may be entered, with each column holding a different vector of values, one for each 'from' point. For a matrix of 'k' values having 'n' columns, the return object will be a modified version in the input 'graph', with an additional 'n' columns, named 'flow1', 'flow2', ... up to 'n'. These columns must be subsequently matched by the user back on to the corresponding columns of the matrix of 'k' values.

See Also

Other distances: dodgr_distances(), dodgr_dists(), dodgr_dists_categorical(), dodgr_dists_nearest(), dodgr_flows_aggregate(), dodgr_flows_si(), dodgr_isochrones(), dodgr_isodists(), dodgr_isoverts(), dodgr_paths(), dodgr_times()

Examples

graph <- weight_streetnet (hampi)
from <- sample (graph$from_id, size = 10)
dens <- rep (1, length (from)) # Uniform densities
graph <- dodgr_flows_disperse (graph, from = from, dens = dens)
# graph then has an additonal 'flows` column of aggregate flows along all
# edges. These flows are directed, and can be aggregated to equivalent
# undirected flows on an equivalent undirected graph with:
graph_undir <- merge_directed_graph (graph)

Aggregate flows throughout a network using a spatial interaction model.

Description

Aggregate flows throughout a network using an exponential Spatial Interaction (SI) model between a specified set of origin and destination points, and associated vectors of densities.

Usage

dodgr_flows_si(
  graph,
  from,
  to,
  k = 500,
  dens_from = NULL,
  dens_to = NULL,
  contract = TRUE,
  norm_sums = TRUE,
  heap = "BHeap",
  tol = 0.000000000001,
  quiet = TRUE
)

Arguments

graph

data.frame or equivalent object representing the network graph (see Details)

from

Vector or matrix of points from which route distances are to be calculated, specified as one of the following:

  • Single character vector precisely matching node numbers or names given in graph$from or graph$to.

  • Single vector of integer-ish values, in which case these will be presumed to specify indices into dodgr_vertices, and NOT to correspond to values in the 'from' or 'to' columns of the graph. See the example below for a demonstration.

  • Matrix or equivalent of longitude and latitude coordinates, in which case these will be matched on to the nearest coordinates of 'from' and 'to' points in the graph.

to

Vector or matrix of points to which route distances are to be calculated. If to is NULL, pairwise distances will be calculated from all from points to all other nodes in graph. If both from and to are NULL, pairwise distances are calculated between all nodes in graph.

k

Width of exponential spatial interaction function (exp (-d / k)), in units of 'd', specified in one of 3 forms: (i) a single value; (ii) a vector of independent values for each origin point (with same length as 'from' points); or (iii) an equivalent matrix with each column holding values for each 'from' point, so 'nrow(k)==length(from)'. See Note.

dens_from

Vector of densities at origin ('from') points

dens_to

Vector of densities at destination ('to') points

contract

If TRUE (default), calculate flows on contracted graph before mapping them back on to the original full graph (recommended as this will generally be much faster). FALSE should only be used if the graph has already been contracted.

norm_sums

Standardise sums from all origin points, so sum of flows throughout entire network equals sum of densities from all origins (see Note).

heap

Type of heap to use in priority queue. Options include Fibonacci Heap (default; FHeap), Binary Heap (BHeap), Trinomial Heap (TriHeap), Extended Trinomial Heap (TriHeapExt, and 2-3 Heap (Heap23).

tol

Relative tolerance below which flows towards to vertices are not considered. This will generally have no effect, but can provide speed gains when flow matrices represent spatial interaction models, in which case this parameter effectively reduces the radius from each from point over which flows are aggregated. To remove any such effect, set tol = 0.

quiet

If FALSE, display progress messages on screen.

Value

Modified version of graph with additional flow column added.

Note

Spatial Interaction models are often fitted through trialling a range of values of 'k'. The specification above allows fitting multiple values of 'k' to be done with a single call, in a way that is far more efficient than making multiple calls. A matrix of 'k' values may be entered, with each column holding a different vector of values, one for each 'from' point. For a matrix of 'k' values having 'n' columns, the return object will be a modified version in the input 'graph', with an additional 'n' columns, named 'flow1', 'flow2', ... up to 'n'. These columns must be subsequently matched by the user back on to the corresponding columns of the matrix of 'k' values.

The norm_sums parameter should be used whenever densities at origins and destinations are absolute values, and ensures that the sum of resultant flow values throughout the entire network equals the sum of densities at all origins. For example, with norm_sums = TRUE (the default), a flow from a single origin with density one to a single destination along two edges will allocate flows of one half to each of those edges, such that the sum of flows across the network will equal one, or the sum of densities from all origins. The norm_sums = TRUE option is appropriate where densities are relative values, and ensures that each edge maintains relative proportions. In the above example, flows along each of two edges would equal one, for a network sum of two, or greater than the sum of densities.

With norm_sums = TRUE, the sum of network flows (sum(output$flow)) should equal the sum of origin densities (sum(dens_from)). This may nevertheless not always be the case, because origin points may simply be too far from any destination (to) points for an exponential model to yield non-zero values anywhere in a network within machine tolerance. Such cases may result in sums of output flows being less than sums of input densities.

See Also

Other distances: dodgr_distances(), dodgr_dists(), dodgr_dists_categorical(), dodgr_dists_nearest(), dodgr_flows_aggregate(), dodgr_flows_disperse(), dodgr_isochrones(), dodgr_isodists(), dodgr_isoverts(), dodgr_paths(), dodgr_times()

Examples

graph <- weight_streetnet (hampi)
from <- sample (graph$from_id, size = 10)
to <- sample (graph$to_id, size = 5)
to <- to [!to %in% from]
flows <- matrix (10 * runif (length (from) * length (to)),
    nrow = length (from)
)
graph <- dodgr_flows_aggregate (graph, from = from, to = to, flows = flows)
# graph then has an additonal 'flows' column of aggregate flows along all
# edges. These flows are directed, and can be aggregated to equivalent
# undirected flows on an equivalent undirected graph with:
graph_undir <- merge_directed_graph (graph)
# This graph will only include those edges having non-zero flows, and so:
nrow (graph)
nrow (graph_undir) # the latter is much smaller

Calculate fundamental cycles on a FULL (that is, non-contracted) graph.

Description

Calculate fundamental cycles on a FULL (that is, non-contracted) graph.

Usage

dodgr_full_cycles(graph, graph_max_size = 10000, expand = 0.05)

Arguments

graph

data.frame or equivalent object representing the contracted network graph (see Details).

graph_max_size

Maximum size submitted to the internal C++ routines as a single chunk. Warning: Increasing this may lead to computer meltdown!

expand

For large graphs which must be broken into chunks, this factor determines the relative overlap between chunks to ensure all cycles are captured. (This value should only need to be modified in special cases.)

Note

This function converts the graph to its contracted form, calculates the fundamental cycles on that version, and then expands these cycles back onto the original graph. This is far more computationally efficient than calculating fundamental cycles on a full (non-contracted) graph.

See Also

Other misc: compare_heaps(), dodgr_flowmap(), dodgr_fundamental_cycles(), dodgr_insert_vertex(), dodgr_sample(), dodgr_sflines_to_poly(), dodgr_vertices(), merge_directed_graph(), summary.dodgr_dists_categorical(), write_dodgr_wt_profile()

Examples

## Not run: 
net <- weight_streetnet (hampi)
graph <- dodgr_contract_graph (net)
cyc1 <- dodgr_fundamental_cycles (graph)
cyc2 <- dodgr_full_cycles (net)

## End(Not run)
# cyc2 has same number of cycles, but each one is generally longer, through
# including all points intermediate to junctions; cyc1 has cycles composed of
# junction points only.

Calculate fundamental cycles in a graph.

Description

Calculate fundamental cycles in a graph.

Usage

dodgr_fundamental_cycles(
  graph,
  vertices = NULL,
  graph_max_size = 10000,
  expand = 0.05
)

Arguments

graph

data.frame or equivalent object representing the contracted network graph (see Details).

vertices

data.frame returned from dodgr_vertices(graph). Will be calculated if not provided, but it's quicker to pass this if it has already been calculated.

graph_max_size

Maximum size submitted to the internal C++ routines as a single chunk. Warning: Increasing this may lead to computer meltdown!

expand

For large graphs which must be broken into chunks, this factor determines the relative overlap between chunks to ensure all cycles are captured. (This value should only need to be modified in special cases.)

Value

List of cycle paths, in terms of vertex IDs in graph and, for spatial graphs, the corresponding coordinates.

Note

Calculation of fundamental cycles is VERY computationally demanding, and this function should only be executed on CONTRACTED graphs (that is, graphs returned from dodgr_contract_graph), and even than may take a long time to execute. Results for full graphs can be obtained with the function dodgr_full_cycles. The computational complexity can also not be calculated in advance, and so the parameter graph_max_size will lead to graphs larger than that (measured in numbers of edges) being cut into smaller parts. (Note that that is only possible for spatial graphs, meaning that it is not at all possible to apply this function to large, non-spatial graphs.) Each of these smaller parts will be expanded by the specified amount (expand), and cycles found within. The final result is obtained by aggregating all of these cycles and removing any repeated ones arising due to overlap in the expanded portions. Finally, note that this procedure of cutting graphs into smaller, computationally manageable sub-graphs provides only an approximation and may not yield all fundamental cycles.

See Also

Other misc: compare_heaps(), dodgr_flowmap(), dodgr_full_cycles(), dodgr_insert_vertex(), dodgr_sample(), dodgr_sflines_to_poly(), dodgr_vertices(), merge_directed_graph(), summary.dodgr_dists_categorical(), write_dodgr_wt_profile()

Examples

net <- weight_streetnet (hampi)
graph <- dodgr_contract_graph (net)
verts <- dodgr_vertices (graph)
cyc <- dodgr_fundamental_cycles (graph, verts)

Insert a new node or vertex into a network

Description

Insert a new node or vertex into a network

Usage

dodgr_insert_vertex(graph, v1, v2, x = NULL, y = NULL)

Arguments

graph

A flat table of graph edges. Must contain columns labelled from and to, or start and stop. May also contain similarly labelled columns of spatial coordinates (for example from_x) or stop_lon).

v1

Vertex defining start of graph edge along which new vertex is to be inserted

v2

Vertex defining end of graph edge along which new vertex is to be inserted (order of v1 and v2 is not important).

x

The x-coordinate of new vertex. If not specified, vertex is created half-way between v1 and v2.

y

The y-coordinate of new vertex. If not specified, vertex is created half-way between v1 and v2.

Value

A modified graph with specified edge between defined start and end vertices split into two edges either side of new vertex.

See Also

Other misc: compare_heaps(), dodgr_flowmap(), dodgr_full_cycles(), dodgr_fundamental_cycles(), dodgr_sample(), dodgr_sflines_to_poly(), dodgr_vertices(), merge_directed_graph(), summary.dodgr_dists_categorical(), write_dodgr_wt_profile()

Examples

graph <- weight_streetnet (hampi)
e1 <- sample (nrow (graph), 1)
v1 <- graph$from_id [e1]
v2 <- graph$to_id [e1]
# insert new vertex in the middle of that randomly-selected edge:
graph2 <- dodgr_insert_vertex (graph, v1, v2)
nrow (graph)
nrow (graph2) # new edges added to graph2

Calculate isochrone contours from specified points.

Description

Function is fully vectorized to calculate accept vectors of central points and vectors defining multiple isochrone thresholds.

Usage

dodgr_isochrones(
  graph,
  from = NULL,
  tlim = NULL,
  concavity = 0,
  length_threshold = 0,
  heap = "BHeap"
)

Arguments

graph

data.frame or equivalent object representing the network graph. For dodgr street networks, this must be a network derived from silicate ("sc") data, generated with weight_streetnet. This function does not work with networks derived from sf data.

from

Vector or matrix of points from which isochrones are to be calculated.

tlim

Vector of desired limits of isochrones in seconds

concavity

A value between 0 and 1, with 0 giving (generally smoother but less detailed) convex iso-contours and 1 giving highly concave (and generally more detailed) contours.

length_threshold

The minimal length of a segment of the iso-contour to be made more convex according to the 'concavity' parameter.. Low values will produce highly detailed hulls which may cause problems; if in doubt, or if odd results appear, increase this value.

heap

Type of heap to use in priority queue. Options include Fibonacci Heap (default; FHeap), Binary Heap (BHeap), Trinomial Heap (TriHeap), Extended Trinomial Heap (TriHeapExt, and 2-3 Heap (Heap23).

Value

A single data.frame of isochrones as points sorted anticlockwise around each origin (from) point, with columns denoting the from points and tlim value(s). The isochrones are given as id values and associated coordinates of the series of points from each from point at the specified isochrone times.

Isochrones are calculated by default using parallel computation with the maximal number of available cores or threads. This number can be reduced by specifying a value via ⁠RcppParallel::setThreadOptions (numThreads = <desired_number>)⁠.

Note

Isodists are calculated by default using parallel computation with the maximal number of available cores or threads. This number can be reduced by specifying a value via ⁠RcppParallel::setThreadOptions (numThreads = <desired_number>)⁠.

See Also

Other distances: dodgr_distances(), dodgr_dists(), dodgr_dists_categorical(), dodgr_dists_nearest(), dodgr_flows_aggregate(), dodgr_flows_disperse(), dodgr_flows_si(), dodgr_isodists(), dodgr_isoverts(), dodgr_paths(), dodgr_times()

Examples

## Not run: 
# Use osmdata package to extract 'SC'-format data:
library (osmdata)
dat <- opq ("hampi india") %>%
    add_osm_feature (key = "highway") %>%
    osmdata_sc ()
graph <- weight_streetnet (dat)
from <- sample (graph$.vx0, size = 100)
tlim <- c (5, 10, 20, 30, 60) * 60 # times in seconds
x <- dodgr_isochrones (graph, from = from, tlim)

## End(Not run)

Calculate isodistance contours from specified points.

Description

Function is fully vectorized to calculate accept vectors of central points and vectors defining multiple isodistances.

Usage

dodgr_isodists(
  graph,
  from = NULL,
  dlim = NULL,
  concavity = 0,
  length_threshold = 0,
  contract = TRUE,
  heap = "BHeap"
)

Arguments

graph

data.frame or equivalent object representing the network graph. For dodgr street networks, this may be a network derived from either sf or silicate ("sc") data, generated with weight_streetnet.

from

Vector or matrix of points from which isodistances are to be calculated.

dlim

Vector of desired limits of isodistances in metres.

concavity

A value between 0 and 1, with 0 giving (generally smoother but less detailed) convex iso-contours and 1 giving highly concave (and generally more detailed) contours.

length_threshold

The minimal length of a segment of the iso-contour to be made more convex according to the 'concavity' parameter.. Low values will produce highly detailed hulls which may cause problems; if in doubt, or if odd results appear, increase this value.

contract

If TRUE, calculate isodists only to vertices in the contract graph, in other words, only to junction vertices.

heap

Type of heap to use in priority queue. Options include Fibonacci Heap (default; FHeap), Binary Heap (BHeap), Trinomial Heap (TriHeap), Extended Trinomial Heap (TriHeapExt, and 2-3 Heap (Heap23).

Value

A single data.frame of isodistances as points sorted anticlockwise around each origin (from) point, with columns denoting the from points and dlim value(s). The isodistance contours are given as id values and associated coordinates of the series of points from each from point at the specified isodistances.

Note

Isodists are calculated by default using parallel computation with the maximal number of available cores or threads. This number can be reduced by specifying a value via ⁠RcppParallel::setThreadOptions (numThreads = <desired_number>)⁠.

See Also

Other distances: dodgr_distances(), dodgr_dists(), dodgr_dists_categorical(), dodgr_dists_nearest(), dodgr_flows_aggregate(), dodgr_flows_disperse(), dodgr_flows_si(), dodgr_isochrones(), dodgr_isoverts(), dodgr_paths(), dodgr_times()

Examples

graph <- weight_streetnet (hampi)
from <- sample (graph$from_id, size = 100)
dlim <- c (1, 2, 5, 10, 20) * 100
d <- dodgr_isodists (graph, from = from, dlim)

Calculate isodistance or isochrone contours from specified points.

Description

Returns lists of all network vertices contained within the contours. Function is fully vectorized to calculate accept vectors of central points and vectors defining multiple isochrone thresholds. Provide one or more dlim values for isodistances, or one or more tlim values for isochrones.

Usage

dodgr_isoverts(graph, from = NULL, dlim = NULL, tlim = NULL, heap = "BHeap")

Arguments

graph

data.frame or equivalent object representing the network graph. For dodgr street networks, this must be a network derived from silicate ("sc") data, generated with weight_streetnet. This function does not work with networks derived from sf data.

from

Vector or matrix of points from which isodistances or isochrones are to be calculated.

dlim

Vector of desired limits of isodistances in metres.

tlim

Vector of desired limits of isochrones in seconds

heap

Type of heap to use in priority queue. Options include Fibonacci Heap (default; FHeap), Binary Heap (BHeap), Trinomial Heap (TriHeap), Extended Trinomial Heap (TriHeapExt, and 2-3 Heap (Heap23).

Value

A single data.frame of vertex IDs, with columns denoting the from points and tlim value(s). The isochrones are given as id values and associated coordinates of the series of points from each from point at the specified isochrone times.

Isoverts are calculated by default using parallel computation with the maximal number of available cores or threads. This number can be reduced by specifying a value via ⁠RcppParallel::setThreadOptions (numThreads = <desired_number>)⁠.

See Also

Other distances: dodgr_distances(), dodgr_dists(), dodgr_dists_categorical(), dodgr_dists_nearest(), dodgr_flows_aggregate(), dodgr_flows_disperse(), dodgr_flows_si(), dodgr_isochrones(), dodgr_isodists(), dodgr_paths(), dodgr_times()

Examples

## Not run: 
# Use osmdata package to extract 'SC'-format data:
library (osmdata)
dat <- opq ("hampi india") %>%
    add_osm_feature (key = "highway") %>%
    osmdata_sc ()
graph <- weight_streetnet (dat)
from <- sample (graph$.vx0, size = 100)
tlim <- c (5, 10, 20, 30, 60) * 60 # times in seconds
x <- dodgr_isoverts (graph, from = from, tlim)

## End(Not run)

Load a street network previously saved with dodgr_save_streetnet.

Description

This always returns the full, non-contracted graph. The contracted graph can be generated by passing the result to dodgr_contract_graph.

Usage

dodgr_load_streetnet(filename)

Arguments

filename

Name (with optional full path) of file to be loaded.

See Also

Other cache: clear_dodgr_cache(), dodgr_cache_off(), dodgr_cache_on(), dodgr_save_streetnet()

Examples

net <- weight_streetnet (hampi)
f <- file.path (tempdir (), "streetnet.Rds")
dodgr_save_streetnet (net, f)
clear_dodgr_cache () # rm cached objects from tempdir
# at some later time, or in a new R session:
net <- dodgr_load_streetnet (f)

Calculate lists of pair-wise shortest paths between points.

Description

Calculate lists of pair-wise shortest paths between points.

Usage

dodgr_paths(
  graph,
  from,
  to,
  vertices = TRUE,
  pairwise = FALSE,
  heap = "BHeap",
  quiet = TRUE
)

Arguments

graph

data.frame or equivalent object representing the network graph (see Details)

from

Vector or matrix of points from which route paths are to be calculated (see Details)

to

Vector or matrix of points to which route paths are to be calculated (see Details)

vertices

If TRUE, return lists of lists of vertices for each path, otherwise return corresponding lists of edge numbers from graph.

pairwise

If TRUE, calculate paths only between the ordered pairs of from and to. In this case, each of these must be the same length, and the output will contain paths the i-th members of each, and thus also be of that length.

heap

Type of heap to use in priority queue. Options include Fibonacci Heap (default; FHeap), Binary Heap (BHeap), Radix, Trinomial Heap (TriHeap), Extended Trinomial Heap (TriHeapExt, and 2-3 Heap (Heap23).

quiet

If FALSE, display progress messages on screen.

Value

List of list of paths tracing all connections between nodes such that if x <- dodgr_paths (graph, from, to), then the path between from[i] and to[j] is x [[i]] [[j]]. Each individual path is then a vector of integers indexing into the rows of graph if vertices = FALSE, or into the rows of dodgr_vertices (graph) if vertices = TRUE.

Note

graph must minimally contain four columns of from, to, dist. If an additional column named weight or wt is present, shortest paths are calculated according to values specified in that column; otherwise according to dist values. Either way, final distances between from and to points are calculated according to values of dist. That is, paths between any pair of points will be calculated according to the minimal total sum of weight values (if present), while reported distances will be total sums of dist values.

The from and to columns of graph may be either single columns of numeric or character values specifying the numbers or names of graph vertices, or combinations to two columns specifying geographical (longitude and latitude) coordinates. In the latter case, almost any sensible combination of names will be accepted (for example, ⁠fromx, fromy⁠, ⁠from_x, from_y⁠, or ⁠fr_lat, fr_lon⁠.)

from and to values can be either two-column matrices of equivalent of longitude and latitude coordinates, or else single columns precisely matching node numbers or names given in graph$from or graph$to. If to is missing, pairwise distances are calculated between all points specified in from. If neither from nor to are specified, pairwise distances are calculated between all nodes in graph.

See Also

Other distances: dodgr_distances(), dodgr_dists(), dodgr_dists_categorical(), dodgr_dists_nearest(), dodgr_flows_aggregate(), dodgr_flows_disperse(), dodgr_flows_si(), dodgr_isochrones(), dodgr_isodists(), dodgr_isoverts(), dodgr_times()

Examples

graph <- weight_streetnet (hampi)
from <- sample (graph$from_id, size = 100)
to <- sample (graph$to_id, size = 50)
dp <- dodgr_paths (graph, from = from, to = to)
# dp is a list with 100 items, and each of those 100 items has 30 items, each
# of which is a single path listing all vertiex IDs as taken from `graph`.

# it is also possible to calculate paths between pairwise start and end
# points
from <- sample (graph$from_id, size = 5)
to <- sample (graph$to_id, size = 5)
dp <- dodgr_paths (graph, from = from, to = to, pairwise = TRUE)
# dp is a list of 5 items, each of which just has a single path between each
# pairwise from and to point.

Sample a random but connected sub-component of a graph

Description

Sample a random but connected sub-component of a graph

Usage

dodgr_sample(graph, nverts = 1000)

Arguments

graph

A flat table of graph edges. Must contain columns labelled from and to, or start and stop. May also contain similarly labelled columns of spatial coordinates (for example from_x) or stop_lon).

nverts

Number of vertices to sample

Value

A connected sub-component of graph

Note

Graphs may occasionally have nverts + 1 vertices, rather than the requested nverts.

See Also

Other misc: compare_heaps(), dodgr_flowmap(), dodgr_full_cycles(), dodgr_fundamental_cycles(), dodgr_insert_vertex(), dodgr_sflines_to_poly(), dodgr_vertices(), merge_directed_graph(), summary.dodgr_dists_categorical(), write_dodgr_wt_profile()

Examples

graph <- weight_streetnet (hampi)
nrow (graph) # 5,742
graph <- dodgr_sample (graph, nverts = 200)
nrow (graph) # generally around 400 edges
nrow (dodgr_vertices (graph)) # 200

Save a weighted streetnet to a local file

Description

The weight_streetnet function returns a single data.frame object, the processing of which also relies on a couple of cached lookup-tables to match edges in the data.frame to objects in the original input data. It automatically calculates and caches a contracted version of the same graph, to enable rapid conversion between contracted and uncontracted forms. This function saves all of these items in a single .Rds file, so that a the result of a weight_streetnet call can be rapidly loaded into a workspace in subsequent sessions, rather than re-calculating the entire weighted network.

Usage

dodgr_save_streetnet(net, filename = NULL)

Arguments

net

data.frame or equivalent object representing the weighted network graph.

filename

Name with optional full path of file in which to save the input net. The extension .Rds will be automatically appended, unless specified otherwise.

Note

This may take some time if dodgr_cache_off has been called. The contracted version of the graph is also saved, and so must be calculated if it has not previously been automatically cached.

See Also

Other cache: clear_dodgr_cache(), dodgr_cache_off(), dodgr_cache_on(), dodgr_load_streetnet()

Examples

net <- weight_streetnet (hampi)
f <- file.path (tempdir (), "streetnet.Rds")
dodgr_save_streetnet (net, f)
clear_dodgr_cache () # rm cached objects from tempdir
# at some later time, or in a new R session:
net <- dodgr_load_streetnet (f)

Convert sf LINESTRING objects to POLYGON objects representing all fundamental cycles within the LINESTRING objects.

Description

Convert sf LINESTRING objects to POLYGON objects representing all fundamental cycles within the LINESTRING objects.

Usage

dodgr_sflines_to_poly(sflines, graph_max_size = 10000, expand = 0.05)

Arguments

sflines

An sf LINESTRING object representing a network.

graph_max_size

Maximum size submitted to the internal C++ routines as a single chunk. Warning: Increasing this may lead to computer meltdown!

expand

For large graphs which must be broken into chunks, this factor determines the relative overlap between chunks to ensure all cycles are captured. (This value should only need to be modified in special cases.)

Value

An sf::sfc collection of POLYGON objects.

See Also

Other misc: compare_heaps(), dodgr_flowmap(), dodgr_full_cycles(), dodgr_fundamental_cycles(), dodgr_insert_vertex(), dodgr_sample(), dodgr_vertices(), merge_directed_graph(), summary.dodgr_dists_categorical(), write_dodgr_wt_profile()


Extract a street network in sf-format for a given location.

Description

Use the osmdata package to extract the street network for a given location. For routing between a given set of points (passed as pts), the bbox argument may be omitted, in which case a bounding box will be constructed by expanding the range of pts by the relative amount of expand.

Usage

dodgr_streetnet(bbox, pts = NULL, expand = 0.05, quiet = TRUE)

Arguments

bbox

Bounding box as vector or matrix of coordinates, or location name. Passed to osmdata::getbb.

pts

List of points presumably containing spatial coordinates

expand

Relative factor by which street network should extend beyond limits defined by pts (only if bbox not given).

quiet

If FALSE, display progress messages

Value

A Simple Features (sf) object with coordinates of all lines in the street network.

Note

Calls to this function may return "General overpass server error" with a note that "Query timed out." The overpass served used to access the data has a sophisticated queueing system which prioritises requests that are likely to require little time. These timeout errors can thus generally not be circumvented by changing "timeout" options on the HTTP requests, and should rather be interpreted to indicate that a request is too large, and may need to be refined, or somehow broken up into smaller queries.

See Also

Other extraction: dodgr_streetnet_sc(), weight_railway(), weight_streetnet()

Examples

## Not run: 
streetnet <- dodgr_streetnet ("hampi india", expand = 0)
# convert to form needed for `dodgr` functions:
graph <- weight_streetnet (streetnet)
nrow (graph) # around 5,900 edges
# Alternative ways of extracting street networks by using a small selection
# of graph vertices to define bounding box:
verts <- dodgr_vertices (graph)
verts <- verts [sample (nrow (verts), size = 200), ]
streetnet <- dodgr_streetnet (pts = verts, expand = 0)
graph <- weight_streetnet (streetnet)
nrow (graph)
# This will generally have many more rows because most street networks
# include streets that extend considerably beyond the specified bounding box.

# bbox can also be a polygon:
bb <- osmdata::getbb ("gent belgium") # rectangular bbox
nrow (dodgr_streetnet (bbox = bb)) # around 30,000
bb <- osmdata::getbb ("gent belgium", format_out = "polygon")
nrow (dodgr_streetnet (bbox = bb)) # around 17,000
# The latter has fewer rows because only edges within polygon are returned

# Example with access restrictions
bbox <- c (-122.2935, 47.62663, -122.28, 47.63289)
x <- dodgr_streetnet_sc (bbox)
net <- weight_streetnet (x, keep_cols = "access", turn_penalty = TRUE)
# has many streets with "access" = "private"; these can be removed like this:
net2 <- net [which (!net$access != "private"), ]
# or modified in some other way such as strongly penalizing use of those
# streets:
index <- which (net$access == "private")
net$time_weighted [index] <- net$time_weighted [index] * 100

## End(Not run)

Extract a street network in silicate-format for a given location.

Description

Use the osmdata package to extract the street network for a given location and return it in SC-format. For routing between a given set of points (passed as pts), the bbox argument may be omitted, in which case a bounding box will be constructed by expanding the range of pts by the relative amount of expand.

Usage

dodgr_streetnet_sc(bbox, pts = NULL, expand = 0.05, quiet = TRUE)

Arguments

bbox

Bounding box as vector or matrix of coordinates, or location name. Passed to osmdata::getbb.

pts

List of points presumably containing spatial coordinates

expand

Relative factor by which street network should extend beyond limits defined by pts (only if bbox not given).

quiet

If FALSE, display progress messages

Value

A Simple Features (sf) object with coordinates of all lines in the street network.

Note

Calls to this function may return "General overpass server error" with a note that "Query timed out." The overpass served used to access the data has a sophisticated queueing system which prioritises requests that are likely to require little time. These timeout errors can thus generally not be circumvented by changing "timeout" options on the HTTP requests, and should rather be interpreted to indicate that a request is too large, and may need to be refined, or somehow broken up into smaller queries.

See Also

Other extraction: dodgr_streetnet(), weight_railway(), weight_streetnet()

Examples

## Not run: 
streetnet <- dodgr_streetnet ("hampi india", expand = 0)
# convert to form needed for `dodgr` functions:
graph <- weight_streetnet (streetnet)
nrow (graph) # around 5,900 edges
# Alternative ways of extracting street networks by using a small selection
# of graph vertices to define bounding box:
verts <- dodgr_vertices (graph)
verts <- verts [sample (nrow (verts), size = 200), ]
streetnet <- dodgr_streetnet (pts = verts, expand = 0)
graph <- weight_streetnet (streetnet)
nrow (graph)
# This will generally have many more rows because most street networks
# include streets that extend considerably beyond the specified bounding box.

# bbox can also be a polygon:
bb <- osmdata::getbb ("gent belgium") # rectangular bbox
nrow (dodgr_streetnet (bbox = bb)) # around 30,000
bb <- osmdata::getbb ("gent belgium", format_out = "polygon")
nrow (dodgr_streetnet (bbox = bb)) # around 17,000
# The latter has fewer rows because only edges within polygon are returned

# Example with access restrictions
bbox <- c (-122.2935, 47.62663, -122.28, 47.63289)
x <- dodgr_streetnet_sc (bbox)
net <- weight_streetnet (x, keep_cols = "access", turn_penalty = TRUE)
# has many streets with "access" = "private"; these can be removed like this:
net2 <- net [which (!net$access != "private"), ]
# or modified in some other way such as strongly penalizing use of those
# streets:
index <- which (net$access == "private")
net$time_weighted [index] <- net$time_weighted [index] * 100

## End(Not run)

Calculate matrix of pair-wise travel times between points.

Description

Calculate matrix of pair-wise travel times between points.

Usage

dodgr_times(graph, from = NULL, to = NULL, shortest = FALSE, heap = "BHeap")

Arguments

graph

data.frame or equivalent object representing the network graph (see Notes). For dodgr street networks, this may be a network derived from either sf or silicate ("sc") data, generated with weight_streetnet.

The from and to columns of graph may be either single columns of numeric or character values specifying the numbers or names of graph vertices, or combinations to two columns specifying geographical (longitude and latitude,) coordinates. In the latter case, almost any sensible combination of names will be accepted (for example, ⁠fromx, fromy⁠, ⁠from_x, from_y⁠, or ⁠fr_lat, fr_lon⁠.)

Note that longitude and latitude values are always interpreted in 'dodgr' to be in EPSG:4326 / WSG84 coordinates. Any other kinds of coordinates should first be reprojected to EPSG:4326 before submitting to any 'dodgr' routines.

See further information in Details.

from

Vector or matrix of points from which route distances are to be calculated, specified as one of the following:

  • Single character vector precisely matching node numbers or names given in graph$from or graph$to.

  • Single vector of integer-ish values, in which case these will be presumed to specify indices into dodgr_vertices, and NOT to correspond to values in the 'from' or 'to' columns of the graph. See the example below for a demonstration.

  • Matrix or equivalent of longitude and latitude coordinates, in which case these will be matched on to the nearest coordinates of 'from' and 'to' points in the graph.

to

Vector or matrix of points to which route distances are to be calculated. If to is NULL, pairwise distances will be calculated from all from points to all other nodes in graph. If both from and to are NULL, pairwise distances are calculated between all nodes in graph.

shortest

If FALSE, calculate distances along the fastest rather than shortest routes. For street networks produced with weight_streetnet, distances may also be calculated along the fastest routes with the shortest = FALSE option. Graphs must in this case have columns of time and time_weighted. Note that the fastest routes will only be approximate when derived from sf-format data generated with the osmdata function osmdata_sf(), and will be much more accurate when derived from sc-format data generated with osmdata_sc(). See weight_streetnet for details.

heap

Type of heap to use in priority queue. Options include Fibonacci Heap (default; FHeap), Binary Heap (BHeap), ⁠Trinomial Heap (⁠TriHeap⁠), Extended Trinomial Heap (⁠TriHeapExt⁠, and 2-3 Heap (⁠Heap23').

Details

graph must minimally contain three columns of from, to, dist. If an additional column named weight or wt is present, shortest paths are calculated according to values specified in that column; otherwise according to dist values. Either way, final distances between from and to points are calculated by default according to values of dist. That is, paths between any pair of points will be calculated according to the minimal total sum of weight values (if present), while reported distances will be total sums of dist values.

Value

square matrix of distances between nodes

See Also

Other distances: dodgr_distances(), dodgr_dists(), dodgr_dists_categorical(), dodgr_dists_nearest(), dodgr_flows_aggregate(), dodgr_flows_disperse(), dodgr_flows_si(), dodgr_isochrones(), dodgr_isodists(), dodgr_isoverts(), dodgr_paths()

Examples

# A simple graph
graph <- data.frame (
    from = c ("A", "B", "B", "B", "C", "C", "D", "D"),
    to = c ("B", "A", "C", "D", "B", "D", "C", "A"),
    d = c (1, 2, 1, 3, 2, 1, 2, 1)
)
dodgr_dists (graph)

# Example of "from" and "to" as integer-ish values, in which case they are
# interpreted to index into "dodgr_vertices()":
graph <- data.frame (
    from = c (1, 3, 2, 2, 3, 3, 4, 4),
    to = c (2, 1, 3, 4, 2, 4, 3, 1),
    d = c (1, 2, 1, 3, 2, 1, 2, 1)
)
dodgr_dists (graph, from = 1, to = 2)
# That then gives distance from "1" to "3" because the vertices are built
# sequentially along "graph$from":
dodgr_vertices (graph)
# And vertex$id [2] is "3"

# A larger example from the included [hampi()] data.
graph <- weight_streetnet (hampi)
from <- sample (graph$from_id, size = 100)
to <- sample (graph$to_id, size = 50)
d <- dodgr_dists (graph, from = from, to = to)
# d is a 100-by-50 matrix of distances between `from` and `to`

## Not run: 
# a more complex street network example, thanks to @chrijo; see
# https://github.com/UrbanAnalyst/dodgr/issues/47

xy <- rbind (
    c (7.005994, 51.45774), # limbeckerplatz 1 essen germany
    c (7.012874, 51.45041)
) # hauptbahnhof essen germany
xy <- data.frame (lon = xy [, 1], lat = xy [, 2])
essen <- dodgr_streetnet (pts = xy, expand = 0.2, quiet = FALSE)
graph <- weight_streetnet (essen, wt_profile = "foot")
d <- dodgr_dists (graph, from = xy, to = xy)
# First reason why this does not work is because the graph has multiple,
# disconnected components.
table (graph$component)
# reduce to largest connected component, which is always number 1
graph <- graph [which (graph$component == 1), ]
d <- dodgr_dists (graph, from = xy, to = xy)
# should work, but even then note that
table (essen$level)
# There are parts of the network on different building levels (because of
# shopping malls and the like). These may or may not be connected, so it may
# be necessary to filter out particular levels
index <- which (!(essen$level == "-1" | essen$level == "1")) # for example
library (sf) # needed for following sub-select operation
essen <- essen [index, ]
graph <- weight_streetnet (essen, wt_profile = "foot")
graph <- graph [which (graph$component == 1), ]
d <- dodgr_dists (graph, from = xy, to = xy)

## End(Not run)

Convert a dodgr graph to an igraph.

Description

Convert a dodgr graph to an igraph.

Usage

dodgr_to_igraph(graph, weight_column = "d")

Arguments

graph

A dodgr graph

weight_column

The column of the dodgr network to use as the edge weights in the igraph representation.

Value

The igraph equivalent of the input. Note that this will not be a dual-weighted graph.

See Also

igraph_to_dodgr

Other conversion: dodgr_deduplicate_graph(), dodgr_to_sf(), dodgr_to_sfc(), dodgr_to_tidygraph(), igraph_to_dodgr()

Examples

graph <- weight_streetnet (hampi)
graphi <- dodgr_to_igraph (graph)

Convert a dodgr graph into an equivalent sf object.

Description

Works by aggregating edges into LINESTRING objects representing longest sequences between all junction nodes. The resultant objects will generally contain more LINESTRING objects than the original sf object, because the former will be bisected at every junction point.

Usage

dodgr_to_sf(graph)

Arguments

graph

A dodgr graph

Value

Equivalent object of class sf.

Note

Requires the sf package to be installed.

See Also

Other conversion: dodgr_deduplicate_graph(), dodgr_to_igraph(), dodgr_to_sfc(), dodgr_to_tidygraph(), igraph_to_dodgr()

Examples

hw <- weight_streetnet (hampi)
nrow (hw) # 5,729 edges
xy <- dodgr_to_sf (hw)
dim (xy) # 764 edges; 14 attributes

Convert a dodgr graph into an equivalent sf::sfc object.

Description

Convert a dodgr graph into a list composed of two objects: dat, a data.frame; and geometry, an sfc object from the (sf) package. Works by aggregating edges into LINESTRING objects representing longest sequences between all junction nodes. The resultant objects will generally contain more LINESTRING objects than the original sf object, because the former will be bisected at every junction point.

Usage

dodgr_to_sfc(graph)

Arguments

graph

A dodgr graph

Value

A list containing (1) A data.frame of data associated with the sf geometries; and (ii) A Simple Features Collection (sfc) list of LINESTRING objects.

Note

The output of this function corresponds to the edges obtained from dodgr_contract_graph. This function does not require the sf package to be installed; the corresponding function that creates a full sf object - dodgr_to_sf does requires sf to be installed.

See Also

Other conversion: dodgr_deduplicate_graph(), dodgr_to_igraph(), dodgr_to_sf(), dodgr_to_tidygraph(), igraph_to_dodgr()

Examples

hw <- weight_streetnet (hampi)
nrow (hw)
xy <- dodgr_to_sfc (hw)
dim (hw) # 5.845 edges
length (xy$geometry) # more linestrings aggregated from those edges
nrow (hampi) # than the 191 linestrings in original sf object
dim (xy$dat) # same number of rows as there are geometries
# The dodgr_to_sf function then just implements this final conversion:
# sf::st_sf (xy$dat, geometry = xy$geometry, crs = 4326)

Convert a dodgr graph to an tidygraph.

Description

Convert a dodgr graph to an tidygraph.

Usage

dodgr_to_tidygraph(graph)

Arguments

graph

A dodgr graph

Value

The tidygraph equivalent of the input

See Also

Other conversion: dodgr_deduplicate_graph(), dodgr_to_igraph(), dodgr_to_sf(), dodgr_to_sfc(), igraph_to_dodgr()

Examples

graph <- weight_streetnet (hampi)
grapht <- dodgr_to_tidygraph (graph)

Re-expand a contracted graph.

Description

Revert a contracted graph created with dodgr_contract_graph back to a full, uncontracted version. This function is mostly used for the side effect of mapping any new columns inserted on to the contracted graph back on to the original graph, as demonstrated in the example.

Usage

dodgr_uncontract_graph(graph)

Arguments

graph

A contracted graph created from dodgr_contract_graph.

Details

Note that this function will generally not recover original graphs submitted to dodgr_contract_graph. Specifically, the sequence dodgr_contract_graph(graph) |> dodgr_uncontract_graph() will generally produce a graph with fewer edges than the original. This is because graphs may have multiple paths between a given pair of points. Contraction will reduce these to the single path with the shortest weighted distance (or time), and uncontraction will restore only that single edge with shortest weighted distance, and not any original edges which may have had longer weighted distances.

Value

A single data.frame representing the equivalent original, uncontracted graph.

See Also

Other modification: dodgr_components(), dodgr_contract_graph()

Examples

graph0 <- weight_streetnet (hampi)
nrow (graph0) # 6,813
graph1 <- dodgr_contract_graph (graph0)
nrow (graph1) # 760
graph2 <- dodgr_uncontract_graph (graph1)
nrow (graph2) # 6,813

# Insert new data on to the contracted graph and uncontract it:
graph1$new_col <- runif (nrow (graph1))
graph3 <- dodgr_uncontract_graph (graph1)
# graph3 is then the uncontracted graph which includes "new_col" as well
dim (graph0)
dim (graph3)

Extract vertices of graph, including spatial coordinates if included.

Description

Extract vertices of graph, including spatial coordinates if included.

Usage

dodgr_vertices(graph)

Arguments

graph

A flat table of graph edges. Must contain columns labelled from and to, or start and stop. May also contain similarly labelled columns of spatial coordinates (for example from_x) or stop_lon).

Value

A data.frame of vertices with unique numbers (n).

Note

Values of n are 0-indexed

See Also

Other misc: compare_heaps(), dodgr_flowmap(), dodgr_full_cycles(), dodgr_fundamental_cycles(), dodgr_insert_vertex(), dodgr_sample(), dodgr_sflines_to_poly(), merge_directed_graph(), summary.dodgr_dists_categorical(), write_dodgr_wt_profile()

Examples

graph <- weight_streetnet (hampi)
v <- dodgr_vertices (graph)

Estimate a value for the 'dist_threshold' parameter of the dodgr_centrality function.

Description

Providing distance thresholds to this function generally provides considerably speed gains, and results in approximations of centrality. This function enables the determination of values of 'dist_threshold' corresponding to specific degrees of accuracy.

Usage

estimate_centrality_threshold(graph, tolerance = 0.001)

Arguments

graph

'data.frame' or equivalent object representing the network graph (see Details)

tolerance

Desired maximal degree of inaccuracy in centrality estimates

  • values will be accurate to within this amount, subject to a constant scaling factor. Note that threshold values increase non-linearly with decreasing values of 'tolerance'

Value

A single value for 'dist_threshold' giving the required tolerance.

Note

This function may take some time to execute. While running, it displays ongoing information on screen of estimated values of 'dist_threshold' and associated errors. Thresholds are progressively increased until the error is reduced below the specified tolerance.

See Also

Other centrality: dodgr_centrality(), estimate_centrality_time()


Estimate time required for a planned centrality calculation.

Description

The 'dodgr' centrality functions are designed to be applied to potentially very large graphs, and may take considerable time to execute. This helper function estimates how long a centrality function may take for a given graph and given value of 'dist_threshold' estimated via the estimate_centrality_threshold function.

Usage

estimate_centrality_time(
  graph,
  contract = TRUE,
  edges = TRUE,
  dist_threshold = NULL,
  heap = "BHeap"
)

Arguments

graph

'data.frame' or equivalent object representing the network graph (see Details)

contract

If 'TRUE', centrality is calculated on contracted graph before mapping back on to the original full graph. Note that for street networks, in particular those obtained from the osmdata package, vertex placement is effectively arbitrary except at junctions; centrality for such graphs should only be calculated between the latter points, and thus 'contract' should always be 'TRUE'.

edges

If 'TRUE', centrality is calculated for graph edges, returning the input 'graph' with an additional 'centrality' column; otherwise centrality is calculated for vertices, returning the equivalent of 'dodgr_vertices(graph)', with an additional vertex-based 'centrality' column.

dist_threshold

If not 'NULL', only calculate centrality for each point out to specified threshold. Setting values for this will result in approximate estimates for centrality, yet with considerable gains in computational efficiency. For sufficiently large values, approximations will be accurate to within some constant multiplier. Appropriate values can be established via the estimate_centrality_threshold function.

heap

Type of heap to use in priority queue. Options include Fibonacci Heap (default; 'FHeap'), Binary Heap ('BHeap'), Trinomial Heap ('TriHeap'), Extended Trinomial Heap ('TriHeapExt', and 2-3 Heap ('Heap23').

Value

An estimated calculation time for calculating centrality for the given value of 'dist_threshold'

Note

This function may take some time to execute. While running, it displays ongoing information on screen of estimated values of 'dist_threshold' and associated errors. Thresholds are progressively increased until the error is reduced below the specified tolerance.

See Also

Other centrality: dodgr_centrality(), estimate_centrality_threshold()


Sample street network from Hampi, India.

Description

A sample street network from the township of Hampi, Karnataka, India.

Format

A Simple Features sf data.frame containing the street network of Hampi.

Note

Can be re-created with the following command, which also removes extraneous columns to reduce size:

See Also

Other data: os_roads_bristol, weighting_profiles

Examples

## Not run: 
hampi <- dodgr_streetnet ("hampi india")
cols <- c ("osm_id", "highway", "oneway", "geometry")
hampi <- hampi [, which (names (hampi) %in% cols)]

## End(Not run)
# this 'sf data.frame' can be converted to a 'dodgr' network with
net <- weight_streetnet (hampi, wt_profile = "foot")

Convert a igraph network to an equivalent dodgr representation.

Description

Convert a igraph network to an equivalent dodgr representation.

Usage

igraph_to_dodgr(graph)

Arguments

graph

An igraph network

Value

The dodgr equivalent of the input.

See Also

dodgr_to_igraph

Other conversion: dodgr_deduplicate_graph(), dodgr_to_igraph(), dodgr_to_sf(), dodgr_to_sfc(), dodgr_to_tidygraph()

Examples

graph <- weight_streetnet (hampi)
graphi <- dodgr_to_igraph (graph)
graph2 <- igraph_to_dodgr (graphi)
identical (graph2, graph) # FALSE

Alias for match_pts_to_graph

Description

Match spatial points to the edges of a spatial graph, through finding the edge with the closest perpendicular intersection. NOTE: Intersections are calculated geometrically, and presume planar geometry. It is up to users of projected geometrical data, such as those within a dodgr_streetnet object, to ensure that either: (i) Data span an sufficiently small area that errors from presuming planar geometry may be ignored; or (ii) Data are re-projected to an equivalent planar geometry prior to calling this routine.

Usage

match_points_to_graph(graph, xy, connected = FALSE)

Arguments

graph

A dodgr graph with spatial coordinates, such as a dodgr_streetnet object.

xy

coordinates of points to be matched to the vertices, either as matrix or sf-formatted data.frame.

connected

Should points be matched to the same (largest) connected component of graph? If FALSE and these points are to be used for a dodgr routing routine (dodgr_dists, dodgr_paths, or dodgr_flows_aggregate), then results may not be returned if points are not part of the same connected component. On the other hand, forcing them to be part of the same connected component may decrease the spatial accuracy of matching.

Value

For distances = FALSE (default), a vector index matching the xy coordinates to nearest edges. For bi-directional edges, only one match is returned, and it is up to the user to identify and suitably process matching edge pairs. For 'distances = TRUE', a 'data.frame' of four columns:

  • "index" The index of closest edges in "graph", as described above.

  • "d_signed" The perpendicular distance from ech point to the nearest edge, with negative distances denoting points to the left of edges, and positive distances denoting points to the right. Distances of zero denote points lying precisely on the line of an edge (potentially including cases where nearest point of bisection lies beyond the actual edge).

  • "x" The x-coordinate of the point of intersection.

  • "y" The y-coordinate of the point of intersection.

See Also

Other match: add_nodes_to_graph(), match_points_to_verts(), match_pts_to_graph(), match_pts_to_verts()

Examples

graph <- weight_streetnet (hampi, wt_profile = "foot")
# Then generate some random points to match to graph
verts <- dodgr_vertices (graph)
npts <- 10
xy <- data.frame (
    x = min (verts$x) + runif (npts) * diff (range (verts$x)),
    y = min (verts$y) + runif (npts) * diff (range (verts$y))
)
edges <- match_pts_to_graph (graph, xy)
graph [edges, ] # The edges of the graph closest to `xy`

Alias for match_pts_to_verts

Description

The match_pts_to_graph function matches points to the nearest edge based on geometric intersections; this function only matches to the nearest vertex based on point-to-point distances.

Usage

match_points_to_verts(verts, xy, connected = FALSE)

Arguments

verts

A data.frame of vertices obtained from dodgr_vertices(graph).

xy

coordinates of points to be matched to the vertices, either as matrix or sf-formatted data.frame.

connected

Should points be matched to the same (largest) connected component of graph? If FALSE and these points are to be used for a dodgr routing routine (dodgr_dists, dodgr_paths, or dodgr_flows_aggregate), then results may not be returned if points are not part of the same connected component. On the other hand, forcing them to be part of the same connected component may decrease the spatial accuracy of matching.

Value

A vector index into verts

See Also

Other match: add_nodes_to_graph(), match_points_to_graph(), match_pts_to_graph(), match_pts_to_verts()

Examples

net <- weight_streetnet (hampi, wt_profile = "foot")
verts <- dodgr_vertices (net)
# Then generate some random points to match to graph
npts <- 10
xy <- data.frame (
    x = min (verts$x) + runif (npts) * diff (range (verts$x)),
    y = min (verts$y) + runif (npts) * diff (range (verts$y))
)
pts <- match_pts_to_verts (verts, xy)
pts # an index into verts
pts <- verts$id [pts]
pts # names of those vertices

Match spatial points to the edges of a spatial graph.

Description

Match spatial points to the edges of a spatial graph, through finding the edge with the closest perpendicular intersection. NOTE: Intersections are calculated geometrically, and presume planar geometry. It is up to users of projected geometrical data, such as those within a dodgr_streetnet object, to ensure that either: (i) Data span an sufficiently small area that errors from presuming planar geometry may be ignored; or (ii) Data are re-projected to an equivalent planar geometry prior to calling this routine.

Usage

match_pts_to_graph(graph, xy, connected = FALSE, distances = FALSE)

Arguments

graph

A dodgr graph with spatial coordinates, such as a dodgr_streetnet object.

xy

coordinates of points to be matched to the vertices, either as matrix or sf-formatted data.frame.

connected

Should points be matched to the same (largest) connected component of graph? If FALSE and these points are to be used for a dodgr routing routine (dodgr_dists, dodgr_paths, or dodgr_flows_aggregate), then results may not be returned if points are not part of the same connected component. On the other hand, forcing them to be part of the same connected component may decrease the spatial accuracy of matching.

distances

If TRUE, return a 'data.frame' object with 'index' column as described in return value; and additional columns with perpendicular distance to nearest edge in graph, and coordinates of points of intersection. See description of return value for details.

Value

For distances = FALSE (default), a vector index matching the xy coordinates to nearest edges. For bi-directional edges, only one match is returned, and it is up to the user to identify and suitably process matching edge pairs. For 'distances = TRUE', a 'data.frame' of four columns:

  • "index" The index of closest edges in "graph", as described above.

  • "d_signed" The perpendicular distance from ech point to the nearest edge, with negative distances denoting points to the left of edges, and positive distances denoting points to the right. Distances of zero denote points lying precisely on the line of an edge (potentially including cases where nearest point of bisection lies beyond the actual edge).

  • "x" The x-coordinate of the point of intersection.

  • "y" The y-coordinate of the point of intersection.

See Also

Other match: add_nodes_to_graph(), match_points_to_graph(), match_points_to_verts(), match_pts_to_verts()

Examples

graph <- weight_streetnet (hampi, wt_profile = "foot")
# Then generate some random points to match to graph
verts <- dodgr_vertices (graph)
npts <- 10
xy <- data.frame (
    x = min (verts$x) + runif (npts) * diff (range (verts$x)),
    y = min (verts$y) + runif (npts) * diff (range (verts$y))
)
edges <- match_pts_to_graph (graph, xy)
graph [edges, ] # The edges of the graph closest to `xy`

Match spatial points to the vertices of a spatial graph.

Description

The match_pts_to_graph function matches points to the nearest edge based on geometric intersections; this function only matches to the nearest vertex based on point-to-point distances.

Usage

match_pts_to_verts(verts, xy, connected = FALSE)

Arguments

verts

A data.frame of vertices obtained from dodgr_vertices(graph).

xy

coordinates of points to be matched to the vertices, either as matrix or sf-formatted data.frame.

connected

Should points be matched to the same (largest) connected component of graph? If FALSE and these points are to be used for a dodgr routing routine (dodgr_dists, dodgr_paths, or dodgr_flows_aggregate), then results may not be returned if points are not part of the same connected component. On the other hand, forcing them to be part of the same connected component may decrease the spatial accuracy of matching.

Value

A vector index into verts

See Also

Other match: add_nodes_to_graph(), match_points_to_graph(), match_points_to_verts(), match_pts_to_graph()

Examples

net <- weight_streetnet (hampi, wt_profile = "foot")
verts <- dodgr_vertices (net)
# Then generate some random points to match to graph
npts <- 10
xy <- data.frame (
    x = min (verts$x) + runif (npts) * diff (range (verts$x)),
    y = min (verts$y) + runif (npts) * diff (range (verts$y))
)
pts <- match_pts_to_verts (verts, xy)
pts # an index into verts
pts <- verts$id [pts]
pts # names of those vertices

Merge directed edges into equivalent undirected edges.

Description

Merge directed edges into equivalent undirected values by aggregating across directions. This function is primarily intended to aid visualisation of directed graphs, particularly visualising the results of the dodgr_flows_aggregate and dodgr_flows_disperse functions, which return columns of aggregated flows directed along each edge of a graph.

Usage

merge_directed_graph(graph, col_names = c("flow"))

Arguments

graph

A undirected graph in which directed edges of the input graph have been merged through aggregation to yield a single, undirected edge between each pair of vertices.

col_names

Names of columns to be merged through aggregation. Values for these columns in resultant undirected graph will be aggregated from directed values.

Value

An equivalent graph in which all directed edges have been reduced to single, undirected edges, and all values of the specified column(s) have been aggregated across directions to undirected values.

See Also

Other misc: compare_heaps(), dodgr_flowmap(), dodgr_full_cycles(), dodgr_fundamental_cycles(), dodgr_insert_vertex(), dodgr_sample(), dodgr_sflines_to_poly(), dodgr_vertices(), summary.dodgr_dists_categorical(), write_dodgr_wt_profile()

Examples

graph <- weight_streetnet (hampi)
from <- sample (graph$from_id, size = 10)
to <- sample (graph$to_id, size = 5)
to <- to [!to %in% from]
flows <- matrix (10 * runif (length (from) * length (to)),
    nrow = length (from)
)
graph <- dodgr_flows_aggregate (graph, from = from, to = to, flows = flows)
# graph then has an additonal 'flows` column of aggregate flows along all
# edges. These flows are directed, and can be aggregated to equivalent
# undirected flows on an equivalent undirected graph with:
graph_undir <- merge_directed_graph (graph)
# This graph will only include those edges having non-zero flows, and so:
nrow (graph)
nrow (graph_undir) # the latter is much smaller

Sample street network from Bristol, U.K.

Description

A sample street network for Bristol, U.K., from the Ordnance Survey.

Format

A Simple Features sf data.frame representing motorways in Bristol, UK.

Note

Input data downloaded from https://osdatahub.os.uk/downloads/open, To download the data from that page click on the tick box next to 'OS Open Roads', scroll to the bottom, click 'Continue' and complete the form on the subsequent page. This dataset is open access and can be used under these licensing conditions, and must be cited as follows: Contains OS data © Crown copyright and database right (2017)

See Also

Other data: hampi, weighting_profiles

Examples

## Not run: 
library (sf)
library (dplyr)
# data must be unzipped here
# os_roads <- sf::read_sf("~/data/ST_RoadLink.shp")
# u <- paste0 (
#     "https://opendata.arcgis.com/datasets/",
#     "686603e943f948acaa13fb5d2b0f1275_4.kml"
# )
# lads <- sf::read_sf(u)
# mapview::mapview(lads)
# bristol_pol <- dplyr::filter(lads, grepl("Bristol", lad16nm))
# os_roads <- st_transform(os_roads, st_crs(lads)
# os_roads_bristol <- os_roads[bristol_pol, ] %>%
#   dplyr::filter(class == "Motorway" &
#                 roadNumber != "M32") %>%
#   st_zm(drop = TRUE)
# mapview::mapview(os_roads_bristol)

## End(Not run)
# Converting this 'sf data.frame' to a 'dodgr' network requires manual
# specification of weighting profile:
colnm <- "formOfWay" # name of column used to determine weights
wts <- data.frame (
    name = "custom",
    way = unique (os_roads_bristol [[colnm]]),
    value = c (0.1, 0.2, 0.8, 1)
)
net <- weight_streetnet (
    os_roads_bristol,
    wt_profile = wts,
    type_col = colnm, id_col = "identifier"
)
# 'id_col' tells the function which column to use to attribute IDs of ways

Transform a result from dodgr_dists_categorical to summary statistics

Description

Transform a result from dodgr_dists_categorical to summary statistics

Usage

## S3 method for class 'dodgr_dists_categorical'
summary(object, ...)

Arguments

object

A 'dodgr_dists_categorical' object

...

Extra parameters currently not used

Value

The summary statistics (invisibly)

See Also

Other misc: compare_heaps(), dodgr_flowmap(), dodgr_full_cycles(), dodgr_fundamental_cycles(), dodgr_insert_vertex(), dodgr_sample(), dodgr_sflines_to_poly(), dodgr_vertices(), merge_directed_graph(), write_dodgr_wt_profile()


Weight a network for routing along railways.

Description

Weight (or re-weight) an sf-formatted OSM street network for routing along railways.

Usage

weight_railway(
  x,
  type_col = "railway",
  id_col = "osm_id",
  keep_cols = c("maxspeed"),
  excluded = c("abandoned", "disused", "proposed", "razed")
)

Arguments

x

A street network represented either as sf LINESTRING objects, typically extracted with dodgr_streetnet.

type_col

Specify column of the sf data.frame object which designates different types of railways to be used for weighting (default works with osmdata objects).

id_col

Specify column of the sf data.frame object which provides unique identifiers for each railway (default works with osmdata objects).

keep_cols

Vectors of columns from sf_lines to be kept in the resultant dodgr network; vector can be either names or indices of desired columns.

excluded

Types of railways to exclude from routing.

Value

A data.frame of edges representing the rail network, along with a column of graph component numbers.

Note

Default railway weighting is by distance. Other weighting schemes, such as by maximum speed, can be implemented simply by modifying the d_weighted column returned by this function accordingly.

See Also

Other extraction: dodgr_streetnet(), dodgr_streetnet_sc(), weight_streetnet()

Examples

## Not run: 
# sample railway extraction with the 'osmdata' package
library (osmdata)
dat <- opq ("shinjuku") %>%
    add_osm_feature (key = "railway") %>%
    osmdata_sf (quiet = FALSE)
graph <- weight_railway (dat$osm_lines)

## End(Not run)

Weight a street network according to a specified weighting profile.

Description

Weight (or re-weight) an sf or silicate *("SC") formatted OSM street network according to a named profile, selected from (foot, horse, wheelchair, bicycle, moped, motorcycle, motorcar, goods, hgv, psv), or a customized version derived from those.

Usage

weight_streetnet(
  x,
  wt_profile = "bicycle",
  wt_profile_file = NULL,
  turn_penalty = FALSE,
  type_col = "highway",
  id_col = "osm_id",
  keep_cols = NULL,
  left_side = FALSE
)

## Default S3 method:
weight_streetnet(
  x,
  wt_profile = "bicycle",
  wt_profile_file = NULL,
  turn_penalty = FALSE,
  type_col = "highway",
  id_col = "osm_id",
  keep_cols = NULL,
  left_side = FALSE
)

## S3 method for class 'sf'
weight_streetnet(
  x,
  wt_profile = "bicycle",
  wt_profile_file = NULL,
  turn_penalty = FALSE,
  type_col = "highway",
  id_col = "osm_id",
  keep_cols = NULL,
  left_side = FALSE
)

## S3 method for class 'sc'
weight_streetnet(
  x,
  wt_profile = "bicycle",
  wt_profile_file = NULL,
  turn_penalty = FALSE,
  type_col = "highway",
  id_col = "osm_id",
  keep_cols = NULL,
  left_side = FALSE
)

## S3 method for class 'SC'
weight_streetnet(
  x,
  wt_profile = "bicycle",
  wt_profile_file = NULL,
  turn_penalty = FALSE,
  type_col = "highway",
  id_col = "osm_id",
  keep_cols = NULL,
  left_side = FALSE
)

Arguments

x

A street network represented either as sf LINESTRING objects, typically extracted with dodgr_streetnet, or as an SC (silicate) object typically extracted with the dodgr_streetnet_sc.

wt_profile

Name of weighting profile, or data.frame specifying custom values (see Details)

wt_profile_file

Name of locally-stored, .json-formatted version of dodgr::weighting_profiles, created with write_dodgr_wt_profile, and modified as desired.

turn_penalty

Including time penalty on edges for turning across oncoming traffic at intersections (see Note).

type_col

Specify column of the sf data.frame object which designates different types of highways to be used for weighting (default works with osmdata objects).

id_col

For sf-formatted data only: Specify column of the sf data.frame object which provides unique identifiers for each highway (default works with osmdata objects).

keep_cols

Vectors of columns from x to be kept in the resultant dodgr network; vector can be either names, regex-patterns, or indices of desired columns (see notes).

left_side

Does traffic travel on the left side of the road (TRUE) or the right side (FALSE)? - only has effect on turn angle calculations for edge times.

Details

The structure of networks generated by this function is dependent on many aspects of the input network, and in particular on specific key-value pairs defined in the underlying OpenStreetMap (OSM) data.

Many key-value pairs influence the resultant network through being used in specified weighting profiles. Keys used in weighting profiles are always kept in the weighted networks, and are specified in weighting_profiles by the "way" column in the "weighting_profiles" item. These include:

  • "bridleway"

  • "cycleway"

  • "ferry"

  • "footway"

  • "living_street"

  • "motorway"

  • "motorway_link

  • "path"

  • "pedestrian"

  • "primary"

  • "primary_link"

  • "residential"

  • "secondary"

  • "secondary_link

  • "service"

  • "steps"

  • "tertiary"

  • "tertiary_link"

  • "track"

  • "trunk"

  • "trunk_link

  • "unclassified"

Some of these are only optionally kept, dependent on the weighting profile chosen. For example, "cycleway" keys are only kept for bicycle weighting. Most of the specified keys also include all possible variations on those keys. For the example of "cycleway" again, key-value pairs are also kept for "cycleway:left" and "cycleway:right".

The following additional keys are also automatically retained in weighted networks:

  • "highway"

  • "junction"

  • "lanes"

  • "maxspeed"

  • "oneway", including with all alternative forms such as "oneway.bicycle"

  • "surface"

Realistic routing including factors such as access restrictions, turn penalties, and effects of incline, can only be implemented when the objects passed to weight_streetnet are of sc ("silicate") format, generated with dodgr_streetnet_sc (and possibly enhanced through applying the osmdata function osm_elevation()). Restrictions applied to ways (in OSM terminology) may be controlled by ensuring specific columns are retained in the dodgr network with the keep_cols argument. For example, restrictions on access are generally specified by specifying a value for the key of "access". Include "access" in keep_cols will ensure these values are retained in the dodgr version, from which ways with specified values can easily be removed or modified, as demonstrated in the examples.

Restrictions and time-penalties on turns can be implemented by setting turn_penalty = TRUE, which will then honour turn restrictions specified in OSM (unless the "penalties" table of weighting_profiles has restrictions = FALSE for a specified wt_profile). Resultant graphs are fundamentally different from the default for distance-based routing. These graphs may be used directly in most 'dodgr' functions, but generally only if they have been created by calling this function in the same session, or if they have been saved and loaded with the dodgr_save_streetnet and dodgr_load_streetnet functions. (This is because the weighted streetnets also have accompanying data stored in a local temporary cache directory; attempting to pass a weighted street network without these accompanying cache files will generally error.)

Some key-value pairs may also directly influence not just the value of the graph produced by this function, but also its size. Among these are "oneway" flags. Without these flags, each edge will be represented in directed form, and so as two rows of the graph: one for A -> B, and one for B -> A. If a way is tagged in OSM as "oneway" = "yes", and if oneway flags are respected for a chosen weighting profile (which, for example, they are generally not for pedestrian or "foot" weighting), then only one edge will be returned representing travel in the direction permitted within the OSM data. Thus weighting a network which includes "oneway" flags, and using a weighting profile which respects these, will generate a graph with fewer rows than a graph produced by ignoring those "oneway" flags.

Value

A data.frame of edges representing the street network, with distances in metres and times in seconds, along with a column of graph component numbers. Times for sf-formatted street networks are only approximate, and do not take into account traffic lights, turn angles, or elevation changes. Times for sc-formatted street networks take into account all of these factors, with elevation changes automatically taken into account for networks generated with the osmdata function osm_elevation().

Note

Names for the wt_profile parameter are taken from weighting_profiles, which is a list including a data.frame also called weighting_profiles of weights for different modes of transport. Values for wt_profile are taken from current modes included there, which are "bicycle", "foot", "goods", "hgv", "horse", "moped", "motorcar", "motorcycle", "psv", and "wheelchair". Railway routing can be implemented with the separate function weight_railway. Alternatively, the entire weighting_profile structures can be written to a local .json-formatted file with write_dodgr_wt_profile, the values edited as desired, and the name of this file passed as the wt_profile_file parameter.

The resultant graph includes only those edges for which the given weighting profile specifies finite edge weights. Any edges of types not present in a given weighting profile are automatically removed from the weighted streetnet.

If the resultant graph is to be contracted via dodgr_contract_graph, and if the columns of the graph have been, or will be, modified, then automatic caching must be switched off with dodgr_cache_off. If not, the dodgr_contract_graph function will return the automatically cached version, which is the contracted version of the full graph prior to any modification of columns.

See Also

write_dodgr_wt_profile, dodgr_times

Other extraction: dodgr_streetnet(), dodgr_streetnet_sc(), weight_railway()

Other extraction: dodgr_streetnet(), dodgr_streetnet_sc(), weight_railway()

Other extraction: dodgr_streetnet(), dodgr_streetnet_sc(), weight_railway()

Other extraction: dodgr_streetnet(), dodgr_streetnet_sc(), weight_railway()

Other extraction: dodgr_streetnet(), dodgr_streetnet_sc(), weight_railway()

Examples

# hampi is included with package as an 'osmdata' sf-formatted street network
net <- weight_streetnet (hampi)
class (net) # data.frame
dim (net) # 6096  11; 6096 streets
# os_roads_bristol is also included as an sf data.frame, but in a different
# format requiring identification of columns and specification of custom
# weighting scheme.
colnm <- "formOfWay"
wts <- data.frame (
    name = "custom",
    way = unique (os_roads_bristol [[colnm]]),
    value = c (0.1, 0.2, 0.8, 1)
)
net <- weight_streetnet (
    os_roads_bristol,
    wt_profile = wts,
    type_col = colnm, id_col = "identifier"
)
dim (net) # 406 11; 406 streets

# An example for a generic (non-OSM) highway, represented as the
# `routes_fast` object of the \pkg{stplanr} package, which is a
# SpatialLinesDataFrame.
## Not run: 
library (stplanr)
# merge all of the 'routes_fast' lines into a single network
r <- overline (routes_fast, attrib = "length", buff_dist = 1)
r <- sf::st_as_sf (r, crs = 4326)
# We need to specify both a `type` and `id` column for the
# \link{weight_streetnet} function.
r$type <- 1
r$id <- seq (nrow (r))
graph <- weight_streetnet (
    r,
    type_col = "type",
    id_col = "id",
    wt_profile = 1
)

## End(Not run)

Weighting profiles used to route different modes of transport.

Description

Collection of weighting profiles used to adjust the routing process to different means of transport. Modified from data taken from the Routino project, with additional tables for average speeds, dependence of speed on type of surface, and waiting times in seconds at traffic lights. The latter table (called "penalties") includes waiting times at traffic lights (in seconds), additional time penalties for turning across oncoming traffic ("turn"), and a binary flag indicating whether turn restrictions should be obeyed or not.

Format

List of data.frame objects with profile names, means of transport and weights.

References

https://www.routino.org/xml/routino-profiles.xml

See Also

Other data: hampi, os_roads_bristol


Write dodgr weighting profiles to local file.

Description

Write the dodgr street network weighting profiles to a local .json-formatted file for manual editing and subsequent re-reading.

Usage

write_dodgr_wt_profile(file = NULL)

Arguments

file

Full name (including path) of file to which to write. The .json suffix will be automatically appended.

Value

TRUE if writing successful.

See Also

weight_streetnet

Other misc: compare_heaps(), dodgr_flowmap(), dodgr_full_cycles(), dodgr_fundamental_cycles(), dodgr_insert_vertex(), dodgr_sample(), dodgr_sflines_to_poly(), dodgr_vertices(), merge_directed_graph(), summary.dodgr_dists_categorical()