#R and Transport - The dodgr package

      library(osmdata)
## Warning: package 'osmdata' was built under R version 4.0.5
## Data (c) OpenStreetMap contributors, ODbL 1.0. https://www.openstreetmap.org/copyright
    library(dodgr)
## Warning: package 'dodgr' was built under R version 4.0.5
        # dodgr is an R package for calculating Distances On Directed Graphs. 
        # It does so very efficiently, and is able to process larger graphs 
        # than many other comparable R packages.
        # https://cran.r-project.org/web/packages/dodgr/vignettes/dodgr.html
        # It also implements Dual-Weighted Directed Graphs.
        
        # Graphs in dodgr are represented by simple flat data.frame objects
        # with the column structure from, to, distance and for 
        # dual weighted from, to, weight, distance.
        
            
        # Columns must be named 'from' and 'to'
        
    net <- data.frame(
            from=c(1,1,2,2,3),
            to=c(1,2,2,3,3),
            distance=c(1,1,1,1,1)
            )

        # Distance in diagonal is 0 although it is set to 1 in df
    
    out <- dodgr_dists(net)
    out
##    1  2 3
## 1  0  1 2
## 2 NA  0 1
## 3 NA NA 0
    class(out)
## [1] "matrix" "array"
        # Notice the simply output no new class with complicated data management routines.
        

        # Determine 
        
    out <- dodgr_dists(net, from = c ("1", "2"), to = c ("1", "2", "3"))
    out
##    1 2 3
## 1  0 1 2
## 2 NA 0 1
    class(out)
## [1] "matrix" "array"
        # Although the package has been intentionally developed to be adaptable 
        # to any kinds of networks, most of the applications illustrated here concern 
        # street networks, and also illustrate several helper functions the package 
        # offers for working with street networks. 
        
        # Cool example drawing random points in a square ... 
        #bb <- osmdata::getbb("Copenhagen")
        #npts <- 1000
        #xy <- apply(bb, 1, function (i) min (i) + runif (npts) * diff (i))
        #bb; head(xy)
        
        # Download the street network ...
        #net <- dodgr_streetnet(bb)
        #net <- weight_streetnet(net, wt_profile = "foot")
        #system.time (
    #           d <- dodgr_dists (net, from = xy, to = xy)
#               )
    
        
                # Cool example drawing random points in a square ... 
        bb <- osmdata::getbb("Copenhagen")
        npts <- 10
        xy <- apply(bb, 1, function (i) min (i) + runif (npts) * diff (i))
        bb; head(xy)
##        min      max
## x 12.41007 12.73007
## y 55.52672 55.84672
##             x        y
## [1,] 12.61028 55.55514
## [2,] 12.45709 55.84063
## [3,] 12.67912 55.62042
## [4,] 12.53857 55.52998
## [5,] 12.69553 55.79669
## [6,] 12.42636 55.55347
        # Download the street network ...
        net <- dodgr_streetnet(bb)
        trans_net <- weight_streetnet(net, wt_profile = "foot")
## The following highway types are present in data yet lack corresponding weight_profile values: NA, corridor, raceway, construction, proposed, platform, disused, rest_area, elevator, bus_stop, skyway,
        system.time (
                d <- dodgr_dists(trans_net, from = xy, to = xy)
                )
##    user  system elapsed 
##    2.13    0.08   32.88
        # Make a small net ..
        bbox <- matrix(c(12.5926,55.6612,12.6325,55.6728),ncol=2)
        colnames(bbox) <- c("min","max")
        rownames(bbox) <- c("x","y")
        small_net <- dodgr_streetnet(bbox)
        
        # plot it 
        #plot(small_net[,c("osm_id","geometry")])

        # plot with tmap
        library(tmap)
## Warning: package 'tmap' was built under R version 4.0.5
        temp <- small_net[,c("osm_id","geometry")]
        tm_shape(temp) + tm_layout(legend.outside=TRUE,bg='black') + 
            tm_lines("osm_id",lwd=1.5)
## Warning: Number of levels of the variable "osm_id" is 1387, which is
## larger than max.categories (which is 30), so levels are combined. Set
## tmap_options(max.categories = 1387) in the layer function to show all levels.
## Linking to GEOS 3.9.0, GDAL 3.2.1, PROJ 7.2.1

        # plot with osmplotr
        #library (osmplotr)
    #   library (magrittr)
#       map <- osm_basemap (small_net, bg = "gray95") %>%
#          add_osm_objects (small_net, col = "gray5") %>%
#         add_axes () %>%
#         print_osm_map ()

        # Convert sf to flat df
        small_net_graph <- weight_streetnet(small_net, wt_profile = "motorcar")
## The following highway types are present in data yet lack corresponding weight_profile values: proposed, NA,
        dim(small_net_graph)
## [1] 5748   15
        head(small_net_graph)
##   geom_num edge_id    from_id from_lon from_lat      to_id   to_lon   to_lat
## 1        1       1    6504028 12.60427 55.66464 8579429824 12.60434 55.66457
## 2        1       2 8579429824 12.60434 55.66457  278116591 12.60503 55.66389
## 3        1       3  278116591 12.60503 55.66389  445526153 12.60618 55.66292
## 4        1       4  445526153 12.60618 55.66292 4262012517 12.60617 55.66290
## 5        1       5 4262012517 12.60617 55.66290    6504038 12.60617 55.66283
## 6        2       6    7397303 12.60907 55.66238 5883068090 12.60961 55.66228
##            d d_weighted     highway  way_id component       time time_weighted
## 1   8.613715  20.672915 residential 1522015         1  1.2403749     2.9768998
## 2  87.671805 210.412331 residential 1522015         1 12.6247399    30.2993757
## 3 129.354351 310.450443 residential 1522015         1 18.6270266    44.7048638
## 4   2.105287   5.052689 residential 1522015         1  0.3031614     0.7275873
## 5   7.830636  18.793525 residential 1522015         1  1.1276115     2.7062677
## 6  35.636990  61.091983    tertiary 1522016         1  3.2073291     5.4982785
        # Only connected part ...
        small_net_graph_con <- small_net_graph[small_net_graph$component == 1, ]