Locating your photos on Google Maps
January 27, 2012 at 9:21 AM by Dr. Drang
Back in October I wrote a little script that added GPS location information to photos. My idea was to be able to take one photo with my iPhone, which would capture the location in its EXIF metadata, and use the script to transfer that information to all the photos I took with my regular camera at that same location. It works well, and I’ve been using it ever since, but once I had a bunch of photos with location info in them, I needed a tool that would do the converse: show me where they were taken. It turned out to be very easy to write.
The October program is called coordinate
, and I use it like this:
coordinate -g iphone-photo.jpg IMG*
This reads the GPS metadata from the iphone-photo.jpg
file and writes it to all the files that start with IMG
. The new program is called map
, and when I call it,
map photo.jpg
it reads the GPS info from the image file and opens Google Maps in my browser with a marker at the photo’s location.
Here’s the code for map
:
python:
1: #!/usr/bin/python
2:
3: import pyexiv2
4: import sys
5: import subprocess
6:
7: try:
8: # Open the photo file.
9: photo = sys.argv[1]
10: md = pyexiv2.ImageMetadata(photo)
11: md.read()
12:
13: # Read the GPS info.
14: latref = md['Exif.GPSInfo.GPSLatitudeRef'].value
15: lat = md['Exif.GPSInfo.GPSLatitude'].value
16: lonref = md['Exif.GPSInfo.GPSLongitudeRef'].value
17: lon = md['Exif.GPSInfo.GPSLongitude'].value
18:
19: except:
20: print "No GPS info in file %s" % photo
21: sys.exit()
22:
23: # Convert the latitude and longitude to signed floating point values.
24: latitude = float(lat[0]) + float(lat[1])/60 + float(lat[2])/3600
25: longitude = float(lon[0]) + float(lon[1])/60 + float(lon[2])/3600
26: if latref == 'S': latitude = -latitude
27: if lonref == 'W': longitude = -longitude
28:
29: # Construct the Google Maps query and open it.
30: query = "http://maps.google.com/maps?q=loc:%.6f,%.6f" % (latitude, longitude)
31: subprocess.call(['open', query])
It uses the standard sys
and subprocess
libraries and the distinctly non-standard pyexiv2
library. Installing pyexiv2
isn’t the hardest thing in the world, but it takes more than a simple pip pyexiv2
. I have a writeup on how to do it via Homebrew if you’re interested.
The script is easy to read, I think. Lines 9-17 get the name of the file from the command line, open it, and extract the GPS information. If there’s a problem in any of those steps, an exception is raised, and Lines 20-21 print an error message and quit.
Because the latitude and longitude are returned in an odd format (a list of three Fractions, one each for degrees, minutes, and seconds), Lines 24-27 are needed to put them in a format we can use to query Google Maps. The query is then constructed in Line 30, and Line 31 sends it to OS X’s wonderfully useful open
command to be opened in the default browser. The Google Maps API automatically drops a marker at the location and centers the map around the marker.
I could extend the query with more parameters to set the zoom level, force the display to satellite, map, or street view, and so on, but I prefer to stick with the defaults.
There are some obvious improvements I could make:
- Add an option to use Bing instead of Google Maps. With aerial photos, Bing’s oblique bird’s eye view is often more useful than Google’s top view. I haven’t looked yet, but I assume Bing can be queried through the URL just like Google Maps can.
- Rewrite it for a library that’s easier to install than
pyexiv2
. This wouldn’t affect me, but would make it easier for others to use. - Turn it into a Service. This is a trivial change that would produce a big improvement in usability. With a Service, I could just right-click on an image in the Finder and get the location by choosing an item from the popup menu.
If you’re wondering why I don’t just use iPhoto’s built-in mapping tools, it’s because I don’t use iPhoto. I find it very clunky and slow, and its organization system doesn’t work for the photos I take for my job (which is most of my photos). The map
script gives me a quick way to check the location of any photo, regardless of where it’s stored on my computer.