Tonight’s project: walk around the block and take some photos with my Nokia N70 while my GPSlim 236 Bluetooth GPS was logging my location every 5 seconds. Then use open source tools to take the time and location information from the GPS traces and merge it with the time information from the photos to automatically stamp the location of each photo into its EXIF data.
I fired up the GPSlim and started the nmea_info application on the phone to start logging my location. I headed out the front door of my office, along Fitzroy St. to Queen St., along Queen to Kent St., along Kent to University Ave., along University to Fitzroy St., and back along Fitzroy St. to the office. The entire trip took 8 minutes.
I ended up with a file on the N70 called nmea_gga_log.txt that I renamed WalkAroundBlock.txt. This is an NMEA-format file with a line for each GPS waypoint (“digital bread crumb”) on my path that looks like this:
Next, I used GPSBabel to convert this NMEA file to a GPX file — GPX being a common XML format for representing geographic data:
gpsbabel -i nmea,date=20060710 -o gpx \ -f WalkAroundBlock.txt \ -F WalkAroundBlock.gpx
I named this new file WalkAroundBlock.gpx and each waypoint in this file looks like this:
<trkpt lat="46.236196667" lon="-63.129941667"> <ele>24.600000</ele> <time>2006-07-10T22:32:49Z</time> <fix>3d</fix> <sat>7</sat> <hdop>1.500000</hdop> </trkpt>
Loading this track into GPS Visualizer and making a map of it, here’s what I get:
I made the map just to check and make sure that my GPS traces look something like the route I walked. So far, so good. Next, I use the fantastic gpsPhoto.pl Perl script to magically merge the GPX file’s location information into the photos by matching up the times of the photos:
perl gpsPhoto.pl \ --dir photos/ \ --gpsfile WalkAroundBlock.gpx --timeoffset 10800
Note that gpsPhoto.pl has some dependencies (they’re clearly indicated on the web page for the script) and I had to futz around for about an hour before running the script getting all the dependencies to build on my OS X machine, the big hold-up being expat, which I had to install with fink which needed updating itself before I could proceed.
One I had everything in place, however, everything went off without a hitch, and gpsPhoto.pl returned a series of successful matches:
photos/20060102824.jpg, 2006:07:10 19:32:20, timediff=29 Lat 46.236196667, Lon -63.129941667 - Bearing: 0 - Altitude: 25m
And so on. Once all was finished — it only took a few seconds — I was able to confirm that the location information had been burned into the JPEG files by opening them up in Graphic Converter and looking at the EXIF date (Window \| Show Information). Here’s what it looks like now:
With the location data burned into the photos, it was easy to whip up a quick Google Maps photo browser application to let me see the location of the photos on a map:
Note that once I saw the photos on the map, I realized that I hadn’t synced my camera phone’s clock to the GPS clock, meaning that things were out of sync by about 60 seconds; I corrected the problem by running gpsPhoto.pl again, and adding 60 seconds to the time correction:
perl gpsPhoto.pl \ --dir photos/ \ --gpsfile WalkAroundBlock.gpx --timeoffset 10860
Things are still a little off, partly because the timing still isn’t perfect, and partly because I’m running the GPS receiver without any sort of DGPS assistance, so the accuracy is not what it could be.