Several times recently I’ve needed to explain how I add gps information to my photos. I thought it would help to document it here. I’m not saying this is the best way to do things, but it seems to work reasonably well.

Update (9 jul 2008): I have updated the Python script linked to near the end of this article.

If your browser window isn’t wide enough to show the right side of the pictures, just click on the picture to see the whole thing.

The NaviGPS device.

Plotting points while taking photos. I carry around a GPS device (NaviGPS) that plots points at intervals you can choose. I usually opt for every 5 seconds. The device is really light, small and waterproof. Main problems:

  1. Finding something to carry it in. I can’t seem to find the armband Scytex describes, and though carrying it in my trouser pocket worked reasonably well, I think it was sub-optimal. I recently acquired a small thin bag that clips onto my backpack or camera bag.
  2. Buildings can block the signal. This was an issue recently in the narrow streets of Oviedo’s old town. But it’s usually fine, and even in Oviedo produced usable results.
  3. Although the plots are usually incredibly accurate, there are occasions where parts of the track seems slightly displaced from the route you can see on Google Earth. I don’t know whether this is because Google Earth is slightly incorrect or the GPS points are slightly off. (See how I deal with that below.)

I also try to remember to synchronise, as GMT, the data/time in my camera with the date/time in the GPS device before I set off (although you’ll read later that I have a way of dealing with this if I forget).

Converting points to tracks. When I get back to my computer, it takes about 10 seconds to upload the data from the GPS device to a folder using a USB cable. The resulting file has a .nmea extension and contains information about latitude, longitude, elevation, etc, and a timestamp for each point plotted. (Example.)

I use a small Python script I wrote to convert that to a .kml file that can be viewed on Google Earth or Google Maps. (The code is given below.) The script takes about one second to run. The result is a line that joins all the ‘dots’ together, and provides timestamp information and elevation data on the left of the screen for each 5-second plot that links to the the appropriate place on the map. (See the picture below.)

The program lets me add a positive or negative offset, in seconds, if I have forgotten to synch the camera and the gps device, and adjusts the times of the plots to match those on the photos.

See the example of this recent trip in Bhutan. The file at the end of that link is a particularly large file – 1.3Mb – since it contains annotations for 5-second plots over a period of around 12 hours. Usually my files are only a fraction of this size. (I often produce the track plot without the annotations. In this case, even this 12-hour file would only be about 248k.) Note: There is one long straight line in that plot – this was due to the GPS device being inadvertently turned off at one stage.

Adding geo data to my photos. After adding XMP data to my photos about location, title, etc, using Adobe CS2 Bridge, I also add latitude and longitude to the exif data using Picassa and Google Earth.

The beta version of Picassa allows you to add latitude and longitude to your photo’s exif data by visually locating a point on Google Earth.

Click to see the full picture.

Picture of the menu selection in Picassa.

You can assign geodata for batches of photos or individual photos. You just line up the target icon with the right place on the map and hit the Geotag button. (See the picture below, showing me about to line up a location with the target icon.)

In principle, to find the right place on the map, I click on the nearest timestamp to the left (see 092535 in the picture below, which was the time in GMT when I took the photo of the tree, bottom right) to identify the position, and then move the map until that position is below the target. In practice, I can usually remember and see where I was standing relative to a given landmark or street corner, etc, and I move that under the target. If the GE definition is not high for that area however, I use the timestamp on the photo and the plot trace on Google Earth.

Where there’s a discrepancy, I don’t know whether my gps plot or the Google Earth map is most correct, but I opt for the visual approach because when I use this data it is typically to show my location on Google Earth/Maps. So I try to sync to what I see (and cross my fingers that things won’t change when GE rephotographs that location).

If I can’t tell within a (very) few metres where I was standing, I don’t geotag my photo.

Click to see the full picture.

Picture of Google Earth just before I position the map for a particular photo and hit the Geotag button.

The one fly in the ointment here is that I can’t use Picassa to tag my RAW files in this way – which is a pain, because using Adobe CS I’m able to add all the other metadata I want. I’m hoping Picassa may do something about this soon, or (perhaps even better for me) that Adobe will add similar capabilities to Picassa for tagging photos from Adobe Bridge with Google Earth… For now, I just get by as best I can.

Uploading the geodata. When I upload a photo to Flickr or Panoramio, the exif geodata is read automatically and used to establish the location on their maps.

Click to see the full picture.

Picture of a photo on Flickr showing how it locates the place the photo was taken on Yahoo maps.

Using the geodata. Once I have the geodata in the photo’s metadata, I can use it in a number of ways.

I can extract it to label a photo, as in this example (click on ‘show detail’). This has advantages such as: (a) a reader can easily get at the data, eg. to cut and paste the coordinates into Google Earth or Google Maps to see where the photo was taken, (b) if the copy of the photo itself no longer contains the metadata (as in this case), the data is still available. (Note: the full-sized version of the photo linked from that page does contain the exif data.)

For my sets on Flickr, I also run some simple Python scripts to create a .kml file which shows the location of each photo on Google Earth or Google Maps. I just upload the .kml file to a server, and you can access the information from a simple HTML link. Try this example of photos taken at the Golconda Fort, Hyderabad, on either Google Earth or Google Maps. If you click on the icons you see on the map, you can see the view I had from that position.

Click to see the full picture.

A picture of a set of photos plotted on a map in Google Earth, showing how you can see a photo by clicking on an icon.

Python code.

This is the code I use to convert the .nmea data to an annotated .kml file. Before the script runs you are asked to input the name of the file to be converted and any offset needed (in seconds) to synchronise the camera time with the time in the gps device (this can be a positive or negative number or zero).

See the sample input (NMEA file) and sample output (KML file).

See the code (view the file or download and convert the extension to .py)