OJW's image locator script - source code
Jump to navigation
Jump to search
Source code to OJW's image locator script
This program is public domain
use strict; my $Tracklog = shift(); my $Directory = shift(); my $GpsTime = shift() or 0; my $CameraTime = shift() or 0; my $Offset = TimeToSeconds($CameraTime) - TimeToSeconds($GpsTime); printf STDERR "Using an offset of %+d seconds\n", $Offset; my($Lat,$Long); my %Points; ReadTracklog($Tracklog); print HtmlHeader(); ProcessImageDir($Directory); print HtmlFooter(); sub ProcessImageDir(){ my $Dir = shift(); print STDERR "$Dir:"; opendir(DIR, $Dir) || return; while(my $File = readdir(DIR)) { if($File =~ /\.jpg$/i && (substr($File,0,1) ne "_")) { my $FullFile = "$Dir/$File"; my $Thumbnail = "$Dir/_thumb_$File"; my ($ImageDate,$ImageTime) = GetImageDate($FullFile); my $CorrectedTime = PrintTime(TimeToSeconds($ImageTime) - $Offset); my ($Valid, $Lat,$Long,$Quality) = LookupTime($ImageDate, $CorrectedTime); print HtmlSummary( $File, $FullFile, $Thumbnail, $ImageDate, $ImageTime, $CorrectedTime, $Valid, $Lat, $Long, $Quality); print STDERR $Valid ? ($Quality > 20 ? "~" : ".") : "X"; } } print STDERR "\n"; } sub HtmlHeader(){ my $Style = ".good{background-color:#CFC}.ok{background-color:#FFC}.bad{background-color:#FCC}"; return("<html><head><title>Photo correlation</title><style>$Style</style></head><body>"); } sub HtmlFooter(){ return("</body></html>"); } sub HtmlSummary() { my ($Title, $Filename, $Thumbnail, $Date, $Time, $CorrectedTime, $Valid, $Lat, $Long, $Quality) = @_; my $Html = sprintf("<p class=\"%s\">", ((!$Valid) || $Quality > 60) ? "bad" : ($Quality < 10 ? "good" : "ok")); my $Image = "<img src=\"file://$Thumbnail\" width=\"200\" alt=\"$Title\">"; $Html .= "<a href=\"file://$Filename\">$Image</a><br>"; $Html .= "<table>". HtmlTableRow("Filename", $Title). HtmlTableRow("Date", $Date). HtmlTableRow("Image timestamp", $Time). HtmlTableRow("Corrected timestamp", $CorrectedTime). HtmlTableRow("Quality", !$Valid ? "No GPS found" : "GPS was $Quality seconds from photo"). HtmlTableRow("Latitude", $Lat). HtmlTableRow("Longitude", $Long). "</table>\n"; $Html .= "</p>\n<hr>\n"; return($Html); } sub HtmlTableRow(){ return(sprintf("<tr><th>%s</th><td>%s</td></tr>\n",shift(), shift())); } sub ReadTracklog(){ my $Filename = shift(); print STDERR "Reading tracklog..."; open(TRACKS, "<", $Filename) || return; foreach my $Line(<TRACKS>){ if($Line =~ /<trkpt lat=\"(.*)\" lon=\"(.*)\">/){ ($Lat,$Long) = ($1,$2); } if($Line =~ /<time>(.*)<\/time>/){ my ($Date, $Time) = GpxTime($1); $Points{$Date}{$Time}{LAT} = $Lat; $Points{$Date}{$Time}{LONG} = $Long; $Points{$Date}{$Time}{VALID} = 1; #printf "%s %s = %f,%f\n", $Date, PrintTime($Time), $Lat, $Long; } } close TRACKS; print STDERR "done\n"; } sub GetImageDate(){ my $Filename = shift(); open(IN, $Filename) || return((0,0)); binmode(IN); read(IN, my $Data, 3000); close IN; if($Data =~ /(\d{4}:\d{2}:\d{2}) (\d{2}:\d{2}:\d{2})/){ my ($Date, $Time) = ($1,$2); $Date =~ tr/:/-/; return($Date,$Time); } return(0,0); } sub LookupTime(){ my $LookupDate = shift(); my $LookupTime = TimeToSeconds(shift()); for(my $Offset = 0; $Offset < 6000; $Offset++){ if($Points{$LookupDate}{$LookupTime - $Offset}{VALID} == 1){ return( 1, $Points{$LookupDate}{$LookupTime - $Offset}{LAT}, $Points{$LookupDate}{$LookupTime - $Offset}{LONG}, $Offset); } } return(0,0,0,0); } sub GpxTime(){ my $Time = shift(); if($Time =~ /(.*)T(\d+)\:(\d+)\:(\d+)Z/){ return($1, $4 + ($3 + ($2 * 60)) * 60); } return(-1,-1); } sub TimeToSeconds(){ my @Parts = split(/:/, shift()); return( $Parts[0] * 3600 + $Parts[1] * 60 + $Parts[2]); } sub PrintTime($Seconds){ my $Time = shift(); return(sprintf("%02d:%02d:%02d", ($Time % 86400) / 3600, ($Time % 3600) / 60, ($Time % 60))); }