Latitude Location History KML Export is very interesting. But how can I download automatically every data? GPS track log is easy to handle geotagging photo than KML waypoint data.

I found that with Workflow is usefull to automatically download. I wrote perl program to convert from KML to GPX track log.

Google Latitude / KML data download
Google Latitude

Download KML data file from Google Latitude

Help page of Google Latitude
Location History - Google Mobile Help

I wrote Workflow to automatic download.

Web browser automation tool
Fake - Mac OS X Web Browser Automation and Webapp Testing Made Simple. Workflow

Convert KML waypoints data files to GPX track log data files

Ruben wrote his blog about how to use this perl script. The entry of his blog is usefull. Please read it.

GPS Babel can not convert from KML file of Google Latitude to GPX Track Log.

So I wrote the Perl script. But now this script does not work.The script does not work any longer because Google Latitude changed the specification.

There are apps in the Android GPX export data from Google Latitude.

You can find the App which add geotag into your images from the Googl Latitude in the Mac App Store.



$ perl *.kml
input: kml-1.kml                                output: 2011-06-29_gl.gpx
input: kml-2.kml                                output: 2011-06-28_gl.gpx
input: kml-3.kml                                output: 2011-06-27_gl.gpx
input: kml-4.kml                                output: 2011-06-25_gl.gpx
input: kml-5.kml                                output: 2011-06-24_gl.gpx
input: kml-6.kml                                output: 2011-06-23_gl.gpx
input: kml-7.kml                                output: 2011-06-22_gl.gpx
input: kml-8.kml                                output: 2011-06-21_gl.gpx
input: kml-9.kml                                output: 2011-06-20_gl.gpx
input: kml.kml                                  output: 2011-06-30_gl.gpx

Source Code

use strict;
use warnings;
use Data::Dumper;
use Encode;
use utf8;
use open ":utf8";
binmode STDIN,  ":utf8";
binmode STDOUT, ":utf8";
binmode STDERR, ":utf8";

sub parse_googlelatitude_datetime {
    use DateTime::Format::DateParse;
    my $str = shift;
    $str =~ s#日本標準時#+0900#;    # for JAPANESE String
    $str =~ s/GMT(.*):(.*)/$1$2/;
    $str =~ s/[時分]/:/g;           # for JAPANESE String
    $str =~ s/秒//;                 # for JAPANESE String
    while ( $str =~ s/ ([A-Z])[a-z]+ Time/ Time$1/ ) {}; # 2011-09-11 added
    $str =~ s/Time([A-Z]+)/$1T/;                         # 2011-09-11 added
    my $dt = DateTime::Format::DateParse->parse_datetime($str);
    return $dt . "Z";

sub test_datetime {
    my $str = shift;
    if ( $str =~ m#\s*<cmt>(.+)</cmt>\s*$# ) {
        my $date = $1;
        my $dt   = parse_googlelatitude_datetime($date);
        return "<time>$dt</time>";
    else {
        return $str;

foreach my $datafile (@ARGV) {
    my $gpx_data;
    printf "input: %-40s", $datafile;
    my $filename_str = $datafile;
    $filename_str =~ s/kml//gi;
    $filename_str =~ s/[^A-Za-z]//gi;
    $filename_str = "_$filename_str" if ($filename_str);
    open GPXDATA, "gpsbabel -i kml -f $datafile -o gpx -F - |"
      or die "cannot pipe from gpsbabel: $!";
    while (<GPXDATA>) {
        $gpx_data = $gpx_data . test_datetime($_);
    close GPXDATA;

    use File::Temp;
    my $tmpfile = File::Temp->new();
    binmode( $tmpfile, ":utf8" );
    print $tmpfile $gpx_data;

    open GPXDATA,
"gpsbabel -i gpx -f $tmpfile -x sort,time -o gpx -F - | gpsbabel -i gpx -f - -x transform,trk=wpt,del -o gpx -F -|"
      or die "cannot pipe from gpsbabel: $!";
    $gpx_data = "";
    while (<GPXDATA>) {
        $gpx_data = $gpx_data . $_;
    close GPXDATA;

    use Geo::Gpx;
    use DateTime;
    my $gpx          = Geo::Gpx->new( xml => $gpx_data );
    my $track_points = $gpx->{tracks}[0]->{segments}[0]->{points};
    my $strftime     = '%Y-%m-%d';
    my $dt_first     = DateTime->from_epoch(
        epoch     => $$track_points[0]->{time},
        time_zone => 'local'
    my $dt_last = DateTime->from_epoch(
        epoch     => $$track_points[ $#{$track_points} ]->{time},
        time_zone => 'local'
    my $output_filename_base = $dt_last . $filename_str . "_gl";
    $output_filename_base =
      "$dt_first" . "_" . "$dt_last" . $filename_str . "_gl"
      if ( "$dt_first" ne "$dt_last" );
    my $output_filename = $output_filename_base . ".gpx";
    my $num             = 1;

    while ( -s $output_filename ) {
        $output_filename = $output_filename_base . "." . $num++ . ".gpx";
    open GPXFILE, ">$output_filename"
      or die "cannot write file ($!)";
    print GPXFILE $gpx->xml;
    close GPXFILE;
    print " output: ", $output_filename;
    print "\n";