Linfiniti Geo Blog

GIS for Open Source People

Browsing Posts published in January, 2010

Since I got a crackberry cellphone that geotags images when I take them using its built in GPS, I have become a photo snapping lunatic. Of course one’s lunacy needs some way to manifest itself using FOSSGIS so I am going to decribe here a workflow to enable you to enjoy the thrills of geotagged imagery in QGIS even if you aren’t the proud owner of a completely proprietary crackberry phone! The process I describe below will allow you to geotag a directory full of images using a gpx track that you collect using your gps when you are out in the field. If your camera / phonecam already geotags your images, you can do step 1 and then skip straight down to step 10 below!

Step 1: Install dependencies:

sudo apt-get install gpscorrelate exiv2 python-pyexiv2

Step 2: Clean up your gpx file.

Be careful of using the QGIS editing tools to cut away any ropey looking or unneeded features – QGIS will delete the vertex attributes in the track! Rather use a text editor (like VIM!).

Step 3: Clean any existing geotags from the images:

gpscorrelate -r *.jpg;

Step 4: Find the timestamp of your first image:

exiv2 IMG_0594.jpg | grep timestamp

Image timestamp : 2009:07:31 13:02:53 IMG_0594.jpg

Step 5: Find the timestamp of the first trkpnt in the gpx file that matches the position where the photo was taken.


Step 6: Compute the time offset betweenn your camera and your gps

13 02 53 <-- photo
10 58 29 <-- gpx
 2  4 24 <-- difference

+ 2:00 hours gmt <-- timezone offset
-264 photo offset <-- difference (4min 24sec) in seconds, negative to show gps is behind the camera

Another example:

Here was a point at which we knew we had taken a picture (and we know the filename of the picture):


  685.07
  
  ACTIVE LOG
  22:10 11-Jan-10
  eTrex Venture
   0
   0

And then we got the exiv2 dump for the image:

File name       : IMG_2709.jpg
File size       : 960453 Bytes
MIME type       : image/jpeg
Image size      : 2816 x 1880
Camera make     : Canon
Camera model    : Canon EOS 1000D
Image timestamp : 2009:11:08 08:55:14
Image number    :
Exposure time   : 1/250 s
Aperture        : F8
Exposure bias   : 0 EV
Flash           : No, compulsory
Flash bias      : 0 EV
Focal length    : 70.0 mm
Subject distance: 0
ISO speed       : 100
Exposure mode   : Landscape mode
Metering mode   : Multi-segment
Macro mode      : Off
Image quality   : Normal
Exif Resolution : 2816 x 1880
White balance   : Auto
Thumbnail       : image/jpeg, 7605 Bytes
Copyright       :
Exif comment    :

From that we can work out something like this:

08 55 14 <-- photo
06 49 54 <-- gpx
 2 05 20 <-- difference
 +2hrs   <-- gmt offset
  320s   <-- second offset

Step 7: GeoTag your images using gpscorrelate:

For the first example:

gpscorrelate --timeadd +2:00 -g /tmp/knp_gpx_tim_interp.gpx --degmins -O -264 -m 1 *.jpg

Sometimes you need to make some manual adjustments to get the timestamps just right. For the images in our second example we ended up using:

gpscorrelate --timeadd +2:00 -g ../../KZN_tim.gpx --degmins -O -348 -m 30 *.jpg

Step 8: Exiv2 Image GeoTag display:

This is just to show what is going on internally - you can use the -pa option to exiv2 to see the geotags that have now been embedded in the images e.g.:

exiv2 -pa IMG_0700.jpg

produces output which includes something like this:

Exif.Image.GPSTag                            Long        1  8984
Exif.GPSInfo.GPSVersionID                    Byte        4  2.0.0.0
Exif.GPSInfo.GPSLatitudeRef                  Ascii       2  South
Exif.GPSInfo.GPSLatitude                     Rational    3  25deg 4.26000'
Exif.GPSInfo.GPSLongitudeRef                 Ascii       2  East
Exif.GPSInfo.GPSLongitude                    Rational    3  31deg 12.74000'
Exif.GPSInfo.GPSAltitudeRef                  Byte        1  Above sea level
Exif.GPSInfo.GPSAltitude                     Rational    1  675.5 m
Exif.GPSInfo.GPSTimeStamp                    SRational   3  13:25:59
Exif.GPSInfo.GPSMapDatum                     Ascii       7  WGS-84
Exif.GPSInfo.GPSDateStamp                    Ascii      11  2009:07:31

Step 9: Bonus material

gpscorrelate includes an interpolation option (enabled by default) that will derive a relative position between two vertices based on the timestamps. You can also use gpsbabel to interpolate extra vertices into your gpx file. For example I put in a vertex for every 1 second interval into the gpx file:

gpsbabel -i gpx -f knp_gpx_tim.gpx -x interpolate,time=1 -o gpx -F knp_gpx_tim_interp.gpx

Step 10: Loading in QGIS

GeoTagged image browsing with evis in QGIS

I have written a simple plugin which will create a shapefile from a directory full of geotagged images. You need to have exiv2 and python bindings for exiv2 in order for it to work, and the geotags must currently be written in degrees / decimal minutes format (which is achieved by using the --degmins option in the examples above). The plugin can be downloaded here. Point the plugin at your directory of geotagged images (it will recurse nested directories too) and afterwards a shapefile will appear in your map view. You can then query the image locations using the EVIS query tool (the EVIS plugin is included by default with QGIS).

You may also want to check out the Easy GeoTagger Project for manual options for embedding geotags into images. EasyGT also includes a vector driver which will treat a directory of geotagged images as vector layer in QGIS.

By the time a release of QGIS makes it out the door, most of us developers have long since forgotten about it and taken to the green fields of being able to add features again in QGIS trunk (i.e. ‘the fun place’). There is however a kind of sigh of relief to have made another milestone in the project and to have reduced the delta between what users want in a desktop GIS and what we provide. This (1.4) release announcement resulted in a bit of a mob rush to the QGIS website which caused quite a bit of downtime for the site over the last 24 hours. Thankfully Chris Schmidt and Frank Warmerdam (and probably others) were on hand to give the server the needed poke with a pointy stick to get it to behave better.

I decided to host the QGIS standalone installer exe on linfiniti.com for this release in order to try to get a better idea of download stats. Despite the server outages (meaning people didn’t have the link to download QGIS off my server) we have done around 900 downloads in the 24 hour period since the announcement. Considering that many people will share a download amongst friends and colleagues, especially here in South Africa where bandwidth is limited, and that there are numerous types of QGIS packages which aren’t tracked, 900 downloads probably means many times that actually installed onto people’s desktops.

QGIS 1.5 should be the final release before we start breaking API compatibility to make way for the 2.0 release. Breaking API compatibility lets use get rid of cruft from the code base and refactor the way we have designed QGIS without the overhead of having to support a large number of existing plugins and custom apps based on QGIS. I am looking forward to the rest of this year and all the new QGIS goodies the developer team will bring to the table!

I just sent out the official release announcement for QGIS 1.4 ‘Enceladus’….lets hope everyone loves it! The QGIS team has done a brilliant job for this one and I can’t wait for 1.5 because things are only going to get better! Read the QGIS Blog for details.

I put the standalone windows installer on my own server this time so I can track downloads – it will be interesting to see just how many people grab it….I’ll post some stats here later if there is anything worth reporting…

Marco Hugentobler and I have been working on integrating C++ based GPS integration into QGIS core.

New functionality

There are two parts:

- a gps background process implemented by Marco that communicates with a GPS and extracts nmea strings and then propogates them to any listing classes
- a user interface, implemented by myself, as a dock panel that shows position, signal strength bar chart, satellite polar chart, options

Similar to Martin Dobias’s GPS project, the GPS ui can be used to capture features (and attributes using the normal attribute dialog mechanism). The ui part uses Qwt for the charting functions.

How is it used?

- Add any reference layers to your project (e.g. satellite imagery backdrop)
- Create or add zero or more vector layers (lines, points, polygons) and enable editing
- Connect the GPS via a serial port (our test systems use serial to usb adaptors)
- Tick the auto-add vertices box in the options pane for easy use
- Now get on the train / bus / car :-)

As you drive along, focus one of your vector layers, and click the Add feature button.

If it’s a point layer a new point will be added, the add attribute dialog will appear and the track will not be destroyed.
If it’s a line layer (should work with poly too, I didn’t test yet), the add dialog will appear and after closing it the feature is added to your dataset and the track will be destroyed – ready to start creating the next feature.

For more control of the vertices assignment you can disable auto-add vertices and click the add vertex button when you want a vertex. Here is what the main panel looks like with auto-add vertices disabled.

The main display after your device is connected,

The Add Vertex button hides when auto add vertex check box is enabled. The add vertex and add feature buttons grow to use all available vertical space to make them easier targets to hit when trying to operate the laptop in a moving vehicle.

The track marker rubber band colour can be specified making it easier to see (e.g. on dark reference maps you can set the track marker to a light colour). For similar reasons, the rubber band width can be specified.

The reset feature button next to the Add feature button is there so that you can discard collected track data if you want to start your feature from your current location rather than your last saved feature’s end.

Other features

The tool can show a simple histogram showing signal strength:

Signal strength graph

It can also show a polar chart showing relative satellite positions:

Satellite position graph

An options panel allows you to specify your device port and various other choices. The map can be panned to be always centered on the GPS position, or recenter when the GPS cursor will leave the current view extents (so minimising refreshing), or never following the GPS. This panel is also where you specify the track width and colour.

GPS capture tool options

When you click the Add feature button, the normal attribute dialog mechanism is invoked allowing you to capture attribute data for your feature. Here is a screen shot showing point capture.

Capturing  a point feature.

In the field

Here is a pic of my in car setup while testing the software:

In car navigation

Note that the dog is still learning to operate the laptop so at the moment I keep her responsible for looking out the window for points of interest.