2

I'm working on creating isochrones in R using osrm, and I keep finding problems with 0-10 minute travel times. Here's some code I've been using to test with a hand-picked test location:

install.packages("osrm")
install.packages("leaflet")

library(osrm)
library(leaflet)

locations <- tibble::tribble(
    ~place,       ~lon,     ~lat,
  "Albany", -73.767699, 42.652451)

iso <- osrmIsochrone(loc = c(locations$lon, locations$lat), breaks = seq(from = 0,to = 60, by = 10))

iso@data$drive_times <- factor(paste(iso@data$min, "to", iso@data$max, "min"))

factpal <- colorFactor("RdYlBu", iso@data$drive_times)

leaflet() %>%
  setView(mean(locations$lon), mean(locations$lat), zoom = 7) %>%
  addProviderTiles("CartoDB.Positron", group="Greyscale") %>% 
  addMarkers(lng = locations$lon, locations$lat) %>% 
  addPolygons(fill=TRUE, stroke=TRUE, color = "black",
              fillColor = ~factpal(iso@data$drive_times),
              weight=0.5, fillOpacity=0.2,
              data = iso, popup = iso@data$drive_times,
              group = "Drive Time") %>% 
  addLegend("bottomright", pal = factpal, values = iso@data$drive_time,   title = "Drive Time")

Which gives me the following map:

Full isochrone map

Which looks good until you zoom in and notice that the latitude and longitude I put into the code (represented by the marker) is not in the 0-10 minute drive isochrone; instead it is in the 10-20 minute drive isochrone.

Zoomed in isochrone map

Does anybody have any idea why the osrmIsochrone code appears to be using a different point for creating the isochrones?

1 Answer 1

5

I think it is using the right point but is generalising the polygons differently.

I tried comparing your isochrones up to 60 minutes:

iso_orig <- osrmIsochrone(loc = c(locations$lon, locations$lat), breaks = seq(from = 0,to = 60, by = 10))

with the same location but only the first three break points, giving 2 features (actually I think the zero is not useful here...):

iso_2 <- osrmIsochrone(loc = c(locations$lon, locations$lat), breaks = seq(from = 0,to = 20, by = 10))

Plotting these isochrones in black and then adding your isochrones in red and the start point looks like this:

enter image description here

in this case the start point is in the 0-10 area, and the outline is more detailed. It looks like the smallest red polygon has been simplified and the bit containing the start location has fallen out.

Looking at the help, the only thing that might affect this looks to be the res parameter, so lets up that to 40 and see what happens:

> iso_orig_40 <- osrmIsochrone(loc = c(locations$lon, locations$lat), breaks = seq(from = 0,to = 60, by = 10),res=40)
> plot(iso_2)
> plot(iso_orig_40,add=TRUE,border="red")

enter image description here

and you can see that the smallest red polygon is different (and in this case includes the dot) and is a better approximation to the black polygon areas.

My hypothesis that the engine uses a res x res grid over the entire region, and then polygonises that grid. If you have isochrones going out to 60 minutes then that's quite a big space and there's not a lot of that grid in the smaller polygons, and so the conversion to polygon is not good. Increasing res results in better polygon conversion at the expense - I guess - of increased computing time.

You could try doing each isochrone with a single call to osrmIsochrone and then each one would be computed using the full res x res grid, but that's at the expense of multiple calls to the API.

1
  • 2
    Thank you so much for such a detailed response! It looks like you figured out exactly what is going on, and that makes a ton of sense! I noticed in once experiment too that the 0-10 isochrone ended up looking like a few polygons near each other but not exactly connected, so your explanation makes a lot of sense for that as well. Thank you very much! Jan 17, 2020 at 21:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.