Start at the end
Public Transport predicted travel time from origin minus the predicted driving travel time
To show relative PT accesibility
Needs a lot more work!
Start at the end
Public Transport predicted travel time from origin minus the predicted driving travel time
To show relative PT accesibility
Contact
belinda.maher@gmail.com
(links to previous talk):
http://about.me/minga
@Surgisse
belindamaher
surgissant
I ❤️
Contact
belinda.maher@gmail.com
(links to previous talk):
http://about.me/minga
@Surgisse
belindamaher
surgissant
I ❤️
Contact
belinda.maher@gmail.com
(links to previous talk):
http://about.me/minga
@Surgisse
belindamaher
surgissant
I ❤️
https://transport.vic.gov.au/about/planning/transport-strategies-and-plans/
Science, Programming, Statistics & Operations Research
I can't show you what we're currently working on, but here's something from 50 years ago.
Still haven't build Doncaster Line!
Think about workers getting to the airport:
Think about workers getting to the airport:
Think about workers getting to the airport:
vs.
Image source: https://maps.openrouteservice.org
If driving is faster and more reliable than public
transport
for your trip, are you going to choose PT?
Modal choice using Google Maps
"If only we could get some data on this!"
If driving is faster and more reliable than public
transport
for your trip, are you going to choose PT?
Modal choice using Google Maps
"If only we could get some data on this!"
Dave Cooley's MelbURN talk which inspired this project:
http://demos.symbolix.com.au/GooglewayRMeetupPresentation.html
Melbourne Isochrone
PT
PV
O-D pair
Centroid
Shapefile
Mode
Mode Shift
Isochrones & Choropleths - next two slides
An isochrone is defined as "a line drawn on a map connecting points at which something occurs or arrives at the same time".
Source: Wikipedia
SA2 Census Journey to Work data - Loader (2014)
a type of thematic map in which areas are
shaded or patterned in proportion to a
statistical variable that represents an aggregate
summary of a geographic characteristic within
each area.Source - Wikipedia
Talk about trying VITM polygons
Excluding the River or areas with no residents
Curvature of the Earth
100 points with transport networks underneath -Polka Dot Map
MelbourneSPDF is a spatial polygons data frame of
Metropolitan Melbourne
library(magrittr)library(leaflet)library(sp)size <- 0.005hex_points <- spsample( MelbourneSPDF, type = "hexagonal", cellsize = size)length(hex_points)[1] 36639
MelbourneSPDF is a spatial polygons data frame of
Metropolitan Melbourne
library(magrittr)library(leaflet)library(sp)size <- 0.005hex_points <- spsample( MelbourneSPDF, type = "hexagonal", cellsize = size)length(hex_points)[1] 36639
MelbourneSPDF is a spatial polygons data frame of
Metropolitan Melbourne
library(magrittr)library(leaflet)library(sp)size <- 0.005hex_points <- spsample( MelbourneSPDF, type = "hexagonal", cellsize = size)#Want to create polygons around these points?hex_grid <- HexPoints2SpatialPolygons( hex_points, dx = size)
MelbourneSPDF is a spatial polygons data frame of
Metropolitan Melbourne
library(magrittr)library(leaflet)library(sp)size <- 0.005hex_points <- spsample( MelbourneSPDF, type = "hexagonal", cellsize = size)#Want to create polygons around these points?hex_grid <- HexPoints2SpatialPolygons( hex_points, dx = size)
#how do we map this in leaflet?#call leaflet (opens interactively in Viewer window)leaflet() %>% addTiles() %>% # or addTiles(url=tileURL)%>% addCircles(data=hex_points)
You don't want to run up hundreds of dollars of google API costs!
How to filter the huge number of points you've generated?
Initially I though this was a complex problem, but there's a simple solution:
This effectively fans out origin points from the destination until
you get to your API calls budget
avoids messing around with selecting spatial areas to include or exclude
#adds dist_km column to centroid_points#from https://gis.stackexchange.com/questions/233373/distance-between-coordinates-in-rlibrary(data.table)library(geosphere)setDT(centroid_points)[, dist_km := distGeo(matrix(c(lon, lat), ncol = 2), matrix(c(long=origin_centroid[[1]][2],lat=origin_centroid[[1]][1]), ncol = 2))/1000]#arrange centroid_points in order of distancecentroid_points<-arrange(centroid_points,dist_km)
Set up the API Key (boring!)
We'll be using the Distance Matrix API, which is limited to 100 OD pairs per call
So we need to chunk our code to send <=100 points per call
I did this with the split() function
#assign a tranche number to every pointcentroid_points$tranche<-factor( ceiling(as.numeric(rownames(centroid_points))/100) )#split the list into tranches of 100centroid_split<-split(centroid_points,centroid_points$tranche)#result: a list of data frames
if you want you can limit your API key so that it can only call Google Distance Matrix
library(purrr)#fixing the formattranches<-totalpoints/100#initiate originsorigins<-list()for(i in 1:tranches){ origins[[i]]<-map2( (centroid_split[[i]]$lat), (centroid_split[[i]]$lon), ~c(.x,.y) )}
APIcall<-function(tranche, origins, destinations, output){#calls to google_distance by mode transit <- google_distance(origins = origins[[tranche]], destinations=destinations, key = map_key, mode="transit", departure_time=depart ) transit$time<-("depart.at"=paste0(depart)) #(repeat for driving)
...
#encapsulate all output into a list chunked by tranche number output$transit[[tranche]] <- transit output$driving[[tranche]] <- drivingreturn(output)}
this is how I feel about nested lists:
(ARGHHHH!!!)
You could use a really ugly for loop
(this is definitely not what I did when I was in a hurry) ;)
Use the googleway accessor functions:
I would advise using functional programming
Links:
Symbolix Googleway Accessor Vignette blog
library(magrittr) is your friend!
Background Tiles
Adding Points Markers
Adding Polylines
(You can add Polygons too, and tooltips)
The default Leaflet basemap is OpenStreetMaps
library(leaflet)leaflet() %>% addTiles() %>% setView(lat = -37.82 , lng = 144.96, zoom = 13)
I like CartoDB much better - just add the tileURL 'http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png' into the addTiles()
library(leaflet)leaflet() %>% addTiles('http://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}.png') %>% setView(lat = -37.82 , lng = 144.96, zoom = 13)
More info on basemaps:
https://rstudio.github.io/leaflet/basemaps.html
More Carto Basemaps
https://carto.com/help/building-maps/basemap-list/
Can be found at:
https://www.ptv.vic.gov.au/footer/data-and-reporting/datasets/
Or download the whole lot in one go (more than you need)
https://discover.data.vic.gov.au/dataset/public-transport-a-collection-of-ptv-datasets
Of the many files, you might be interested in these:
Paths:
Train Corridor Centreline
Metro Tram Routes
Metro Bus Routes
Stops/Stations as shapefiles:
Metro Train Stations
Metro Tram Stops
Metro Bus Stops
You can also get all the stops easily out of GTFS text files if you don't want to deal with shapefiles (see my R Ladies talk)
#addPolylinesleafletmap%<>% addPolylines(data=metro_lines, weight=0.6, color="#0072CE")#addPolygonsleafletmap %<>% addPolygons(data=SA2polygons, color=~pal(as.numeric(SA2_5DIG16)), label=~paste(SA2_NAME16, SA2_5DIG16,sep=" - "), labelOptions = labelOptions(noHide = F), fillOpacity=0.5)
#where I have used this palette in leafletlibrary(RColorBrewer)pal <- colorNumeric( palette = "RdYlGn",reverse=TRUE, domain=as.numeric(outputmins$diff.mins))leafletmap%<>% addLegend("bottomright", data=outputmins, pal = pal, values = ~diff.mins, title = "Minutes Difference (PT-PV)", opacity = 1)
leafletmap%<>%addScaleBar(position = "bottomleft", options = scaleBarOptions(maxWidth = 100, metric = TRUE, imperial = FALSE, updateWhenIdle = TRUE))
Applications: Bus Planning
Lining up arrival not departure
More points, closer together and for all of Melbourne
Automating querying and storing for other destinations
Perceived reliability and number of changes
Plotting paths taken by these predicted trips
Better visualisation of the data (I'm not really a mapping person)
belinda.maher@gmail.com
http://about.me/minga
@Surgisse
belindamaher
surgissant
FIN
To avoid some of the frustrations of dealing with shapefiles:
(When you know where your shapefile is but not what it's called)
library(rgdal)files <- dir(filepath)shapefile <- grep("shp$", files, value=TRUE)# find the shapefile in the file list (looks for *.shp)shape <- readOGR(dsn=paste0(filepath,"\",shapefile), GDAL1_integer64_policy = TRUE, stringsAsFactors=FALSE)
If you don't specify a layer it will default to the first one
Needs a lot more work!
Start at the end
Public Transport predicted travel time from origin minus the predicted driving travel time
To show relative PT accesibility
Keyboard shortcuts
↑, ←, Pg Up, k | Go to previous slide |
↓, →, Pg Dn, Space, j | Go to next slide |
Home | Go to first slide |
End | Go to last slide |
Number + Return | Go to specific slide |
b / m / f | Toggle blackout / mirrored / fullscreen mode |
c | Clone slideshow |
p | Toggle presenter mode |
t | Restart the presentation timer |
?, h | Toggle this help |
Esc | Back to slideshow |