From 36952ff52159eaa39754aba20bf5361606b84b9c Mon Sep 17 00:00:00 2001 From: robinlovelace Date: Mon, 23 Sep 2019 12:00:57 +0100 Subject: [PATCH] Close #237 --- vignettes/stplanr-route-nets.Rmd | 52 +++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/vignettes/stplanr-route-nets.Rmd b/vignettes/stplanr-route-nets.Rmd index 8e3f5994..e1ea67eb 100644 --- a/vignettes/stplanr-route-nets.Rmd +++ b/vignettes/stplanr-route-nets.Rmd @@ -63,18 +63,27 @@ class(sln@nb); length(unique(unlist(sln@nb))) identical(sln@sl$geometry, rnet$geometry) ``` +```{r} +sln_nodes = sln2points(sln) +nrow(sln_nodes) +length(sln@nb) +``` + ```{r} rnet_coordinates = sf::st_coordinates(rnet) set.seed(85) x = runif(n = 2, min = min(rnet_coordinates[, 1]), max = max(rnet_coordinates[, 1])) y = runif(n = 2, min = min(rnet_coordinates[, 2]), max = max(rnet_coordinates[, 2])) -xy_sf = sf::st_as_sf(data.frame(n = 1:2, x, y), coords = c("x", "y"), crs = sf::st_crs(rnet)) +crs = sf::st_crs(rnet) +xy_sf = sf::st_as_sf(data.frame(n = 1:2, x, y), coords = c("x", "y"), crs = crs) xy_nodes = stplanr::find_network_nodes(sln = sln, x = x, y = y) ``` # Routing on route networks ```{r} +plot(rnet$geometry) +plot(sln_nodes, add = TRUE) xy_path = sum_network_routes(sln = sln, start = xy_nodes[1], end = xy_nodes[2], sumvars = "length") # xy_path = sum_network_links(sln = sln, start = xy_nodes[1], end = xy_nodes[2]) plot(rnet$geometry) @@ -82,6 +91,47 @@ plot(xy_sf$geometry, add = TRUE) plot(xy_path$geometry, add = TRUE, lwd = 5) ``` +# Adding new nodes + +New nodes can be added to the network, although this should be done before the graph representation is created. +Imagine we want to create a point half way along the the most westerly route segment in the network, near the coordinates -1.540, 53.826: + +```{r netpoint} +new_point_coordinates = c(-1.540, 53.826) +p = sf::st_sf(geometry = sf::st_sfc(sf::st_point(new_point_coordinates)), crs = crs) +``` + +We can identify the nearest point on the network at this point and use that to split the associated linestring: + +```{r, fig.show='hold'} +pmat = matrix(new_point_coordinates, ncol = 2) +rmat = nabor::knn(data = rnet_coordinates[, 1:2], query = pmat, k = 1) +rnet_point_nearst_p = sf::st_sfc(sf::st_point(rnet_coordinates[rmat$nn.idx, 1:2]), crs = crs) +rnet_intersecting_p = lengths(st_intersects(rnet, rnet_point_nearst_p)) > 0 +rnet_line_near_p = rnet[rnet_intersecting_p, ] +rnet_lines_far_p = rnet[!rnet_intersecting_p, ] +rnet_new_geometry_collection = lwgeom::st_split(rnet_line_near_p, rnet_point_nearst_p) +rnet_new_linestrings = sf::st_cast(rnet_new_geometry_collection) +rnet_new = rbind(rnet_lines_far_p, rnet_new_linestrings) +plot(rnet_lines_far_p$geometry) +plot(rnet_line_near_p$geometry, col = "grey", lwd = 6, add = TRUE) +plot(rnet_new_linestrings, col = "blue", lwd = c(1, 4), add = TRUE) +sln_new = SpatialLinesNetwork(rnet_new) +node_new = find_network_nodes(sln = sln_new, x = new_point_coordinates[1], y = new_point_coordinates[2]) +node_xy2 = find_network_nodes(sln = sln_new, x = x[1], y = y[1]) +sln_new_path = sum_network_routes(sln = sln_new, start = node_new[1], end = node_xy2, sumvars = "length") +plot(rnet_new$geometry) +plot(sln_nodes$geometry, col = "red", add = TRUE) +plot(p$geometry, cex = 5, add = TRUE) +plot(sln_new_path$geometry, lwd = 5, add = TRUE) +``` + + + +```{r newnetplot} + +``` + # Other approaches Other approaches to working with route networks include: