Skip to content

Instantly share code, notes, and snippets.

@ivabrunec
Last active July 18, 2022 22:06
Show Gist options
  • Save ivabrunec/87a6e78ccf6a6b3c8a7e12819890495e to your computer and use it in GitHub Desktop.
Save ivabrunec/87a6e78ccf6a6b3c8a7e12819890495e to your computer and use it in GitHub Desktop.
# Create a map of traces using Google Location History #
# get your google maps data:
# https://www.howtogeek.com/725241/how-to-download-your-google-maps-data/
library(dplyr) # data wrangling
library(lubridate) # date parsing
library(ggplot2) # plotting
library(jsonlite) # reading in json file
library(sf) # spatial
library(osmdata) # osm api
library(sfnetworks) # spatial
library(showtext) # fonts
# switch to current wd
setwd(dirname(rstudioapi::getActiveDocumentContext()$path))
# add font
font_add_google(name = "Abril Fatface", family = "abril")
showtext_auto()
# read in file
myHistory <- jsonlite::fromJSON("Takeout/Location History/Records.json", flatten=TRUE)
# data cleaning & transformations
# based on https://medium.com/geekculture/explore-your-activity-on-google-with-r-how-to-analyze-and-visualize-your-location-history-2ea8edabe733
# grab just locations
myData <- myHistory$locations
myData <- myData %>%
filter(activity!="NULL")
# clean up dates and lat/long
myData <- myData %>%
mutate(time = as_datetime(myData$timestamp),
date = date(time),
hour = paste(hour(time),minute(time),sep=":"),
week = isoweek(time),
month = paste(month(time)),
year = isoyear(time),
latitude = latitudeE7/1e7,
longitude= longitudeE7/1e7) %>%
select(-timestamp,-latitudeE7,-longitudeE7,-time)
### !! EDIT THESE DEPENDING ON YOUR LOCATION AND DATES !! ###
# grab everything before the end of April
philly_data <- filter(myData, date < '2022-04-28')
# add underlying osm map
bbx = c(-75.20, 39.92,
-75.13, 39.98)
# all roads for dataviz
roads_all <- bbx %>%
opq() %>%
add_osm_feature(key = 'highway') %>%
osmdata_sf()
# larger roads only to snap to network
# takes a second to run
highways <- bbx %>%
opq() %>%
add_osm_feature(
key = "highway",
value = c(
'road',
"motorway",
"trunk",
"primary",
"secondary",
"tertiary",
"motorway_link",
"trunk_link",
"primary_link",
"secondary_link",
"tertiary_link",
'unclassified'
)
) %>%
osmdata_sf()
# now, we want to link the points to the nearest osm segment
# build sf network
my_roads <- st_geometry(highways$osm_lines)
net = as_sfnetwork(my_roads, directed = FALSE)
# grab coordinates
philly_coords <- myData %>%
st_as_sf(coords = c('longitude', 'latitude'))
st_crs(philly_coords) = 4326
# snap points to their nearest node
nearest_nodes = st_nearest_feature(philly_coords, net)
snapped_pois = philly_coords %>%
st_set_geometry(st_geometry(net)[nearest_nodes])
# okay, now we want to filter the network by the points
filtered = net %>%
activate("edges") %>%
st_filter(snapped_pois$geometry)
# split geometry into lon and lat
snapped_pois <- snapped_pois %>%
dplyr::mutate(lon = sf::st_coordinates(.)[,1],
lat = sf::st_coordinates(.)[,2])
# plot
ggplot()+
geom_sf(data = roads_all$osm_lines, col = 'grey40', size = .4) +
geom_sf(data = st_as_sf(filtered, "edges"), col = "#f88379") +
#geom_point(data = snapped_pois, aes(x = lon, y = lat), size = .5, col = '#f88379') +
theme_void() +
theme(plot.background=element_rect(fill = 'grey20', color=NA),
panel.background = element_rect(fill = 'grey20', color=NA),
plot.margin = unit(c(t=.2,r=.2,b=1,l=.2), "cm"),
plot.caption = element_text(color = "#f88379", size = 70,
hjust = .65, vjust = .5, family = "abril"))+
labs(caption = 'Philly, 2022')
# save
ggsave('philly_map.png', dpi = 300, height = 7, width = 5)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment