Skip to content

Place to store code and example data for route sensitive routing hackathon

Notifications You must be signed in to change notification settings

sfnetworks/sloperouting

Repository files navigation

sloperouting

The goal of sloperouting is to provide a place to share code/data for slope sensitive routing.

The starting point is having the latest version of sfnetworks installed:

remotes::install_github("luukvdmeer/sfnetworks")
remotes::install_github("itsleeds/slopes")
remotes::install_github("itsleeds/od")
library(sfnetworks)
library(tidygraph)
#> 
#> Attaching package: 'tidygraph'
#> The following object is masked from 'package:stats':
#> 
#>     filter
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(sf)
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 7.0.0

Example with package data

Test the package is working:

net = as_sfnetwork(roxel, directed = FALSE)
class(net)
#> [1] "sfnetwork" "tbl_graph" "igraph"
sf::st_crs(net)
#> Coordinate Reference System:
#>   User input: EPSG:4326 
#>   wkt:
#> GEOGCRS["WGS 84",
#>     DATUM["World Geodetic System 1984",
#>         ELLIPSOID["WGS 84",6378137,298.257223563,
#>             LENGTHUNIT["metre",1]]],
#>     PRIMEM["Greenwich",0,
#>         ANGLEUNIT["degree",0.0174532925199433]],
#>     CS[ellipsoidal,2],
#>         AXIS["geodetic latitude (Lat)",north,
#>             ORDER[1],
#>             ANGLEUNIT["degree",0.0174532925199433]],
#>         AXIS["geodetic longitude (Lon)",east,
#>             ORDER[2],
#>             ANGLEUNIT["degree",0.0174532925199433]],
#>     USAGE[
#>         SCOPE["unknown"],
#>         AREA["World"],
#>         BBOX[-90,-180,90,180]],
#>     ID["EPSG",4326]]
net_proj = sf::st_transform(net, 3035)
p1 = net_proj %>%  
  activate(nodes) %>%  
  st_as_sf() %>%  
  slice(1)  
p2 = net_proj %>%  
  activate(nodes) %>%  
  st_as_sf() %>%  
  slice(9)  
p3 = sf::st_sfc(  
  sf::st_geometry(p1)[[1]] + sf::st_point(c(500, 500)),  
  crs = sf::st_crs(p1)  
)  
p4 = sf::st_sfc(  
  sf::st_geometry(p2)[[1]] + sf::st_point(c(-500, -500)),  
  crs = sf::st_crs(p2)  
)  
net_proj %>%  
  activate("edges") %>%  
  mutate(weight = edge_length()) %>%  
  convert(to_spatial_shortest_paths, p3, p4) ->  
  net_sp  
par(mar = c(1,1,1,1), bg = NA)  
plot(net_proj)  
plot(net_sp,
     col = "Orange", lwd = 1.5, cex = 1.5,
     add = T)

Example with data from Lisbon

library(sfnetworks)
library(tidygraph)
library(dplyr)
library(sf)
r = slopes::lisbon_road_segments
sf::st_is_longlat(r)
#> [1] FALSE
class(r)
#> [1] "sf"         "tbl_df"     "tbl"        "data.frame"
names(r)
#>  [1] "OBJECTID"   "fid_1"      "gradient_s" "Shape_Leng" "Z_Min"     
#>  [6] "Z_Max"      "Z_Mean"     "SLength"    "Min_Slope"  "Max_Slope" 
#> [11] "Avg_Slope"  "z0"         "z1"         "gradverifi" "query"     
#> [16] "lat"        "lon"        "lat_min"    "lat_max"    "lon_min"   
#> [21] "lon_max"    "bbox"       "geom"
plot(r["Avg_Slope"])

net = as_sfnetwork(r)

p1 = net %>%  
  activate(nodes) %>%  
  st_as_sf() %>%  
  slice(1)  
p2 = net %>%  
  activate(nodes) %>%  
  st_as_sf() %>%  
  slice(9)
#mapview::mapview(p1) + mapview::mapview(p2)
path1 = net %>%  
  activate("edges") %>%  
  mutate(weight = edge_length()) %>%  
  convert(to_spatial_shortest_paths, p1, p2)

plot(path1)

#mapview::mapview(st_as_sf(path1)) +
#  mapview::mapview(p1) + mapview::mapview(p2)


# Change the weight so that it is a product of edge_length and average slope.
# I am not sure how to access the edge columns to see if this worked
path2 = net %>%
  activate("edges") %>%
  mutate(weight = edge_length() * Avg_Slope) %>%
  convert(to_spatial_shortest_paths, p1, p2)
plot(path2)

# plot to see difference in routes
#plot(net, col = "lightgrey")  # How do we plot this with the Avg_Slope as a variable
plot(r["Avg_Slope"], reset = F, lwd=5)
plot(path1, add=T, lwd = 3, col = "red")

plot(r["Avg_Slope"], reset = F, lwd=5)
# less hilly route
plot(path2, add=T, col="green", lwd = 3)
plot(p1, add=T, col="darkred")
plot(p2, add=T, col="darkred")

# lets try with an UNDIRECTED GRAPH (results are different )
net_und = as_sfnetwork(r, directed=F)

path1_und = net_und %>%
  activate("edges") %>%
  mutate(weight = edge_length()) %>%
  convert(to_spatial_shortest_paths, p2, p1)
plot(path1_und)

# Change the weight so that it is a product of edge_length and average slope.
# I am not sure how to access the edge columns to see if this worked
path2_und = net_und %>%
  activate("edges") %>%
  mutate(weight = edge_length() * Avg_Slope) %>%
  convert(to_spatial_shortest_paths, p2, p1)
plot(path2_und)

plot(r["Avg_Slope"], reset = F, lwd=3)
plot(path1_und, add=T, col="red")
plot(path2_und, add=T, col="green")
plot(p1, add=T, col="darkred")
plot(p2, add=T, col="darkred")

Next step

Gradient deterrence function.

Shortest path in Lisbon with sfnetworks

About

Place to store code and example data for route sensitive routing hackathon

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages