% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/flows.R
\name{dodgr_flows_aggregate}
\alias{dodgr_flows_aggregate}
\title{dodgr_flows_aggregate}
\usage{
dodgr_flows_aggregate(
  graph,
  from,
  to,
  flows,
  contract = TRUE,
  heap = "BHeap",
  tol = 0.000000000001,
  norm_sums = TRUE,
  quiet = TRUE
)
}
\arguments{
\item{graph}{\code{data.frame} or equivalent object representing the network
graph (see Details)}

\item{from}{Vector or matrix of points \strong{from} which aggregate flows are to
be calculated (see Details)}

\item{to}{Vector or matrix of points \strong{to} which aggregate flows are to be
calculated (see Details)}

\item{flows}{Matrix of flows with \code{nrow(flows)==length(from)} and
\code{ncol(flows)==length(to)}.}

\item{contract}{If \code{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). \code{FALSE} should only be used if the \code{graph}
has already been contracted.}

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

\item{tol}{Relative tolerance below which flows towards \code{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 \code{from} point over which
flows are aggregated. To remove any such effect, set \code{tol = 0}.}

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

\item{quiet}{If \code{FALSE}, display progress messages on screen.}
}
\value{
Modified version of graph with additional \code{flow} column added.
}
\description{
Aggregate flows throughout a network based on an input matrix of flows
between all pairs of \code{from} and \code{to} points.
}
\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 \code{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 \code{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 \code{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
\verb{RcppParallel::setThreadOptions (numThreads = <desired_number>)}.
}
\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
\dontrun{
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)
}

# 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.
\dontrun{
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"])
}
}
\seealso{
Other distances: 
\code{\link{dodgr_distances}()},
\code{\link{dodgr_dists_categorical}()},
\code{\link{dodgr_dists}()},
\code{\link{dodgr_flows_disperse}()},
\code{\link{dodgr_flows_si}()},
\code{\link{dodgr_isochrones}()},
\code{\link{dodgr_isodists}()},
\code{\link{dodgr_isoverts}()},
\code{\link{dodgr_paths}()},
\code{\link{dodgr_times}()}
}
\concept{distances}
