RouteWise - Bike Ride Companion
Background
Earlier this year, my family convinced me to join the Medio ride as part of the RBC Gran Fondo Whistler. It’s a 55km road bike ride with 835m of elevation gain.
I would consider myself a casual road biker, so while I was not terribly worried about my overall fitness to complete the ride, it would be the biggest ride I’ve done in many years, and I had never completed that route.
Question
I began to wonder if there was some product that I could find to help me answer questions like:
- How much distance do I have left?
- How much longer is this climb?
- How steep is the next climb?
Solutions
I searched and found that many Garmin dedicated bike computers have a feature that fits exactly these use cases, ClimbPro.
As I found myself contemplating buying another $500+ device with a screen and a GPS, I started to wonder if I could use the existing screen & GPS device that I carry with me everywhere already.
I don’t do many rides like this, so if I could get a similar display from my iPhone, that would eliminate my need to purchase another device that would spend most of it’s time gathering dust.
RideWithGPS is a popular platform for many riders, which has this functionality, but requires a subscription. Being a software developer, of course I decided rather than pay the $10/month subscription I should spend too much some time trying to build my own.
Product Design
The functionality that I thought I’d need seemed fairly straightforward:
- Current speed (direct from the GPS)
- Elapsed/current time (easy timer and clock access)
- Elapsed distance (log GPS positions and calculate line length)
- Show a map of current position and the course
- Show an elevation profile, with current position identified, and indicators for hill grade
I’ve been working on a few other mapping related projects recently, so the position and mapping features seemed like they should be easy enough and so it was only the elevation profile that held some unknowns for me.
Technology Design
I started by considering my various technology options:
Technology | Benefits | Challenges |
---|---|---|
Native Mobile App (ReactNative) | ✅ Easy access to GPS, screen wake lock, and orientation locking | ⚠️ No easy charting options ⚠️ Difficult distribution |
Hybrid Mobile App (Cordova) | ✅ Easy access to hardware (as above) | ⚠️ No easy charting options ⚠️ Difficult distribtution |
Web App | ✅ Straightforward deployment/distribution ✅ Good charting and mapping tools | ⚠️ Can’t lock rotation on iOS |
It was easy to discard Native Mobile as there was no compelling advantage, and both Native and Hybrid mobile would require more effort for distribution. I decided I could deal with having to perhaps occasionally tip my phone in order to get it in the desired orientation, in order to have the simplicity and ecosystem of making it a native web application.
Usage
The first step to prepare for a ride is to acquire the data needed for the route. Using many popular web apps, you can generate a TCX file. The file contains XML data representing location points along the route (longitude, latitude, and elevation). Loading that file into the web app we can display the route and elevation profile. All of this processing happens on the device, so it’s fast and entirely private. While loading the data we can calculate the grade of each point by looking at the surrounding points, and then use that data to shade the area under the elevation profile to indicate the grade of that point.
Next Steps
I refined the app over the weeks leading up to the event, polishing rough edges and tweaking to make it was comfortable and useful as possible. It was a great help for the big ride, and I’ve continued to use it for most rides since.
The free rotation has started to become a bit irritating, so I’m starting to consider moving it to a Cordova app so that I can lock the rotation.
There are a handful of little bugs that are minor irritations that I might try to crack open (zooming in on the elevation profile sometimes makes it impossible to zoom back out all the way, loop/overlapping routes confuse the nearest-point calculation).
The app is live and public, so if you want to give it a try head over to RouteWise and upload a TCX file. I’m planning to publish the source code but want to tidy it up a bit first.
Technology of Note
- xml2js for parsing the data from the TCX files
- idb for managing data persistence using IndexedDb
- Chart.js to render the elevation profile
- Turf.js for calculating nearest point on a line, distance of a line
- MapLibre to render a map of the current location and route
The app is a vanilla HTML/JS app styled with TailwindCSS and processed with Vite.