From the Travelogue:
A while back, two friends from Tulsa introduced me to a little BBC television program called Top Gear. Periodically, these three glorious Brits would be sent by “the Producers” (prah-DEU-suhz) on special adventures: buy used cars sight-unseen over the Internet for a pittance, then drive them over a long distance (meandering routes preferred) while being hilariously abusive to each other and competing to see who made the best purchase (by no measure in particular). I do not recall the quantity of grownup drinks required to believe recreating this enterprise would be wise, but, sufficiently imbibed, an idea emerged!
I was almost surprised by the enthusiasm generated among my friends and family at our upcoming lunacy. Everyone wanted to know how I’d be sharing our adventures. For that trip, back in 2015, I had a Tumblr blog for photos and text, and I’d include screenshots of static maps as we went along.
But we’ve been planning a second trip for the past six months, which has given me time to up my blogging game.
Under the Hood
This is perhaps a more complex amalgamation of services than it could have been, but I’ve tried to separate concerns as much as possible.
In 2015, I tracked our trip with a terrible pile of PHP scripts* created in great haste before we left. After the trip, I left the service running and continued to improve it. Over time, I’ve built it into a Silex application with MySQL for data storage and a set of API endpoints which exposes location history data and GeoJSON.
Location Tracker’s job: Record location updates from my phone (submitted every 30 minutes) and provide these data for the frontend to display our progress in real-time.
* Yes, all keys and credentials in this commit have since been invalidated.
The Backend app uses Google Maps’s API to “geocode” the longitude and latitude coordinates in the updates into useful data like city, state, street address, and more. Currently, I’m only using the city names, but the application stores the entire response serialized in the database in case I want to use more of it in future updates.
An example of a geocoded response as provided by the
GeocoderServiceProver for Silex:
Array ( [latitude] => 36.15685900 [longitude] => -95.99151600 [bounds] => Array ( [south] => 36.15685900 [west] => -95.99151600 [north] => 36.15685900 [east] => -95.99151600 ) [streetNumber] => 1 [streetName] => South Boston Avenue [cityDistrict] => [city] => Tulsa [zipcode] => 74103 [county] => Tulsa County [countyCode] => TULSA COUNTY [region] => Oklahoma [regionCode] => OK [country] => United States [countryCode] => US [timezone] => )
These data are mostly for my own use in the location tracker, but are used in one place on the blog:
Google Geocoder’s job: Provide the city names used in the frontend for “Where are they now?”.
So this location tracker has sensitive information: precisely where I’ve been every half hour over the past two years, accurate to within about 20 feet.
(That’s “What trail are you on?” precision.)
Also, I’d rather not have the real endpoint exposed to the public since the application’s authentication is currently quite simple and the server it runs on isn’t very powerful.
AWS API Gateway exposes a CORS-capable endpoint and accepts
GET requests which are passed to a Lambda function I wrote to fetch data from the backend application and anonymize it.
- Only the endpoints used by the blog are whitelisted: a list of trips, trip details including the actual route, and the latest location
OPTIONS(for CORS) requests are permitted
- If a response contains coordinate pairs in Austin or Tulsa, they are replaced with the State Capitol or the Center of the Universe, respectively.
Also, API Gateway can cache responses to reduce the load on my server while we’re actually traveling and site traffic will be marginally higher. This kicks me out of AWS’s Free Usage Tier, but I won’t be in a position to fix anything on the road, so I say it’s worth it.
Finally, S3 is used to store all the static assets (images, fonts, style, and scripts) for the frontend theme.
AWS’s jobs: Make sure the crazies can’t figure out where I sleep. Prevent overloading my backend application server. Serve static assets via an HTTPS-capable CDN.
Google’s Drive service offers a suite of applications from word processing to spreadsheeting. A little known application in that suite is “My Maps,” which allows users to add routes, points, geometric shapes, and other geographical data to maps and export it as KML. I use this to collect our route plans, accommodations, and points of interest we intend to visit.
My Maps’s job: Let me collect the route and POI data to be added to the map and export it to a standard format.
Mapbox allows rich map design options and their free tier is more than enough to support my small audience. Using Mapbox, I compile the customized base map as a “Style” which also includes overlays of our route and accommodations I imported from “My Maps” as a custom tileset. This way, all those layers are loaded as a single map.
Mapbox’s job: Design and provide the visual map for the frontend with route/POI data already imported.
My trusty Google Pixel, a generous Christmas gift from Four Kitchens, is ultimately the source of all of these data. A custom task for Tasker records my location every half hour, batches it for submission, and submits the batch when a connection is available.
I also use the Tumblr Android app to write the shorter posts and upload single images and videos.
My phone’s job: Passively record and submit location data, post content.
At its heart, the frontend is just a Tumblr blog. I picked Tumblr because it has a good mobile editing experience, an even better desktop editing experience, handles photos and video gracefully, and supports fully customized themes.
I partially rescind this recommendation. Tumblr’s Android application and desktop interface are both quite buggy, especially on slow internet connections we had in remote places. Despite usable connections for Instagram, Facebook, and other media-upload capable sites/applications, Tumblr uploads consistently failed. And the mobile app’s failure response is to indicate that it will try again “later” automatically, but at an unknown interval, once. A subsequent failure ends with an attempted-humorous but useless error message like, “Something annoying happened. Try again later.” There is no way to see, change, or clear the failure retry queue; the best way to force a retry is to make a blank text post which causes both to be attempted immediately, then delete the blank post.
Further, while the post date and time can be altered on the web, they can’t be changed on the mobile app, and delayed uploads on mobile will be timestamped for the submission time, not the capture/writing time, so matching up post times with location timestamps was inconsistent until I could get my laptop to wifi to fix them.
During the trip, I ditched Tumblr’s video service altogether for a superior experience with Vimeo. At least Tumblr handled Vimeo embeds pretty well.
That said, I haven’t found a better alternative yet, but I’ll be looking.
The frontend loads the Mapbox map, pulls the route and current location data from the AWS API proxy, and displays in the custom theme a chronological listing of all posts I’ve made: long-form text posts, individual photos with captions, photosets (galleries with a lightbox), quotes (because the funniest part of all this is the banter), and the occasional video (because some things have to be seen to be believed). Each post has a “Show on Map” link which re-centers the map view to where we were when I made the post.
Tumblr’s job: Tie all the pieces together into the frontend experience.
Ready to Roll
We’re about three weeks out from the trip. I’m excited to have this almost finished up, though I see lots of room for improvements if I find the free time. I love projects that tie multiple interests together, and I especially appreciate the opportunity to help people use the web to tell their stories. This project has hit all of those spots.
All that’s left is to buy an off-roader off Craigslist, drive it a thousand miles through the desert, and sell it off in Salt Lake. How hard can it be?
It worked out okay the first time. Follow along on the Travelogue.
(Yes, this is where my Favicon came from.)
We lived. ;-)