Skip to content

Instantly share code, notes, and snippets.

@naamancampbell
Last active January 11, 2020 11:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save naamancampbell/356a4d59de09a613b34905be268a93ff to your computer and use it in GitHub Desktop.
Save naamancampbell/356a4d59de09a613b34905be268a93ff to your computer and use it in GitHub Desktop.
---
title: "Boy Swallows Universe - Routes"
author: "Naaman Campbell"
date: "11 January 2020"
output:
html_document:
code_folding: hide
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, warning = FALSE)
library(googleway)
library(knitr)
library(rmarkdown)
library(DT)
load(".RData")
```
# Routes
## Overview
<img alt="Boy Swallows Universe cover" src="publish/boy-swallows-universe.jpg" style="height: 200px; float: left; padding-right: 10px" />
Boy Swallows Universe is a crime fiction novel by Trent Dalton based in the suburbs around Brisbane, Queensland, Australia. The story takes readers for a detailed guided tour of Brisbane's suburbs including Darra, Bracken Ridge, The Gap and beyond.
The routes and address data below present suggested ways of exploring the locations detailed throughout Boy Swallows Universe. Some addresses are a best-effort guess at the main _fictional_ addresses in the book.
Routes have been generated using a trial account with [Routific](https://routific.com/). Full details of the mapping process can be found in the Technical section.
<br /><br />
## Single Route
### Overview
The **Single Route** was generated by optimising all Brisbane-based locations as one continuous itinerary. The purpose is to provide an ordered trip across all locations spanning multiple days.
### Map
```{r single_map}
single_map <- google_map(key = apikey) %>%
add_polylines(data = pls_df, polyline = "polylines")
htmltools::tagList(single_map)
```
### Data
```{r single_map_table}
datatable(df, options = list(
pageLength = 5,
columnDefs = list(list(visible = FALSE, targets = c(4, 5, 6, 7, 8, 9)))
))
```
[Single Route CSV data file](http://www.sharecsv.com/s/b9de4fb84d2f7baea7aed6006ccaee84/BSU%20-%20Routific%20-%20Single%20Route.csv "CTRL+click to open")
## Multi-Day Routes
### Overview
The **Multi-Day Routes** were generated by reorganising all Brisbane-based locations into a series of routes that could be completed within one day. The purpose is to provide a 7-day itinerary across all locations.
All **Multi-Day Routes** start and finish at the Brisbane General Post Office.
### Data
[Multi-Day Route CSV data file](http://www.sharecsv.com/s/0ff68c146d7879f6dd69a89aa58ca0ce/BSU%20-%20Routific%20-%207%20Days.csv "CTRL+click to open")
```{r day_maps}
day_map_counter <- 0
day_maps <- lapply(day_polylines, function(x) {
day_map_counter <<- day_map_counter + 1
day_pls_df <- data.frame(polylines = unlist(x), stringsAsFactors = F)
day_map <- google_map(key = apikey) %>%
add_polylines(data = day_pls_df, polyline = "polylines")
day_map <- htmlwidgets::prependContent(
day_map, htmltools::tags$h3(sprintf('Day %s Route', day_map_counter)))
day_map <- htmlwidgets::appendContent(day_map, htmltools::tags$h3('Data'))
day_map <- htmlwidgets::appendContent(
day_map, datatable(day_routes[[day_map_counter]], options = list(
pageLength = 5,
columnDefs = list(list(visible = FALSE, targets = c(1, 5, 6, 7, 8, 9, 10)))
)))
day_map
})
htmltools::tagList(day_maps)
```
## Surrounds Route
### Overview
The **Surrounds Route** was generated by optimising all non-Brisbane-based locations as one continuous itinerary. The purpose is to provide an ordered trip across all locations spanning multiple days.
### Map
```{r surrounds_map}
surrounds_map <- google_map(key = apikey) %>%
add_polylines(data = surrounds_pls_df, polyline = "polylines")
htmltools::tagList(surrounds_map)
```
### Data
[Brisbane Surrounds Route CSV data file](http://www.sharecsv.com/s/aa5ce9e08bf623bc86e789e9b9e2129a/BSU%20-%20Routific%20-%20Surrounds.csv "CTRL+click to open")
# Technical
## Source Data
All addresses were compiled, in reading order, into BSU - Locations.csv and BSU - Locations - Surrounds.csv. South East Queensland locations outside the Brisbane/Ipswich/Moreton Bay/Logan localities were separated out into the separate Surrounds CSV file.
### Data
* [BSU - Brisbane Locations CSV data file](http://www.sharecsv.com/s/490d9f1c715438d5ee7e017bf5c99355/BSU%20-%20Locations.csv "CTRL+click to open")
* [BSU - Brisbane Surrounds Locations CSV data file](http://www.sharecsv.com/s/9a138d1a17b999aad3aa506080e9ea45/BSU%20-%20Locations%20-%20Surrounds.csv "CTRL+click to open")
## Routific Routes
Routes were generated by uploading the Source Data CSV files to [Routific](https://routific.com/). Routific generated routes processed hundreds of locations to provide optimised routes starting from the Brisbane General Post Office.
The routes were exported into CSV files (available after each map above) containing latitude and longitude pairs.
## Route Maps
The latitude and longitude pairs were processed using R data frames and displayed using the [googleway](https://symbolixau.github.io/googleway/) package. The tables are displayed with the [DT](https://rstudio.github.io/DT/) package and rendered using [R Markdown](https://rmarkdown.rstudio.com/).
### Single Route / Surrounds Route
```{.R}
library(googleway)
library(knitr)
library(rmarkdown)
library(DT)
load(".RData")
locations <- read.csv('C:\\Users\\Naaman\\Documents\\Code\\BSU\\data\\BSU - Routific - Single Route.csv')
df <- data.frame(locations)
polylines <- lapply(2:nrow(df)-1, function(x) {
route <- google_directions(origin = unlist(df[x, 8:9]),
destination = unlist(df[x+1, 8:9]),
key = apikey,
mode = "driving",
simplify = TRUE)
route$routes$overview_polyline$points
})
pls_df <- data.frame(polylines = unlist(polylines), stringsAsFactors = F)
single_map <- google_map(key = apikey) %>%
add_polylines(data = pls_df, polyline = "polylines")
htmltools::tagList(single_map)
```
#### Data Import
The Routific-generated CSV file was imported and loaded as an R Data Frame.
#### Polylines
Polylines determining the route outlines are drawn using the `google_directions` function from the Googleway R package. The `lapply` function iterates through the route data frame and returns a polyline between the current row and the next row. Columns 8 & 9 represent the Latitude and Longitude columns.
#### Generate Map with Route
The list of polylines is converted into a data frame and passed to the `google_map`/`add_polylines` Googleway functions. The map is then displayed using the `htmltools::tagList` function to match the same formatting used for the Multi-Day Routes.
### Multi-Day Routes
```{.R}
library(googleway)
library(knitr)
library(rmarkdown)
library(DT)
load(".RData")
locations_7days <- read.csv('C:\\Users\\Naaman\\Documents\\Code\\BSU\\data\\BSU - Routific - 7 Days.csv')
day_routes <- split(
locations_7days,
cumsum(locations_7days[,"Stop.Number"] == "0" & !is.na(locations_7days[,"Stop.Number"]))
)
day_polylines <- sapply(day_routes, function(y) {
y <- subset(y, Visit.Name != "Break")
lapply(2:nrow(y)-1, function(x) {
day_route <- google_directions(origin = unlist(y[x, 9:10]),
destination = unlist(y[x+1, 9:10]),
key = apikey,
mode = "driving",
simplify = TRUE)
day_route$routes$overview_polyline$points
})
})
day_pls_df <- data.frame(polylines = unlist(day_polylines[[1]]), stringsAsFactors = F)
day_map_counter <- 0
day_maps <- lapply(day_polylines, function(x) {
day_map_counter <<- day_map_counter + 1
day_pls_df <- data.frame(polylines = unlist(x), stringsAsFactors = F)
day_map <- google_map(key = apikey) %>%
add_polylines(data = day_pls_df, polyline = "polylines")
day_map <- htmlwidgets::prependContent(
day_map, htmltools::tags$h3(sprintf('Day %s Route', day_map_counter)))
day_map <- htmlwidgets::appendContent(day_map, htmltools::tags$h3('Data'))
day_map <- htmlwidgets::appendContent(
day_map, datatable(day_routes[[day_map_counter]], options = list(
pageLength = 5,
columnDefs = list(list(visible = FALSE, targets = c(1, 5, 6, 7, 8, 9, 10)))
)))
day_map
})
htmltools::tagList(day_maps)
```
#### Data Import
The Routific-generated CSV file was imported and split into multiple data frames based on zeroes in the Stop.Number column. The cumsum() splitting technique is credited to the following Stack Overflow post: https://stackoverflow.com/a/11402170/8751739.
#### Polylines
Each day's list of routes have "Break" lines removed before building polylines similar to the Single Route maps. Columns 9 & 10 represent the Latitude and Longitude columns in the Multi-Day data frames.
#### Generate Map with Route
The list of polylines is converted into a data frame and passed to the `google_map`/`add_polylines` Googleway functions. The Multi-Day maps are generated as a continuous block of R HTMLWidgets with accompanying DT data tables. To assist with formatting, `prependContent` and `appendContent` from `htmlwidgets` are used for placing titles and data tables before and after maps. The collection of maps and tables are then displayed using the `htmltools::tagList`.
## Markdown Source
R Markdown source for this page is available as a [GitHub Gist](https://gist.github.com/naamancampbell/356a4d59de09a613b34905be268a93ff "CTRL+click to open").
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment