GPS, and other kinds of Picture tagging with PowerShell

imageWell… I have been off for a bit and you can have a read of the previous post for some background on that. During that time I’ve done a lot of walking, taking photos as I go.  Having raved about my HTC Touch pro 2 and its GPS I’ve been using it to GeoTag those photos. Naturally (for me) PowerShell figures in here somewhere. I’ve added to the image module in the Windows Powerpack that James Brundage wrote. It now takes data from a log and applies it to pictures. It supports several log formats and incidental things I found I wanted to do with GPS data. And it is available for download

I log my walks using Efficasoft’s GPS  utilities (on the right). I have a picture of the logger to help with the first of the three PowerShell commands I need to use

  1. Set-Offset works out the time difference between the time on the logger and time on the camera and stores it in $offset
  2. Get-CSVGPSData reads the GPS log from a CSV file, using $offset to adjust the time so it matches the camera. I store the result in $points and a successful import can be verified by looking at $points.count.
  3. Copy-GpsImage copies pictures from a memory card to my computer renaming them, rotating them if need be, and tagging them using the GPS data I stored in $points (if copying many files, it is useful to use -verbose switch to see progress)

Steps 2 and 3 might be repeated to tag more than one set of photos provided the camera clock is a consistent interval away from “GPS time”. Here’s what a session looks like in PowerShell


PS > set-offset "D:\dcim \100Pentx\IMG43272.JPG" –Verbose

Click for a Larger VersionPlease enter the Date & time in the reference picture, formatted as
Either MM/DD/yyyy HH:MM:SS ±Z or dd MMMM yyyy HH:mm:ss ±Z: 04/04/2010 16:02:17 +1
VERBOSE: Loading file D:\dcim \100Pentx\IMG43272.JPG
VERBOSE: OffSet = 3607

PS> $points= Get-CSVGPSData 'F:\My Documents\My GPS\Track Log\20100425115503.log' ‑offset $offset
PS> $points.count

593

PS> Dir E:\dcim –include *.jpg –recurse |
Copy-GpsImage -Points $Points `
-Keywords "Oxfordshire" `
-DestPath "C:\users\jamesone\pictures\oxford" `
-replace "IMG","OX-" `
-verbose

VERBOSE: Loading file E:\dcim\100PENTX\IMG43624.JPG
VERBOSE: Checking 593 points for one where DateTime is closest to 04/25/2010 12:36:41
VERBOSE: Point 229 matched with variance of 2 seconds
VERBOSE: Performing operation "Write image" on Target " C:\users\jamesone\pictures\oxford\OX-43624".

In my case this will go through a stack of files, ending
VERBOSE: Performing operation "Write image" on Target " C:\users\jamesone\pictures\oxford\OX-43757"


imageThe picture shows a detail from the Radcliffe Observatory building in Oxford (featured in a recent episode of Lewis ) with its GPS co-ordinates visible through File/Properties. I also wrote a little bit of code to push the data from the log though to MapPoint – this ended up as a function Out-MapPoint although I later added a function named convertTo-GPX which does the same job more quickly and also works with programs like GoogleEarth.

$MPApp = New-Object -ComObject "Mappoint.Application" $MPApp.Visible = $true $map = $mpapp.ActiveMap ForEach ($point in $points) {    $location=$map.GetLocation($point.Lat, $point.lon)    $Pin =$map.AddPushpin( $location, $point.datetime)    if ( $point.datetime -lt [datetime]"04/25/2010 12:12:00"){$pin.symbol= 6 }    else                                                     {$pin.symbol = 7} } The details behind this this take some explaining, so this will be the first of several parts: if you would like to know more have a look at the next few posts where I will drill into how it all works, but if you want to dive in and play the code is available for download now.