Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

README.Rmd build fails #19

Closed
layik opened this issue Mar 11, 2019 · 14 comments
Closed

README.Rmd build fails #19

layik opened this issue Mar 11, 2019 · 14 comments

Comments

@layik
Copy link
Collaborator

layik commented Mar 11, 2019

Quitting from lines 75-76 (README.Rmd) 
Error in stplanr::line2route(desire_lines, route_fun = stplanr::route_cyclestreet) : 
object 'r' not found
Calls: <Anonymous> ... withCallingHandlers -> withVisible -> eval -> eval -> <Anonymous>
Execution halted
@Robinlovelace
Copy link
Member

You need a CYCLESTREETS=api-key saved in .Renviron, e.g. by running:

usethis::edit_r_environ()

However, that should definitely be better documented: that command didn't exist when I wrote the route_cyclestreets() function, and it makes life much easier.

@Robinlovelace
Copy link
Member

Another idea: use local routing, but that also has costs. One for @mpadge: is dodgr good to go for point-to-point routing... Will put together a reprex on that.

@mpadge
Copy link

mpadge commented Mar 11, 2019

Yep, absolutely good to do. Give me an example with external call, and I'll happily dodgerify it

@Robinlovelace
Copy link
Member

Heads-up @mpadge this is impressive from your awesome dodgr pkg - what's the best way to get a single sf object back from the path2 object, including distance and other per-route characteristics if needs be. Very excited to finally be almost implementing this in stplanr as route_dodgr() (sound good based on this code?), and this could be the perfect excuse to finally do so.

@mpadge a 'predodgrified' (~90%, nonoptimised) version coming up!

# get origin-destination coords
(from_coords = stplanr::geo_code("chapeltown, leeds"))
#> [1] -1.531175 53.816667
(to_coords = stplanr::geo_code("university of leeds"))
#> [1] -1.552457 53.803872

# with cyclestreets (negative: needs api key)
(route1 = stplanr::route_cyclestreet(from_coords, to_coords))
#> class       : SpatialLinesDataFrame 
#> features    : 1 
#> extent      : -1.55247, -1.53145, 53.80275, 53.81671  (xmin, xmax, ymin, ymax)
#> coord. ref. : +init=epsg:4326 +proj=longlat +datum=WGS84 +no_defs +ellps=WGS84 +towgs84=0,0,0 
#> variables   : 15
#> names       :    plan,           start,           finish, length, time, waypoint, cum_hill, change_elev, dif_max_min, up_tot, down_tot, av_incline, co2_saving, calories, busyness 
#> value       : fastest, Chapeltown Road, Car storage area,   2663,  748,      113,       86,          -8,          34,     39,       47,  0.0322944,        496,       54,    25613

# with osrm (negative: very limited api rate limits)
(route2 = stplanr::route_osrm(from_coords, to_coords))
#> class       : SpatialLinesDataFrame 
#> features    : 1 
#> extent      : -1.55523, -1.53145, 53.79947, 53.8167  (xmin, xmax, ymin, ymax)
#> coord. ref. : +proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs +towgs84=0,0,0 
#> variables   : 2
#> names       : distance, duration 
#> value       :   3503.9,    410.2

# with dodgr (negative: involves downloading lots of osm data, but that can be reduced...)
# inspiration: https://github.com/Robinlovelace/geocomp-tranport-workshop

library(dodgr)
net = dodgr_streetnet(sp::bbox(route2)) # would be good to have 'profile = "cycle"' or similar
net_sf = sf::st_sf(net)
plot(net_sf$geometry)
ways_dg = weight_streetnet(net)
#> The following highway types are present in data yet lack corresponding weight_profile values: no, corridor, construction,
summary(ways_dg)
#>     geom_num         edge_id        from_id             from_lon     
#>  Min.   :   1.0   Min.   :    1   Length:14650       Min.   :-1.563  
#>  1st Qu.: 511.2   1st Qu.: 3663   Class :character   1st Qu.:-1.552  
#>  Median :1058.0   Median : 7326   Mode  :character   Median :-1.545  
#>  Mean   :1085.3   Mean   : 7326                      Mean   :-1.545  
#>  3rd Qu.:1668.0   3rd Qu.:10988                      3rd Qu.:-1.539  
#>  Max.   :2199.0   Max.   :14650                      Max.   :-1.513  
#>     from_lat        to_id               to_lon           to_lat     
#>  Min.   :53.80   Length:14650       Min.   :-1.563   Min.   :53.80  
#>  1st Qu.:53.80   Class :character   1st Qu.:-1.552   1st Qu.:53.80  
#>  Median :53.81   Mode  :character   Median :-1.545   Median :53.81  
#>  Mean   :53.81                      Mean   :-1.545   Mean   :53.81  
#>  3rd Qu.:53.81                      3rd Qu.:-1.539   3rd Qu.:53.81  
#>  Max.   :53.82                      Max.   :-1.513   Max.   :53.82  
#>        d               d_weighted           highway         
#>  Min.   :0.0002846   Min.   : 0.000e+00   Length:14650      
#>  1st Qu.:0.0066948   1st Qu.: 0.000e+00   Class :character  
#>  Median :0.0130474   Median : 0.000e+00   Mode  :character  
#>  Mean   :0.0194124   Mean   :7.044e+306                     
#>  3rd Qu.:0.0250488   3rd Qu.: 0.000e+00                     
#>  Max.   :0.2424939   Max.   :1.798e+308                     
#>     way_id            component     
#>  Length:14650       Min.   : 1.000  
#>  Class :character   1st Qu.: 1.000  
#>  Mode  :character   Median : 1.000  
#>                     Mean   : 1.036  
#>                     3rd Qu.: 1.000  
#>                     Max.   :13.000

verts = dodgr_vertices(ways_dg) # the vertices or points for routing
knf = nabor::knn(cbind(verts$x, verts$y), matrix(from_coords, ncol = 2), k = 1)
knt = nabor::knn(cbind(verts$x, verts$y), matrix(to_coords, ncol = 2), k = 1)
dp = dodgr_paths(ways_dg, from = verts$id[knf$nn.idx], to = verts$id[knt$nn.idx])
path2 = verts[match(dp[[1]][[1]], verts$id), ]
head(path2)
#>              id         x        y component    n
#> 1064 1303834554 -1.531542 53.81645         1  677
#> 3658  245494251 -1.531562 53.81641         1 1992
#> 7646   52690754 -1.531643 53.81621         1 4067
#> 1137   52690529 -1.531796 53.81588         1  712
#> 7642  989067410 -1.531880 53.81572         1 4066
#> 7640  982577602 -1.531912 53.81565         1 4065
path2_linestring = sf::st_linestring(cbind(path2$x, path2$y))
path2_sf = sf::st_sf(sf::st_sfc(path2_linestring))
plot(path2_linestring, col = "red", lwd = 5, add = TRUE)

Created on 2019-03-11 by the reprex package (v0.2.1)

@Robinlovelace
Copy link
Member

BTW I like the route it chooses: a clear 'route1' that avoids busy Clay Pit Lane and goes through central Leeds ( take a different route, but also start and end at slightly different places).

@Robinlovelace
Copy link
Member

@layik I suggest we implement route_dodgr() in stplanr (way overdue) and use that as it's more powerful and flexible, although it eats memory when doing routing across a city.

@mpadge
Copy link

mpadge commented Mar 11, 2019

Wow, fast work, and a strong result. One point: easier and more (memory) efficient to use dodgr_to_sfc rather than sf::st_sf(). And one question: What is the rationale behind the knn bit? Why are you routing from multiple points? Or is that part of the non-optimised 10%? In which case, you could just:

from <- dodgr::match_pts_to_graph (verts, from)
to <- dodgr::match_pts_to_graph (verts, to)

and use those for the routing.

@Robinlovelace
Copy link
Member

Aha, yes, match_pts_to_graph() may be the missing component. Thanks for that, and the dodgr_to_sfc() function. Final question: any advice about extracting info from the route?

@mpadge
Copy link

mpadge commented Mar 11, 2019

Can you elaborate on what kind of info would be useful here? Overall distance is just dodgr_dists(), which is a very cheap calculation. Time is not yet calculated, but will be soon-ish in an upcoming version of dodgr. Anything else?

@Robinlovelace
Copy link
Member

Summary statistics about variables associated with the segments that the route passes along. Distance in m, time in s and hilliness metrics including total climb and ascent and steepest section would, at some point be useful. After that the distance on different types of road (e.g. highway=cycleway) and even the ability to create custom metrics such as the business measure from CycleStreets.net could be useful. Or documentation of how one could build these things from OSM and raster data representing gradient... But for now just distance is good enough (PCT uses hilliness and distance to estimate cycling levels, hilliness is a surprisingly powerful predictor of current cycling levels).

@mpadge
Copy link

mpadge commented Mar 12, 2019

Yeah, hilliness is the next biggest challenge that will come with this osmdata issue. That will then get piped in to dodgr, and then traffic signals and turn angles will be relatively straightforward, and all that's needed for accurate time estimates. So I guess your short answer is not yet, but a rough guess would be end of April or so that should be possible? In the meantime, distance is easy, as said - just use dodgr_dists(net, from, to).

@Robinlovelace
Copy link
Member

That sounds like a good plan to me!

@layik
Copy link
Collaborator Author

layik commented Mar 12, 2019

Way too much for me to cover between you two :) leave it to you guys. I did have a key at CYCLESTREET but not CYCLESTREETS.

@layik
Copy link
Collaborator Author

layik commented Mar 12, 2019

Builds absolutely fine!

@layik layik closed this as completed Mar 12, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants