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.
Location Tracker Backend
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.
Google Maps Geocoder API
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?”.
Amazon Web Services
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 allowed: a list of trips, trip details including the actual route, and the latest location. Other endpoints are rejected, and latest location responses that don’t correspond to an active trip are dropped.
- Only
GET
andOPTIONS
(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 My Maps
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
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 Phone
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.
Tumblr
At its heart, the frontend is just a Tumblr WordPress blog. I
[originally] picked Tumblr because [I thought] it has a good mobile editing
experience, an even better desktop editing experience, handles photos and video
gracefully, and supports fully customized themes.
2017: I partially entirely 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 a 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.
2019: I’ve dusted off my old WordPress chops and moved the Travelogue over to a self-hosted WordPress install. I used to build WordPress sites almost exclusively at the agency from 2010-2013 and haven’t messed with it much since. It’s grown up a lot, and while it’s still rough around some edges, what you can build with very little effort is staggaring. I should write about the WordPress rebuild one day.
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. ;-)