Location-tracking Roadtrip Blog

Combining automatic location tracking, geocoding, route planning, map design, and a custom theme frontend on a Tumblr blog to bring friends and family along on one hell of a ride.
Update 2019-03: I’ve swapped out Tumblr for WordPress to build this site, and it has been rebranded as Route Not Found from travelogue.

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

Diagram of the application

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 admin view

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:

Where Are They Now?

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.

Like, really precise

(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.

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.

API Gateway Config

Finally, S3 is used to store all the static assets (images, fonts, style, and scripts) for the frontend theme.

S3 Storage Bucket Contents

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.

The “My Maps” map for the roadtrip

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.

The Mapbox composite in the editor

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.

Update 2017-06 and 2019-03:

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.

Tumblr Dashboard

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.

The site frontend

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?

Olympic National Park

It worked out okay the first time. Follow along on the Travelogue.

(Yes, this is where my Favicon came from.)

Update 2017-06:

We lived. ;-)

  <a
    href="/blog/2017/building-travelogue/grand-canyon.jpg"
    data-pswp-width="1200"
    data-pswp-height="800"
  >
    
    

    
    <picture>
      <source
        type="image/webp"
        sizes="(max-width: 680px) 100vw, (max-width: 975px) 680px, 960px"
        srcset="/blog/2017/building-travelogue/grand-canyon_hua76724629d924919eb7b6d368318b219_1048931_960x960_fit_q75_h2_box.webp 960w"
        />
      <img
        src="/blog/2017/building-travelogue/grand-canyon_hua76724629d924919eb7b6d368318b219_1048931_960x960_fit_q75_box.jpg"
        class="default shadow"
        alt="Grand Canyon"
        width="960"
        height="640"
        loading="lazy"
      />
    </picture>
  </a>