Geotagging on linux with gps visualizer and gpsPhoto
Is this for you?
This page is geared at people who like to host and run their own pages. It will be useful to you if you at least have your own web page with photos, even better if you host a picture gallery, and perfect if you happen to use Rig, Ralf's image gallery (sf.net link if main site is unreachable).
If you aren't comfortable hand editing html, editing a perl script to change paths in variables, or applying a unified diff patch, this page isn't for you. If you don't mind giving control of your data to a third party in exchange for a fully integrated service, you will probably like Everytrail, which takes your pictures and GPS track and can display a few pictures for you. The downside however is that it's not very configurable, and you cannot easily include their stuff with your web pages in any way you'd like, and you of course also rely on them remaining around and free.
Now, if you are the do it yourself kind, and like to tweak/configure and get exactly the result you were hoping for, read on...
Quick reminder steps for me
- My bookmark link for direct form access is this link.
- Make sure the input gdb GPS track has at least one waypoint of the converter script won't work
- parse_gps_vizualizer_output output.html > 20110605_Montreal.php (match name to picture album name).
End result
What you get is:
- The javascript google map with your own pictures on it. You can see pictures by hovering over photo pictures, or you can click on them for a picture popup. That picture popup has a link that can take you to the picture library.
All your included photos are also visible on the right tab if you scroll at the bottom (I used a selection of my photos to only show the better ones, and not have a map littered with little camera icons )
- Once you click on a link in a photo, or you are in the picture library like in this page: you can click on the main photo or 'link to google maps' and be brought to a slightly different javascript map. This map is different as it is centered on the photo you just clicked on, zoomed in some more and only shows one photo icon, the photo you were looking at.
- If you are browsing the photo album, you get a new '(georef)' link on all the pictures, which also brings you to the map centered on where the picture was taken.
- When you are reading the report page, all the pictures included on the page also have georeferenced links (like the picture below you can click on)
In a nutshell, the map has links to pictures and pictures have links back to where they were taken on the map.
Required Software
Since I host and run my own anyway so that I can do exactly what I want, I came up with a solution that uses GPS Visualizer and gpsPhoto. My instructions are written for linux, but should work the same on MacOS X, and ought to work on windows with cygwin.
GPS Visualizer is responsible creating a javascript google map with your waypoints and your pictures, like this example.
gpsPhoto takes a GPX track, some time offsets on the command line, and a bunch of jpegs and tags them with their coordinates. You end up with JFIF data like you can see at the bottom of this picture (scroll to the bottom of the page to see the GPS data and IPTC data).
It is enough to have those two, although it's nicer if you can have image links in a google map show you a small version of the picture, and then link to a larger version of the picture. For that, I used my image gallery of choice, Rig, which I also modified to link its pictures back to the location on the map (Rig: link1, link2).
You can however use any picture library system you'd like as long as you manage your own way of making geo-referenced links back to the javascript google map.
How you get there
Geotag your pictures
This is the first step, get the geotagging information in your pictures with gpsPhoto:
./gpsPhoto --gpsfile 20080702_LostCoastTrail.gpx --overwrite-geotagged --timeoffset 25200 --maxtimediff 7200 --dir /photos/20080702_Lost_Coast_Trail/
Let me explain two of the options: --timeoffset is 7 hours x 3600 sec + any offset between your camera time and real local time (7 hours is because I'm in daylight savings time in California (GMT-7), so my GPS UTC time is 7 hours ahead). It is also recommended that you take a picture of your GPS's clock from your camera so that you can compute the offset between your camera time and correct time (or better, fix your camera time before the hike). Of course, if your camera is 5 minutes off on a hike, it may not be a huge deal, but if you're in a car, or plane at over 200mph, 5 minutes goes a long way...
You will also notice the large --maxtimediff 7200 diff I use, of 2 hours. The reason for this is that when I take a 30mn or longer break, I turn off my GPS to save on batteries while potentially still taking pictures. That way, if I setup camp for the night, turn off my GPS and still take pictures around the camp after that, my pictures have a reasonably accurate position on the map (as long as I don't wander off too far from the camp).
Once your pictures are geotagged, you can proceed.
Create your javascript google map with GPS Visualiser
You will be hosting the map you create with GPS Visualiser, and for that to work, you will need your own google API key. Make sure you put the shortest domain name in there, not www.yoursite.tld/some/dir/ but yoursite.tld.
Once you have the key, you can use this link to get the defaults I used to create my map (changes are just a slightly wider track, a 800 pixel wide map, and my google API key which you need to replace with yours).
This is where you get to feed your GPX file, or you can feed a CSV list of waypoints, descriptions and label names (which allows for sorting waypoints by category like I did in my example). You can convert your GPX file to text with this page and read this guide to get more details on the file format.
Tweaking the generated javascript
As you'll see below, I have a script to simply add pictures to your generated map and options you can change by hand in the javascript generated (which is much nicer on Adam's web server since you won't regenerate the map over and over again until you get it right :) ).
Try your resulting html file to make sure the map looks like you wanted, tweak as required.
You then have lots of settings you can tweak in the resulted javacript, Adam did a good job documenting the variables, but there are many, and you may not know what's worthwhile to change. I'm going to list a few here:
Making a map fullscreen:
A map can be made full screen by setting gv_options.full_screen = true; but this makes the waypoint list floating on top of the map. This is turns unfortunately makes the map off center since the center code does not take into account the portion of map obscured by the waypoint map. The following code is then recommended at the end to size the waypoint list to the window size (it would be nice to have the 200 in bold auto-resize to the track list height):
// put this after gv_options.tracklist_options
<?php $in = $_REQUEST;
if ($in['fullscreen'] == 0)
{
echo "gv_options.full_screen = false;";
}
else
{
// true|false: should the map fill the entire page (or frame)?
echo "gv_options.full_screen = true;";
// when full screen, marker list will grow from the bottom, so tracklist should grow from the top
echo "gv_options.tracklist_options.position = ['G_ANCHOR_TOP_RIGHT',6,40];";
}
?>
(...)
// this is optional to resize the waypoint list height on the first display
$('gv_marker_list').style.height = (gmap.getSize().height-300)+'px';
GEvent.addListener(gmap, "resize", function() {
// resize accordingly when needed
$('gv_marker_list').style.height = (gmap.getSize().height-300)+'px';
});
GV_Finish_Map(gv_options);
You can also add these variables to the URL:
- zoom=level
- center=wpts[0] (wpt 1) or center=waypointname or center=trk[3]
- even url?center=4&zoom=12.
- or url?center=1&open_info_window=0 to center on a waypoint without showing its info (otherwise you can turn that off by default with gv_options.centering_options = { 'open_info_window':false.
- maptype=G_HYBRID_MAP, G_PHYSICAL_MAP, MYTOPO_TILES
- showonlytrack=7¢er=trk[7]
One thing I did was just to feed my GPX file and I edited the generated map I got from gpsvisualizer to add labels, based on the waypoint types (blue flag vs Cross sign). If you want to go that route, you can use those scripts:
gandalf [mc]$ cat add_label
perl -pi.bak -e "s#/gpsmap/(.*).png'#/gpsmap/\$1.png',folder:'\$1'#g; s#(folder:'[^']*)%2C_#\$1 #g; s#(folder:'[^']*)_#\$1 #g" $1
gandalf [mc]$ cat change_labels
perl -pi -e "s/Pin Blue/Creeks/; s/Flag Blue/Waypoints/; s/(folder:[^']*)Crossing/\$1Tide Crossings/; s/Flag Green/EndPoints/" $1
Add select pictures to your google map
While I recommend against adding all your pictures to the map (it would be too cluttered), you can chose a few select pictures and add those.
This is where you use the first function of my pictprocess script, you call it as gen_gmaps_gv after editing pathnames in it, and this will generate a bunch of lines that look like this:
gen_gmaps_gv *.jpg
(...)
Wrote 446_LCT_Day2 / 40.0449581 / -124.0786916
Missing GPS data for 500_The_Counter.jpg
All gv data written to gvoutput, merge those waypoints to your JS html file
tail -1 gvoutput
GV_Draw_Marker({lat:40.0449581,lon:-124.0786916,name:'446_LCT_Day2',desc:'446_LCT_Day2',url:'/perso/hiking/Pix/20080702_Lost_Coast_Trail/446_LCT_Day2.html',thumbnail:'/perso/hiking/Pix/rig-cache/20080702_Lost_Coast_Trail/prev640_446_LCT_Day2.jpg',color:'magenta',icon:'camera',folder:'photos'});
While you're at it, consider changing the following values:
- marker_link_target from _blank to youralbum (this will cause all pictures opened in a new window to share the same window as opposed to opening a lot of new ones).
- thumbnail_width from 0 to 480 or smaller if you want to force resize big thumbnails to smaller sized ones.
At this point, make a backup copy of your gmap.html (google map output from gpsvisualizer) and add the content of gvoutput to it in the end section where the other GV_Draw_Marker lines are (at the beginning or the end of the block depending on where you want your photo icons to show up, I put mine at the end).
Open gmap.html with your browser, make sure it still works.
If so, congratulations, you have a georeferenced map with your waypoints and selected photos.
You can include that html map within another page with code like this:
<iframe src="/path/to/20080702_Lost_Coast_Trail.html" marginheight="0" marginwidth="0" frameborder="0" scrolling="no" width="1030" height="800">
</iframe>
Make a php version of your gmap.html with my scripts that do the work
(note, the gps Visualizer code gets updated from time to time. Some of the information on this page may be slightly outdated and require minor tweaks, but I'll try to keep the the javascript patch reasonably up to date)
Ok, hand patching sucked, so I did better: parse_gps_vizualizer_output is a script that will nicely take as input a file generated from GPS Visualizer (assuming you use the same settings than me, using the link I gave above), and add all the nice PHP bits to make the map even smarter and dynamically geolocation aware than the stock one.
The gmap.html from above does not work as a landing page when you click on photos that you included in a web page, or a photo from your image gallery (Rig or other).
To achieve this, you need to copy gmap.html to gmap.php, configure your web server to parse php files if necessary, and hand apply this patch (sorry, the diff cannot auto apply, but again, use parse_gps_vizualizer_output which actually has a chance of auto applying).
What the diff does is:
- center the map on the lat/lon provided
- change the zoom level to 14, you could even zoom more if you wanted to
- hide the center crosshair as it would conflict with the photo icon
- Create a new GV_Marker entry with the waypoint info being fed via the URL
Once you've done this, load your PHP file to see if it generates a working page. If it does, your php probably works. After that, try adding ?lat=40.1321163&lon=-124.1817920&name=photo&desc=desc&label=photos after your php filename in the URL, like in this page
Note that with the new javascript diff above, there is no real need to use/keep/separately maintain the html file. The php file will autodetect whether it's supposed to show the entire map with all the pictures that were added, or zoom on the point given while showing the picture given.
You probably just want to edit the html title in that file to match what you graphed.
Adding georef links to a static page with existing pictures
If you have a static page with included pictures, you can run pictprocess against the html and it'll add height/width tags if they are missing as well as a link for each jpeg with GPS tags.
This is how this page has pictures that you can click on.
Since the pictures in your html page are likely scaled down copies of your originals, if they are missing the GPS tags, you can add them with this command:
cd pictdir
jhead -te /original/dir/'&i' picts*.jpg
Patching Rig or picture gallery program
Patch Rig (or your picture gallery program) to parse a .rig_mapping file that contains a link text and link target with geotag information for each photo. The file looks like this:
(...)
447_LCT_Day2.jpg|georef|Link to Google Maps|
448_LCT_Day2.jpg|georef|Link to Google Maps|
This is the patch for Rig to support those .rig_mapping files.
Now, you simply have to generate this .rig_mapping file, which you do with another symlink to pictprocess, called gen_rig_gps_mapping. If you just run it in the directory you want to generate some georef links for, it'll drop a .rig_mapping that will be automatically used by Rig, like in this page.
End result
When you're done, you get a page like this one.
Thank the tool authors and make a donation if you can
If this works for you, a simple thanks Email is plenty for me, donations aren't needed. However, this guide would be nothing without GPS Visualiser, which quite frankly is a great piece of work. So, consider making a donation if you can.
gpsPhoto is also a well done script that gets the job done right, and Rig is still the most versatile picture gallery viewer in my opinion.
All the patch files can also be found here
Feedback is appreciated
Email
Link to Home Page