I’m an avid jogger. Some years back, I decided that it’s pretty boring to run the same section of the Burke Gilman trail over and over again. Instead, if I picked up where I left off each time, I could section run the entire 27 miles. Later, when I was training for my first marathon, I continued the section run idea and connected the dots from the Burke Gilman to Green Lake to Alki. Since then I’ve continued to jog in new places including the John Wayne Pioneer Trail from North Bend to the Columbia River.
Run map of all the places I’ve run. Zoomed out, it’s thick blurry lines representing the extents of each run. If you zoom in, you’ll see the detailed view of the places I’ve been.
Making the run map turned out to be an interesting programming exercise. Fitness watches (and before I had one of those, apps like RunKeeper) export the map as an xml (gpx or cvs) file. The first version of the run map was just a python script that read them all in and wrote out an html file with the points as a javascript array. This worked well for several months until browsers couldn’t load the file because it was too large.
The next version scanned the folder for files and opened each with AJAX calls. Even though all the polylines in google maps took a lot of memory, not having the data embedded in the source file made it work for many more months (maybe years). As I kept running, and logging longer and longer runs, the map got slower and slower and eventually ran out of memory.
Somewhere in there, the ISP I was hosting it on updated their security (possibly adding some for the first time) and it was no longer possible to scan the folder for the files, so I made an index.xml that contained the file names. This came in handy when moving to the current implementation. When I’m generating the index file, I also compute the bounds and extents of each run. That way once the index is loaded, the low-res version of the map can be drawn immediately without loading any of the individual xml files of the individual runs. Also, the bounds give the information of which runs are on-screen to be able to only load those individual runs that are visible in the current view.
It’s also now split out with a web worker for the file loading. The changes make it feel pretty good to pan around and zoom in and out.
Some day, I’ll add one of those “MyLocation” buttons and an indicator of when it’s loading to make it easier when out on a run to know if I’ve gone up a particular fork in a trail.
Source code is on GitHub
UPDATE 30 April 2019
Linking to http pages from Facebook doesn’t work at all. Https or go home. So I tried to add an SSL cert to the google cloud bucket that was serving the page. That’s harder than it should be, so I moved it to Firebase and registered rungordon.run.
Meanwhile, I made another version of the run map with just those runs that are part of the coast to border trek. With less data, it can load the high-detail versions without zooming in. Both are available at: