Every photograph is taken somewhere. With the advances in miniature GPS chips, equipping cameras with GPS capability, and implanting location data into the images should be a no-brainer. Several manufacturers have indeed come out with GPS enabled cameras. So , how do you use this new feature to georeference your photos in a FOSS GIS environment?
At work we recently purchased a Panasonic TZ-10 with an embedded GPS. I want the photos to pop open when I click on their location on a map. Picasa already does this on Googlemaps with photos that contain location data in their EXIF information header. But we want to implement this feature on our maps, with our data layers. And using our favorite open source GIS software. The toolkit I suggest includes QGIS together with the highly regarded ExifTool. Using this method we create a point shapefile of photograph locations. Then, with the “Actions” functionality built into QGIS we’ll call up an image display program to show the pictures at a mouse click.
(A new, experimental plugin called photo2shape is available from GIS-LAB to extract the photo locations from the exif data directly into a shapefile. However I couldn’t get it working, and others have reported bugs, as is expected in early versions. I’ll report back as the plugin matures)
To install ExifTool on linux, first download the installation tarball from the ExifTool web site. Unzip and untar the package. Then follow these straight-forward steps. For Windows users there’s a binary package ready to use. Unzip it into a directory such as C:\Program Files\Exiftool, and as per this explanation rename the executable exiftool(k).exe to exiftool.exe.
This perl based program has a rich list of command line options including selection of EXIF tags, and output formatting. We’ll demonstrate a few. On Windows, the exiftool executable won’t necessarily be in the PATH, so open a command window and change directory to “C:\Programs Files\ExifTool” (if that is where the exiftool.exe lives). Also you’ll use the backslash ‘\’ character as the Windows directory separator. Other than that the commands work the same on both platforms. First try running with the -l option to list all available EXIF tags in your photos:
micha@hayun-820:~$ exiftool -l /media/data/pix/ExifTool/P1000034.JPG | grep "GPS" .... GPS Satellites .... GPS Latitude GPS Longitude
So this image contains EXIF tags with GPS data. Now we’ll have a quick look at the data in these tags:
micha@hayun-820:~$ exiftool -GPSLongitude -GPSLatitude /media/data/pix/ExifTool/P1000034.JPG GPS Longitude : 35 deg 11' 9.27" E GPS Latitude : 30 deg 36' 51.73" N
We enter the tag name as -TagName using a dash, and no spaces in the name, for each tag, and exiftool outputs the information. Now check the -c option to format the output of the Lon/Lat coordinates.
micha@hayun-820:~$ exiftool -c "%.6f" -GPSLongitude -GPSLatitude /media/data/pix/ExifTool/P1000034.JPG GPS Longitude : 35.185908 E GPS Latitude : 30.614369 N
Formatting follows the conventions of C printf formatting syntax. We also want to extract the date/time of the photo and some exposure information. The date is formatted with the -d option, and follows the UNIX date formatting, so:
micha@hayun-820:~$ exiftool -c "%.6f" -d "%d/%m/%Y-%H:%M" -CreateDate -Aperture -ShutterSpeed -GPSLongitude -GPSLatitude /media/data/pix/ExifTool/P1000034.JPG Create Date : 31/10/2010-08:32 Aperture : 4.5 Shutter Speed : 1/500 GPS Longitude : 35.185908 E GPS Latitude : 30.614369 N
Finally we want to output the details in table form and extract from several photos at once. We will also need the photo filename and path for later use in defining the QGIS action. ExifTool has the -p option for this. This option can take either a list of the tag names, each preceeded by a ‘$’, or a filename which contains the same list of tag names. The way the tag names are listed in the file is the way they are output. For example, in order to create a CSV (Comma Separated Values) file, we create and use a file like:
micha@hayun-820:~$ cat /media/data/pix/ExifTool/exif_format.txt $Filename,$Directory,$CreateDate,$ShutterSpeed,$Aperture,$GPSLongitude ,$GPSLatitude ,$GPSSatellites
The tag names in the format file are commas-separated, so we get equivalent commas in the output. Now by handing off the above format filename to the -p option, here’s the result:
micha@hayun-820:~$ exiftool -c "%.6f" -d "%d/%m/%Y" -p "/media/data/pix/ExifTool/exif_format.txt" /media/data/pix/ExifTool/*.JPG P1000032.JPG,/media/data/pix/ExifTool,29/10/2010,1/250,3.9,35.301453 E ,30.806672 N ,4 P1000033.JPG,/media/data/pix/ExifTool,29/10/2010,1/200,4.0,35.301453 E ,30.806672 N ,4 P1000034.JPG,/media/data/pix/ExifTool,31/10/2010,1/500,4.5,35.185908 E ,30.614369 N ,4 3 image files read
We’re getting close… We need to dump this output into a “point_locations.csv” file, but only after entering the tag names as column headers (separated by commas) as the first line of this file. Then re-run the above command but redirect the output to the same point_locations.csv file:
micha@hayun-820:~$ echo "Filename,Path,Date,Shutter,Aperture,Longitude,Latitude,Satellites" >> point_locations.csv micha@hayun-820:~$ exiftool -c "%.6f" -d "%d/%m/%Y" -p "/media/data/pix/ExifTool/exif_format.txt" /media/data/pix/ExifTool/*.JPG >> point_locations.csv 3 image files read
Here’s the final CSV file:
micha@hayun-820:~$ cat point_locations.csv Filename,Path,Date,Shutter,Aperture,Longitude,Latitude,Satellites P1000032.JPG,/media/data/pix/ExifTool,29/10/2010,1/250,3.9,35.301453 E ,30.806672 N ,4 P1000033.JPG,/media/data/pix/ExifTool,29/10/2010,1/200,4.0,35.301453 E ,30.806672 N ,4 P1000034.JPG,/media/data/pix/ExifTool,31/10/2010,1/500,4.5,35.185908 E ,30.614369 N ,4
One more important chore. Exiftool gives the Lon/Lat coordinates with the N-E-S or W qualifier. That won’t work when importing into QGIS. The coordinates have to be pure numbers. So open the CSV file in your favorite editor, and do a search/replace to remove all instances of ‘ N ‘ or ‘ E ‘. Note that in the above formatting step I left a space after the $GPSLongitude and $GPSLatitude entries. This then leaves a space after the Lon and Lat values in the resulting CSV. Use this trick to make the search/replace easier. And, of course, if your photos are in the Southern hemisphere, or west of Greenwich, the value followed by an ‘S’ or ‘W’ must be made negative.
We next fire-up QGIS and start the Delimited Text plugin. Point it to your CSV file, check that it is parsed properly, and click OK to import the photo locations.
Once the photo locations are imported, open the layer’s Properties window and go to the Actions tab. Enter a name for the action such as “Display photo” and in the Action text box enter the program you want to run to display the photos. On linux systems running Gnome, just enter gthumb or eog (Eye of Gnome). Windows users can start the “Windows Picture and Fax Viewer” with the following command:
You might also have an alternate image viewer installed such as Irfanview. In that case the display command will be:
After the program name you’ll choose the attribute fields “Path” and “Filename” which hold the full path to each photo. Be sure to enter a slash ‘/’ as directory separator between the path and filename. Windows users will of course use the backslash. And another important note for Windows: You must add another ‘%’ character after the Path and Filename column headers. So the full “Action” on a Windows system will look like:
rundll32.exe C:\Windows\system32\shimgvw.dll,ImageView_Fullscreen %Path%\%Filename%
Save the action. Now using the QGIS information button, click on one of the photo points, and open the Action item at the start of the attribute list. Click on the “Display photo” action and the photo should open.