library(tidyverse)
library(lubridate)
library(rayshader)
library(raster)
library(sf)
library(mapview)
library(magick)
Rayshading the Big Sur Marathon
Visualizing marathon races
With marathons and other large gatherings canceled or delayed by the COVID-19 pandemic, I’ve been feeling extra nostalgic for past running experiences in some of my favorite places. At the top of the list is the Big Sur Marathon that runs along California State Route 1 from Big Sur Station to Carmel. The course starts near the southern edge of the Redwood forest, rises to the top of Hurricane Point overlooking the Pacific, crosses iconic Bixby Creek Bridge, and passes over numerous hills and turns before reaching the finish. Big Sur is a challenging spring marathon, and while I finished in just over 4 hours in 2019, it was definitely the most difficult race I’ve run. Having a live piano performance at Bixby helped though.
Like other runners, I tracked my progress with GPS, using the RunKeeper app on my phone. This project will use the GPS location data from RunKeeper and visualize the course using the rayshader
R package, which can provide a 3-dimensional view of a landscape or other surface. Tyler Morgan-Wall recently posted an excellent guide for combining elevation data with satellite imagery to create 3D renderings of landscapes. Examples from Sebastian Engel-Wolf, Simon Coulombe, and Francois Keck of using animation with rayshader also provided plenty of guidance and inspiration.
Data sources and prep
This project will need the GPS data from RunKeeper, satellite imagery data, and elevation data. Morgan-Wall’s post includes the step-by-step process for downloading the SRTM elevation data and imagery data from USGS. I won’t repeat those steps here, but I’ve pre-downloaded the data for the Big Sur region of California.
Let’s get to it and load the R packages.
First, let’s load the elevation data. I downloaded data for two bordering areas, so I’ll merge them together.
<- raster::raster(file.path(path_to_data, "N36W122.hgt"))
elevation1 <- raster::raster(file.path(path_to_data, "N36W123.hgt"))
elevation2
<- raster::merge(elevation1,elevation2)
bigsur_elevation plot(bigsur_elevation)
Next, let’s load the satellite data, which comes in three files that are separate layers for the image. After loading the layers, we’ll combine them and apply a color adjustment. It will need more refinement, but the Monterey peninsula is visible.
<- raster::raster(file.path(path_to_data, "LC08_L1TP_044035_20191026_20191030_01_T1_B4.TIF"))
bigsur_r <- raster::raster(file.path(path_to_data, "LC08_L1TP_044035_20191026_20191030_01_T1_B3.TIF"))
bigsur_g <- raster::raster(file.path(path_to_data, "LC08_L1TP_044035_20191026_20191030_01_T1_B2.TIF"))
bigsur_b
<- sqrt(raster::stack(bigsur_r, bigsur_g, bigsur_b))
bigsur_rbg_corrected ::plotRGB(bigsur_rbg_corrected) raster
Finally, let’s load the GPS data from RunKeeper, which comes as a GPX file. With a quick view using mapView
, we can see the tracked points from the GPS file are in the right locations.
<-
bigsur_gpx st_read(
file.path(path_to_data, "RK_gpx_2019-04-28_0643.gpx"),
layer = "track_points",
quiet = TRUE
%>%
) ::select(track_seg_point_id, ele, time, geometry)
dplyr
mapView(bigsur_gpx)