Archive for November, 2005

Upgrading Postgres 7.4 to 8.0 in Debian

Wednesday, November 9th, 2005

I recently had to upgrade my PostgreSQL 7.4 to 8.0 in Debian and learned that there is a cool way of doing this. This procedure is described in /usr/share/doc/postgresql-common/architecture.html.

In a nutshell:

  1. Install the new version in packages: postgresql-*-8.0. Mote that all the pg_* tools still point to the old versions.
  2. Make sure that both servers are up and running.
  3. Run: “pg_upgradecluster 7.4 main” to upgrade the old database to the new one.
  4. Now all the pg_* tools point to the new versions, also the new server will listen on the standard port. Check if everything works fine.
  5. Run “pg_dropcluster 7.4 main” to delete the old database.

Cool. I wonder how Gentoo does this ;-)

  • gmap-pedometer: you can put markers on google maps and it tells you how long your trip was (including calories and mile markers if you want). (BTW: switch mile markers off on long routes!) (0)

On Image GeoTagging or why I love Image::ExifTool, hate GPS::Garmin and am indifferent to Garmin’s transfer protocol.

Tuesday, November 1st, 2005

GeoTagging: This idea has been maturing long enough and last Sunday reached its critical mass. Here’s my account on the story and a few things I learned.

GeoTagging The idea is simple: when you go hiking, sightseeing, travelling you put a GPS on top of your backpack. You go and take photos as usual. When you’re back home, you connect the GPS to the computer and download the saved track. You then run a program that correlates the time when the images were taken with your position from the track and encodes this information into EXIF. As a result the images are GeoTagged and their position can be displayed by a GeoTagging-aware software.

Downloading GPS After having a look at different options, I chose two candidates for downloading the track: gpstrans and GPS::Garmin.

Note that these both support only Garmin GPSs. I don’t know if there is any universal track transfer protocol (probably not). Everything that claims to be cross-GPS typically is limited to reading the current position via NMEA.

GPStrans works ok, although it’s a bit old and doesn’t work well with my eTrex. The problems are: waypoints are corrupted, track does not contain the information about new segments and the output format is strange (this can be fixed). Afterall, I must admit that unlike other tools it worked at the first try.

GPS::Garmin gave me much more trouble. First it tunred out that it relied on some undocumented behavior of Device::Serial and at the end it turned out that it was doing a non-blocking read and considered that it would always get data. While this might have been true a couple of years ago, since then computers have gotten faster and it stopped working. After a couple of hours I fixed it by adding: $PortObj->read_const_time(5000); $PortObj->read_char_time(5000); somewhere in GPS::Serial.

The second problem was that the code relied on particular product codes of Garmin deivces and changed its behavoir accordingly. The problem is that it’s not exactly how Garmin protocol was written (unless you want to encode the behavior of all their products).

Garmin Protocol It’s fairly simple, although implementing it correctly can take a good evening. The problem is that the number of commands is limited (e.g., get waypoints, get track, get route), however the interpretation of data received differs depending on the device. This is a bit strange, but it is the way it is. One way of going around it is to know which devices do what (GPS::Garmins’s approach). The better way could be to query which protocol version is supported (e.g., A100, A103, A108) and load the correct handler accordingly. Wonder why they didn’t do it…

Image::ExifTool I really love it. It’s a well-maintained, and a fully functioned EXIF read and manipulation library. Adding GPS data to an image is virtually 6 lines of code (taking error checking out): $exifTool->ExtractInfo($file); $exifTool->SetNewValue(GPSLatitudeRef => ($lat > 0)?'N':'S', Group=>'GPS'); $exifTool->SetNewValue(GPSLongitudeRef => ($lon > 0)?'E':"W", Group=>'GPS'); $exifTool->SetNewValue(GPSLatitude => abs($lat), Group=>'GPS'); $exifTool->SetNewValue(GPSLongitude => abs($lon), Group=>'GPS'); $exifTool->WriteInfo($file, $file."-new");

Ok, the real code is more complicated but it’s what it does:

  • Read saved GPS track (array of arrays) and sort it by the timestamp
  • Process files from the command line: check if they have EXIF, are not already GeoTagged or have some other problems.
  • Do the binary search on the sorted timestamps and find the correct two elements.
  • If the second one does not start a new segment (or the timestamp difference is not too big) approximate the position from the two points.
  • Write the data back to the file, making backup if necessary

The program is really simple and works well. What remains to be done now is to add some more runtime options and write a manual. I also need to work a bit more on the garmin transfer program - I’m still not happy with GPS::Garmin, even after some basic fixes.