Skip to content

Instantly share code, notes, and snippets.

@luelista
Last active May 5, 2019 01:16
Show Gist options
  • Save luelista/757850 to your computer and use it in GitHub Desktop.
Save luelista/757850 to your computer and use it in GitHub Desktop.
Extracts GPS location data from JPEG EXIF and creates a KMZ file with thumbnails. Info and Howto here: http://home.max-weller.de/perl/jpeg2kml/
#!/usr/bin/perl
# jpeg2kml.pl
# Extracts GPS location data from JPEG EXIF and creates a KMZ file with thumbnails
# http://home.max-weller.de/perl/jpeg2kml/
use strict;
use Image::ExifTool qw(:Public);
use File::Basename;
use File::Copy;
use Data::Dumper;
my $tempdef = "/tmp/jpeg2kml_tmpdir";
my $convert = "convert";
if ($^O eq 'MSWin32') {
$tempdef = "./jpeg2kml_tmpdir";
$convert = "convert.exe";
}
# ------ GLOBAL CONFIG ---------------
my %options = ( tempDir => "./jpeg2kml_tmpdir",
thumbWidth => 640,
thumbHeight => 480,
kmlFilename => "doc.kml",
showFilename => 0,
iconScale => "1.5"
);
# ------ ENDE GLOBAL CONFIG ----------
my $tempDir = $options{'tempDir'};
die "Usage: perl jpeg2kml.pl DIRECTORY TARGET_FILE" if ($#ARGV != 1);
mkdir $tempDir;
print "Created directory $tempDir ...\n";
print "Creating '$options{kmlFilename}' ...\n";
open FILE, ">", $tempDir."/".$options{"kmlFilename"};
print FILE q{<?xml version="1.0" encoding="UTF-8"?>}, "\n";
print FILE q{<kml xmlns="http://www.opengis.net/kml/2.2">}, "\n";
print FILE q{ <Folder>}, "\n";
my $dir = $ARGV[0];
$dir="$dir/" if ($ARGV[0] !~ m|[/\\]$|);
opendir (DIR, $dir) or die "$dir: $!\n";
my $imageFilename;
for $imageFilename (readdir DIR) {
next if ($imageFilename !~ /.jpg$/i);
print "Creating thumbnail for '$imageFilename' ... ";
# use % for dereferencing the ptr to hash returned by ImageInfo
my %info = %{ ImageInfo($imageFilename, {"CoordFormat" => "%.14f" } ) };
my $name = basename($imageFilename);
my $targetFilename = "$tempDir/$name";
if (-f $targetFilename) {
print "EXISTS\n";
} else {
system "$convert -scale $options{thumbWidth}x$options{thumbHeight} \"$imageFilename\" \"$targetFilename\"";
if (-f $targetFilename) { print "OK\n"; } else { print "FAIL [!]\n"; }
}
my ($lon,$lat) = ( latLonSigned($info{"GPSLongitude"}), latLonSigned($info{"GPSLatitude"}) );
print FILE qq{ <Placemark>}, "\n";
print FILE qq{ <name>$name</name>}, "\n" if ($options{'showFilename'});
print FILE qq{ <description><![CDATA[<img src="$name">]]></description>}, "\n";
print FILE qq{ <Style><IconStyle><Icon><href>$name</href></Icon><Scale>$options{iconScale}</Scale></IconStyle></Style>}, "\n";
# longitude,latitude[,altitude]
print FILE qq{ <Point><coordinates>$lon,$lat,0</coordinates></Point>}, "\n";
print FILE qq{ </Placemark>}, "\n";
}
close DIR;
print FILE q {</Folder>}, "\n";
print FILE q{</kml>}, "\n";
close FILE;
print "Creating kml and thumbs: done\n";
print "\n\nCompressing to KMZ ...\n";
unlink "$tempDir/temp.zip";
if ($^O eq 'MSWin32') {
system "cmd", "/c", "cd \"$tempDir\" & zip.exe -D \"temp.zip\" \"*\"";
} else {
system "sh", "-c", "cd \"$tempDir\" && zip -r \"temp.zip\" \"*\"";
}
move("$tempDir/temp.zip", $ARGV[1]);
print "\n\n";
print "KMZ file saved as: $ARGV[1]\n";
print "\nDone.\n";
sub latLonSigned {
if ($_[0] =~ /([0-9.]+)\s*([NESW])/) {
return "-$1" if ($2 eq "W" || $2 eq "S");
return "$1"; #else
} else {
return $_[0];
}
}
@roleohibachi
Copy link

Nice! Possible easy improvement: create a kml timestamp from the exif "date taken" field.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment