Geocoding Your Photos

I've been geocoding photos for a while and it's finally taking off in the mainstream. I have a few sets of photos that I've geocoded and show on maps. For example, the McGuffin Game (which shows thumbnails on a Google map) and biking to Santa Cruz (which I did offline onto static images, before there were any open mapping APIs). Other people have much slicker display systems, but for getting the coordinates into the images, the state of the art hasn't changed much.

My setup for showing the thumbnails on a map is still pretty clunky, but just sticking coordinates into a JPEG and using that to link to a map is much easier. Here's where I explain how I do it and give you tools to help you do it.

Overview

The basic idea is simple. I have a GPS periodically record my position and the time, and I take pictures using a digital camera, which puts a timestamp in the image file metadata. Later, on my computer, I correlate the two using the timestamps and figure out where I was at the time I took the picture. Then I use the Google Maps API to present it in a nice way.

Collecting the Data

  1. You need a GPS and a digital camera (or you'll need to do a ton of stuff by hand).
  2. Look at the time on the GPS and set your camera's time to match, as closely as you can.
  3. With the GPS turned on and recording a tracklog, take a bunch of pictures.
  4. If you can't set your camera's clock precisely to the second, take a picture of your GPS showing the current time.

Preparing the Tracklog

I use gpsbabel to get the tracklog from the GPS and store it in GPX format.

Geocoding the Photos

Fixing the Timestamps

If you took a picture of your GPS showing the time, you can compare the time shown in the photo to the timestamp embedded in the EXIF data to see how far off your camera's clock is. Then you can adjust all the photo timestamps so they match the GPS' clock. For example, this command would adjust the timestamps on a bunch of images forward by 1 hour 2 minutes and 3 seconds:

exiv2 -a 01:02:03 ad *.jpg

Everything Else

I now have wonderful scripts that geocode the photos and store the location data in the EXIF chunks of the JPEG files.

exiv2
You'll need a copy of exiv2 (not written by me). This can read and write the EXIF info in JPEG files, but it's a bit tricky to use.
geoexif.py
A nice wrapper around exiv for reading from and writing to a JPEG file's EXIF GPS data.
tracklog.py
This reads and understands GPX tracklog files and can do some processing on them.
geoassociate.py
Geocodes photos based on correlated timestamps, stores geographic data in the JPEGs. This depends on tracklog.py and geoexif.py.

To show thumbnails on a map, I used to generate an xml file that describes each photo (URL, coordinates, dimensions). Now that I have a way to encode the coordinates in the jpegs, I'd like to rewrite all the JavaScript map code to pull the data from there so I can just pass it a list of JPEG URLs. But until I do that, I don't have anything I'd consider reusable.

Displaying Everything

For all the real work, I use the Google Maps API or just a local search for the coordinates, depending on what I'm trying to do. This all happens in your web browser, so you can poke around in the HTML and Javascript to see how it works.