From f44d8094e12a9162e490e6906e65ef3bcbad86b5 Mon Sep 17 00:00:00 2001 From: mpadge Date: Thu, 11 Aug 2022 11:39:35 +0200 Subject: [PATCH] add add_nodes_to_graph fn; closes #103 --- DESCRIPTION | 2 +- NAMESPACE | 1 + R/match-points.R | 97 ++++++++++++++++++++++++++ codemeta.json | 2 +- man/add_nodes_to_graph.Rd | 46 ++++++++++++ man/compare_heaps.Rd | 1 + man/dodgr_flowmap.Rd | 1 + man/dodgr_full_cycles.Rd | 1 + man/dodgr_fundamental_cycles.Rd | 1 + man/dodgr_insert_vertex.Rd | 1 + man/dodgr_sample.Rd | 1 + man/dodgr_sflines_to_poly.Rd | 1 + man/dodgr_vertices.Rd | 1 + man/match_points_to_graph.Rd | 1 + man/match_points_to_verts.Rd | 1 + man/match_pts_to_graph.Rd | 1 + man/match_pts_to_verts.Rd | 1 + man/merge_directed_graph.Rd | 1 + man/summary.dodgr_dists_categorical.Rd | 1 + man/write_dodgr_wt_profile.Rd | 1 + 20 files changed, 161 insertions(+), 2 deletions(-) create mode 100644 man/add_nodes_to_graph.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 45a0f7760..cb2a9d68d 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: dodgr Title: Distances on Directed Graphs -Version: 0.2.14.086 +Version: 0.2.14.087 Authors@R: c( person("Mark", "Padgham", , "mark.padgham@email.com", role = c("aut", "cre")), person("Andreas", "Petutschnig", role = "aut"), diff --git a/NAMESPACE b/NAMESPACE index e50034a3b..5f8db9635 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -5,6 +5,7 @@ S3method(weight_streetnet,default) S3method(weight_streetnet,sc) S3method(weight_streetnet,sf) export("%>%") +export(add_nodes_to_graph) export(clear_dodgr_cache) export(compare_heaps) export(dodgr_cache_off) diff --git a/R/match-points.R b/R/match-points.R index e2332ceba..21087e500 100644 --- a/R/match-points.R +++ b/R/match-points.R @@ -160,3 +160,100 @@ match_points_to_graph <- function (graph, xy, connected = FALSE) { match_pts_to_graph (graph, xy, connected = connected) } + +#' Insert new nodes into a graph, breaking edges at point of nearest +#' intersection. +#' +#' The "id" value of each edge to be divided through insertion of new points is +#' modified to produce two new "id" values with suffixes "_A" and "_B". This +#' routine presumes graphs to be `dodgr_streetnet` object, with geographical +#' coordinates. +#' +#' @inheritParams match_pts_to_graph +#' @return A modified version of `graph`, with additional edges formed by +#' breaking previous edges at nearest penpendicular intersections with the +#' points, `xy`. +#' @family misc +#' @export +add_nodes_to_graph <- function (graph, xy) { + + index <- match_pts_to_graph (graph, xy) + + gr_cols <- dodgr_graph_cols (graph) + gr_cols <- unlist (gr_cols [which (!is.na (gr_cols))]) + graph_std <- graph [, gr_cols] # standardise column names + names (graph_std) <- names (gr_cols) + + # Expand index to include all potentially duplicated edges: + index <- lapply (seq_along (index), function (i) { + out <- which ( + (graph_std$from == graph_std$from [index [i]] & + graph_std$to == graph_std$to [index [i]]) | + (graph_std$from == graph_std$to [index [i]] & + graph_std$to == graph_std$from [index [i]]) + ) + cbind (rep (i, length (out)), out) + }) + index <- data.frame (do.call (rbind, index)) + names (index) <- c ("n", "index") + + genhash <- function (len = 10) { + paste0 (sample (c (0:9, letters, LETTERS), size = len), collapse = "") + } + + edges_to_split <- graph_std [index$index, ] + graph_to_add <- graph [index$index, ] + + graph_std <- graph_std [-index$index, ] + graph <- graph [-index$index, ] + + edges_to_split$n <- index$n + + edges_split <- lapply (unique (index$n), function (i) { + + edges_to_split_i <- edges_to_split [which (edges_to_split$n == i), ] + + d_wt <- edges_to_split_i$d_weighted / edges_to_split_i$d + t_wt <- edges_to_split_i$time_weighted / edges_to_split_i$time + t_scale <- edges_to_split_i$time / edges_to_split_i$d + + new_edges_i <- lapply (seq (nrow (edges_to_split_i)), function (e) { + + edge_i <- rbind (edges_to_split_i [e, ], edges_to_split_i [e, ]) + edge_i$to [1] <- edge_i$from [2] <- genhash () + edge_i$xto [1] <- xy$x [i] + edge_i$yto [1] <- xy$y [i] + edge_i$xfr [2] <- xy$x [i] + edge_i$yfr [2] <- xy$y [i] + + xy_i <- data.frame ( + x = c (edge_i [1, "xfr"], edge_i [1, "xto"], edge_i [2, "xto"]), + y = c (edge_i [1, "yfr"], edge_i [1, "yto"], edge_i [2, "yto"]) + ) + dmat <- geodist::geodist (xy_i) + edge_i$d [1] <- dmat [1, 2] + edge_i$d [2] <- dmat [2, 3] + + edge_i$d_weighted <- edge_i$d * d_wt + edge_i$time <- edge_i$d * t_scale + edge_i$time_weighted <- edge_i$time * t_wt + + edge_i$edge_id <- paste0 (edge_i$edge_id, "_", LETTERS [e]) + + return (edge_i) + }) + + return (do.call (rbind, new_edges_i)) + }) + + edges_split <- do.call (rbind, edges_split) + + # Then match edges_split back on to original graph: + graph_to_add <- graph_to_add [edges_split$n, ] + gr_cols <- gr_cols [which (!is.na (gr_cols))] + for (g in seq_along (gr_cols)) { + graph_to_add [, gr_cols [g]] <- edges_split [[names (gr_cols) [g]]] + } + + return (rbind (graph, graph_to_add)) +} diff --git a/codemeta.json b/codemeta.json index 1c32b48d7..b708d42ad 100644 --- a/codemeta.json +++ b/codemeta.json @@ -7,7 +7,7 @@ "codeRepository": "https://github.com/ATFutures/dodgr", "issueTracker": "https://github.com/ATFutures/dodgr/issues", "license": "https://spdx.org/licenses/GPL-3.0", - "version": "0.2.14.086", + "version": "0.2.14.087", "programmingLanguage": { "@type": "ComputerLanguage", "name": "R", diff --git a/man/add_nodes_to_graph.Rd b/man/add_nodes_to_graph.Rd new file mode 100644 index 000000000..25a655a81 --- /dev/null +++ b/man/add_nodes_to_graph.Rd @@ -0,0 +1,46 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/match-points.R +\name{add_nodes_to_graph} +\alias{add_nodes_to_graph} +\title{Insert new nodes into a graph, breaking edges at point of nearest +intersection.} +\usage{ +add_nodes_to_graph(graph, xy) +} +\arguments{ +\item{graph}{A \code{dodgr} graph with spatial coordinates, such as a +\code{dodgr_streetnet} object.} + +\item{xy}{coordinates of points to be matched to the vertices, either as +matrix or \pkg{sf}-formatted \code{data.frame}.} +} +\value{ +A modified version of \code{graph}, with additional edges formed by +breaking previous edges at nearest penpendicular intersections with the +points, \code{xy}. +} +\description{ +The "id" value of each edge to be divided through insertion of new points is +modified to produce two new "id" values with suffixes "_A" and "_B". This +routine presumes graphs to be \code{dodgr_streetnet} object, with geographical +coordinates. +} +\seealso{ +Other misc: +\code{\link{compare_heaps}()}, +\code{\link{dodgr_flowmap}()}, +\code{\link{dodgr_full_cycles}()}, +\code{\link{dodgr_fundamental_cycles}()}, +\code{\link{dodgr_insert_vertex}()}, +\code{\link{dodgr_sample}()}, +\code{\link{dodgr_sflines_to_poly}()}, +\code{\link{dodgr_vertices}()}, +\code{\link{match_points_to_graph}()}, +\code{\link{match_points_to_verts}()}, +\code{\link{match_pts_to_graph}()}, +\code{\link{match_pts_to_verts}()}, +\code{\link{merge_directed_graph}()}, +\code{\link{summary.dodgr_dists_categorical}()}, +\code{\link{write_dodgr_wt_profile}()} +} +\concept{misc} diff --git a/man/compare_heaps.Rd b/man/compare_heaps.Rd index 57f827798..a6c175c74 100644 --- a/man/compare_heaps.Rd +++ b/man/compare_heaps.Rd @@ -38,6 +38,7 @@ compare_heaps (graph, nverts = 1000, replications = 1) } \seealso{ Other misc: +\code{\link{add_nodes_to_graph}()}, \code{\link{dodgr_flowmap}()}, \code{\link{dodgr_full_cycles}()}, \code{\link{dodgr_fundamental_cycles}()}, diff --git a/man/dodgr_flowmap.Rd b/man/dodgr_flowmap.Rd index 5df6521ef..85b527cdd 100644 --- a/man/dodgr_flowmap.Rd +++ b/man/dodgr_flowmap.Rd @@ -42,6 +42,7 @@ dodgr_flowmap (graph_undir) } \seealso{ Other misc: +\code{\link{add_nodes_to_graph}()}, \code{\link{compare_heaps}()}, \code{\link{dodgr_full_cycles}()}, \code{\link{dodgr_fundamental_cycles}()}, diff --git a/man/dodgr_full_cycles.Rd b/man/dodgr_full_cycles.Rd index 56c11e873..ff156b54b 100644 --- a/man/dodgr_full_cycles.Rd +++ b/man/dodgr_full_cycles.Rd @@ -39,6 +39,7 @@ cyc2 <- dodgr_full_cycles (net) } \seealso{ Other misc: +\code{\link{add_nodes_to_graph}()}, \code{\link{compare_heaps}()}, \code{\link{dodgr_flowmap}()}, \code{\link{dodgr_fundamental_cycles}()}, diff --git a/man/dodgr_fundamental_cycles.Rd b/man/dodgr_fundamental_cycles.Rd index 8e7aa0dad..fdd7dd7f2 100644 --- a/man/dodgr_fundamental_cycles.Rd +++ b/man/dodgr_fundamental_cycles.Rd @@ -58,6 +58,7 @@ cyc <- dodgr_fundamental_cycles (graph, verts) } \seealso{ Other misc: +\code{\link{add_nodes_to_graph}()}, \code{\link{compare_heaps}()}, \code{\link{dodgr_flowmap}()}, \code{\link{dodgr_full_cycles}()}, diff --git a/man/dodgr_insert_vertex.Rd b/man/dodgr_insert_vertex.Rd index 9d7718d49..e0b4ec7db 100644 --- a/man/dodgr_insert_vertex.Rd +++ b/man/dodgr_insert_vertex.Rd @@ -43,6 +43,7 @@ nrow (graph2) # new edges added to graph2 } \seealso{ Other misc: +\code{\link{add_nodes_to_graph}()}, \code{\link{compare_heaps}()}, \code{\link{dodgr_flowmap}()}, \code{\link{dodgr_full_cycles}()}, diff --git a/man/dodgr_sample.Rd b/man/dodgr_sample.Rd index 8686d27ed..d6d936b0c 100644 --- a/man/dodgr_sample.Rd +++ b/man/dodgr_sample.Rd @@ -33,6 +33,7 @@ nrow (dodgr_vertices (graph)) # 200 } \seealso{ Other misc: +\code{\link{add_nodes_to_graph}()}, \code{\link{compare_heaps}()}, \code{\link{dodgr_flowmap}()}, \code{\link{dodgr_full_cycles}()}, diff --git a/man/dodgr_sflines_to_poly.Rd b/man/dodgr_sflines_to_poly.Rd index 67960e7c5..45ee24c4d 100644 --- a/man/dodgr_sflines_to_poly.Rd +++ b/man/dodgr_sflines_to_poly.Rd @@ -25,6 +25,7 @@ fundamental cycles within the \code{LINESTRING} objects. } \seealso{ Other misc: +\code{\link{add_nodes_to_graph}()}, \code{\link{compare_heaps}()}, \code{\link{dodgr_flowmap}()}, \code{\link{dodgr_full_cycles}()}, diff --git a/man/dodgr_vertices.Rd b/man/dodgr_vertices.Rd index d3c9c69fc..8ff3880d0 100644 --- a/man/dodgr_vertices.Rd +++ b/man/dodgr_vertices.Rd @@ -27,6 +27,7 @@ v <- dodgr_vertices (graph) } \seealso{ Other misc: +\code{\link{add_nodes_to_graph}()}, \code{\link{compare_heaps}()}, \code{\link{dodgr_flowmap}()}, \code{\link{dodgr_full_cycles}()}, diff --git a/man/match_points_to_graph.Rd b/man/match_points_to_graph.Rd index 8fbb28190..74dcdd1c0 100644 --- a/man/match_points_to_graph.Rd +++ b/man/match_points_to_graph.Rd @@ -42,6 +42,7 @@ graph [edges, ] # The edges of the graph closest to `xy` } \seealso{ Other misc: +\code{\link{add_nodes_to_graph}()}, \code{\link{compare_heaps}()}, \code{\link{dodgr_flowmap}()}, \code{\link{dodgr_full_cycles}()}, diff --git a/man/match_points_to_verts.Rd b/man/match_points_to_verts.Rd index 07024c3a5..46785bc7e 100644 --- a/man/match_points_to_verts.Rd +++ b/man/match_points_to_verts.Rd @@ -43,6 +43,7 @@ pts # names of those vertices } \seealso{ Other misc: +\code{\link{add_nodes_to_graph}()}, \code{\link{compare_heaps}()}, \code{\link{dodgr_flowmap}()}, \code{\link{dodgr_full_cycles}()}, diff --git a/man/match_pts_to_graph.Rd b/man/match_pts_to_graph.Rd index 62fc404b0..f494ebb6b 100644 --- a/man/match_pts_to_graph.Rd +++ b/man/match_pts_to_graph.Rd @@ -48,6 +48,7 @@ graph [edges, ] # The edges of the graph closest to `xy` } \seealso{ Other misc: +\code{\link{add_nodes_to_graph}()}, \code{\link{compare_heaps}()}, \code{\link{dodgr_flowmap}()}, \code{\link{dodgr_full_cycles}()}, diff --git a/man/match_pts_to_verts.Rd b/man/match_pts_to_verts.Rd index 8f120f5c8..21924339b 100644 --- a/man/match_pts_to_verts.Rd +++ b/man/match_pts_to_verts.Rd @@ -43,6 +43,7 @@ pts # names of those vertices } \seealso{ Other misc: +\code{\link{add_nodes_to_graph}()}, \code{\link{compare_heaps}()}, \code{\link{dodgr_flowmap}()}, \code{\link{dodgr_full_cycles}()}, diff --git a/man/merge_directed_graph.Rd b/man/merge_directed_graph.Rd index 8e00a0f4b..65ab3b7bc 100644 --- a/man/merge_directed_graph.Rd +++ b/man/merge_directed_graph.Rd @@ -46,6 +46,7 @@ nrow (graph_undir) # the latter is much smaller } \seealso{ Other misc: +\code{\link{add_nodes_to_graph}()}, \code{\link{compare_heaps}()}, \code{\link{dodgr_flowmap}()}, \code{\link{dodgr_full_cycles}()}, diff --git a/man/summary.dodgr_dists_categorical.Rd b/man/summary.dodgr_dists_categorical.Rd index 4b031c517..98b7f0216 100644 --- a/man/summary.dodgr_dists_categorical.Rd +++ b/man/summary.dodgr_dists_categorical.Rd @@ -19,6 +19,7 @@ Transform a result from 'dodgr_dists_categorical' to summary statistics } \seealso{ Other misc: +\code{\link{add_nodes_to_graph}()}, \code{\link{compare_heaps}()}, \code{\link{dodgr_flowmap}()}, \code{\link{dodgr_full_cycles}()}, diff --git a/man/write_dodgr_wt_profile.Rd b/man/write_dodgr_wt_profile.Rd index ccc60bd92..d4e37d1c4 100644 --- a/man/write_dodgr_wt_profile.Rd +++ b/man/write_dodgr_wt_profile.Rd @@ -21,6 +21,7 @@ Write the \code{dodgr} street network weighting profiles to a local \link{weight_streetnet} Other misc: +\code{\link{add_nodes_to_graph}()}, \code{\link{compare_heaps}()}, \code{\link{dodgr_flowmap}()}, \code{\link{dodgr_full_cycles}()},