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)));
}