Tips for print format file to generate Google Earth KML for geo-tagged photos

Started by Kohekohe, November 23, 2016, 03:23:19 PM

Previous topic - Next topic

Kohekohe

1. A great starting example is at the bottom of http://www.exiftool.org/geotag.html

2. Not all your photos might have geo-coordinates, so you can add  -if "$gpslongitude ge 0" to the exiftool command line parameters to process only the files that have geo-coordinates.  That way your KML list of photos in Google Earth doesn't become cluttered by the photos without coordinates.

3. -r -fileOrder DateTimeOriginal are handy exiftool parameters to go through a whole directory structure of photos and end up with a KML that's sorted by photo date!
I just run the exiftool command from the top level and specify . (a dot = current directory) as the starting point.  Leave the KML output file in the same top level directory and Google Earth will find your local image files.

4. If you have lots of photos, the names of them on all the placemarks end up cluttering Google Earth.  Replace the
#[HEAD]    <Style id="Photo">
...
#[HEAD]    </Style>
with the following StyleMap of two styles so that the photo name is hidden (LabelStyle scale 0) unless you hover over the placemark or select it.  This is much neater if you have lots of placemarks/photos:

#[HEAD]    <Style id="Photo_normal">
#[HEAD]      <IconStyle>
#[HEAD]        <Icon>
#[HEAD]          <href>PhotoPin.png</href>
#[HEAD]          <scale>1.0</scale>
#[HEAD]          <hotSpot x="0.5" y="0" xunits="fraction" yunits="fraction"/>
#[HEAD]        </Icon>
#[HEAD]      </IconStyle>
#[HEAD]      <LabelStyle>
#[HEAD]        <scale>0</scale>
#[HEAD]      </LabelStyle>
#[HEAD]    </Style>
#[HEAD]    <Style id="Photo_highlighted">
#[HEAD]      <IconStyle>
#[HEAD]        <Icon>
#[HEAD]          <href>PhotoPin.png</href>
#[HEAD]          <scale>1.0</scale>
#[HEAD]          <hotSpot x="0.5" y="0" xunits="fraction" yunits="fraction"/>
#[HEAD]        </Icon>
#[HEAD]      </IconStyle>
#[HEAD]      <LabelStyle>
#[HEAD]        <scale>0.75</scale>
#[HEAD]      </LabelStyle>
#[HEAD]    </Style>
#[HEAD]    <StyleMap id="Photo">
#[HEAD]      <Pair>
#[HEAD]        <key>normal</key>
#[HEAD]        <styleUrl>#Photo_normal</styleUrl>
#[HEAD]      </Pair>
#[HEAD]      <Pair>
#[HEAD]        <key>highlight</key>
#[HEAD]        <styleUrl>#Photo_highlighted</styleUrl>
#[HEAD]      </Pair>
#[HEAD]    </StyleMap>

Note: In the above code, I use a local image file "PhotoPin.png" for the placemark icon with the hotspot halfway (0.5) across the bottom (0) of the icon image, and I've also reduced the label text size to 0.75 scale (for the highlighted style, where the text is actually shown).

5. When you click on a placemark and it shows the photo, I like having the date underneath the photo.  What is displayed in the popup in Google Earth is basic HTML, so you can simply add another table row below the image: ...</td></tr><tr><td>$DateTimeOriginal</td></tr>
If you do that, but aren't happy with the default format, you can specify a different format via an exiftool command line parameter, e.g. -d "%d %b %Y %I:%M %p" gets you 30 Sep 2015 11:32 a.m.

If you don't want leading zeros for the day or hour, then add a minus sign after the %, e.g. %-d  (if you use Windows, use a # instead of the minus sign).  See http://strftime.org/ for a complete list of date/time format options.

Note: You could display any exiftool variable here (f-stop, shutter speed, whatever!) - how awesome is that?!

6. In the example file, the placemark labels display the filename (<name>$filename</name>).  To make it a bit neater, you can strip the .jpg extension, and also change '&' to '&amp;' if you have any ampersands in any filenames, otherwise the HTML complains:
<name>${filename;s/.jpg//g;s/&/&amp;/g}</name>

7. Keep in mind that what's displayed in the popup is basically HTML.  So, you can do things like limit the size of the image shown, so it doesn't end up having scroll bars by adding an inline CSS style, e.g.
<img src="$directory/$filename" style="max-height: 900px" />

Phil Harvey

Awesome!  Some very useful tips!  I have added a link to your post from the Geotagging page.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

havkacik

Because default KML.FMT definition file  only extracts latitude, longitude and time only, one might want to make some customization in order to extract additional elements like GPSAltitude, GPSSpeed, GPSTrack (compass information), GPSSatellites and GPSDOP (Dilution of Precision).

With help of Google's KML Reference (based on KML 2.2. standard),  and ExifTool Tag help page and CSV help page, we can define KML.FMT file which is extracting ALL GPS information (except accelerometer data but this is limitation of current version 12.82 ExifTool) and add the data into ExtendedData KML element.

However, based on Google's reference on Adding Custom Data  Google Earth is currently unable to color data by speed so the exports will server just for historical purposes. We are using third approach (from the Google referenced help page) for Adding Arbitrary XML Data to a Feature which allows you to preserve user data within a KML file. Google Earth passes this data along with the file and saves it, but does not use it.

The KML.FMT looks something like this:

#------------------------------------------------------------------------------
# File:         kml_track_naextbase_dashcam.fmt
#
# Spec:         This is generated for Google KML elements defined in KML Version 2.2, as well as elements in the Google extension namespace. 
#
# Link:         Reference link: Google KML Version 2.2 https://developers.google.com/kml/documentation/kmlreference
#
# Description:  Example ExifTool print format file for generating a
#               track in Google Earth KML format from a collection of
#               geotagged images or timed GPS from video files
#
# Usage:        From a collection of images:
#
#                 exiftool -p kml_track.fmt -r DIR [...] > out.kml
#
#               From video files:
#
#                 exiftool -p kml_track.fmt -ee3 FILEorDIR [...] > out.kml
#
# Requires:     ExifTool version 10.41 or later
#
# Revisions:    2019/10/29 - P. Harvey created
#               2024/04/14 - MM added support for Google KML elements defined in KML Version 2.2, works well with ExifTool 12.56 and NextBase 622GW source MP4 files
#
# Notes:     1) Input files must contain GPSLatitude and GPSLongitude.
#            2) The -fileOrder option may be used to control the order of the
#               waypoints when processing multiple still-image files, or the
#               order of the tracks when processing multiple video files.
#            3) The "0" in the BODY line below may be changed to "$gpsaltitude#"
#               and the altitudeMode may be changed to "absolute" to store
#               altitude information if it exists in the track log.
#------------------------------------------------------------------------------
#[HEAD]<?xml version="1.0" encoding="UTF-8"?>
#[HEAD]<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2">
#[HEAD]  <Document>
#[HEAD]    <name>NextBase NB622GW Tracks</name>
# MM: the part below defines generic styles of tracks to be shown in Google Earth
#[HEAD]    <!-- Normal track style -->
#[HEAD]    <Style id="track_n">
#[HEAD]      <IconStyle>
#[HEAD]        <scale>.5</scale>
#[HEAD]        <Icon>
#[HEAD]          <href>http://earth.google.com/images/kml-icons/track-directional/track-none.png</href>
#[HEAD]        </Icon>
#[HEAD]      </IconStyle>
#[HEAD]      <LabelStyle>
#[HEAD]        <scale>0</scale>
#[HEAD]      </LabelStyle>
#[HEAD]
#[HEAD]    </Style>
#[HEAD]    <!-- Highlighted track style -->
#[HEAD]    <Style id="track_h">
#[HEAD]      <IconStyle>
#[HEAD]        <scale>1.2</scale>
#[HEAD]        <Icon>
#[HEAD]          <href>http://earth.google.com/images/kml-icons/track-directional/track-none.png</href>
#[HEAD]        </Icon>
#[HEAD]      </IconStyle>
#[HEAD]    </Style>
#[HEAD]    <StyleMap id="track">
#[HEAD]      <Pair>
#[HEAD]        <key>normal</key>
#[HEAD]        <styleUrl>#track_n</styleUrl>
#[HEAD]      </Pair>
#[HEAD]      <Pair>
#[HEAD]        <key>highlight</key>
#[HEAD]        <styleUrl>#track_h</styleUrl>
#[HEAD]      </Pair>
#[HEAD]    </StyleMap>
#[HEAD]    <!-- Normal multiTrack style -->
#[HEAD]    <Style id="multiTrack_n">
#[HEAD]      <IconStyle>
#[HEAD]        <Icon>
#[HEAD]          <href>http://earth.google.com/images/kml-icons/track-directional/track-0.png</href>
#[HEAD]        </Icon>
#[HEAD]      </IconStyle>
#[HEAD]      <LineStyle>
#[HEAD]        <color>99ffac59</color>
#[HEAD]        <width>6</width>
#[HEAD]      </LineStyle>
#[HEAD]    </Style>
#[HEAD]    <!-- Highlighted multiTrack style -->
#[HEAD]    <Style id="multiTrack_h">
#[HEAD]      <IconStyle>
#[HEAD]        <scale>1.2</scale>
#[HEAD]        <Icon>
#[HEAD]          <href>http://earth.google.com/images/kml-icons/track-directional/track-0.png</href>
#[HEAD]        </Icon>
#[HEAD]      </IconStyle>
#[HEAD]      <LineStyle>
#[HEAD]        <color>99ffac59</color>
#[HEAD]        <width>8</width>
#[HEAD]      </LineStyle>
#[HEAD]    </Style>
#[HEAD]    <StyleMap id="multiTrack">
#[HEAD]      <Pair>
#[HEAD]        <key>normal</key>
#[HEAD]        <styleUrl>#multiTrack_n</styleUrl>
#[HEAD]      </Pair>
#[HEAD]      <Pair>
#[HEAD]        <key>highlight</key>
#[HEAD]        <styleUrl>#multiTrack_h</styleUrl>
#[HEAD]      </Pair>
#[HEAD]    </StyleMap>
#[HEAD]    <!-- Normal waypoint style -->
#[HEAD]    <Style id="waypoint_n">
#[HEAD]      <IconStyle>
#[HEAD]        <Icon>
#[HEAD]          <href>http://maps.google.com/mapfiles/kml/pal4/icon61.png</href>
#[HEAD]        </Icon>
#[HEAD]      </IconStyle>
#[HEAD]    </Style>
#[HEAD]    <!-- Highlighted waypoint style -->
#[HEAD]    <Style id="waypoint_h">
#[HEAD]      <IconStyle>
#[HEAD]        <scale>1.2</scale>
#[HEAD]        <Icon>
#[HEAD]          <href>http://maps.google.com/mapfiles/kml/pal4/icon61.png</href>
#[HEAD]        </Icon>
#[HEAD]      </IconStyle>
#[HEAD]    </Style>
#[HEAD]    <StyleMap id="waypoint">
#[HEAD]      <Pair>
#[HEAD]        <key>normal</key>
#[HEAD]        <styleUrl>#waypoint_n</styleUrl>
#[HEAD]      </Pair>
#[HEAD]      <Pair>
#[HEAD]        <key>highlight</key>
#[HEAD]        <styleUrl>#waypoint_h</styleUrl>
#[HEAD]      </Pair>
#[HEAD]    </StyleMap>
#[HEAD]    <Style id="lineStyle">
#[HEAD]      <LineStyle>
#[HEAD]        <color>99ffac59</color>
#[HEAD]        <width>6</width>
#[HEAD]      </LineStyle>
#[HEAD]    </Style>
# MM: the part below defines additional data that I want to pull from *.MP4 source files
#[HEAD]    <Schema id="schema">
#[HEAD]      <gx:SimpleArrayField name="speed" type="int">
#[HEAD]        <displayName>Speed</displayName>
#[HEAD]      </gx:SimpleArrayField>
#[HEAD]      <gx:SimpleArrayField name="magvar" type="int">
#[HEAD]        <displayName>Compass</displayName>
#[HEAD]      </gx:SimpleArrayField>
#[HEAD]      <gx:SimpleArrayField name="sat" type="float">
#[HEAD]        <displayName>Satellites</displayName>
#[HEAD]      </gx:SimpleArrayField>
#[HEAD]      <gx:SimpleArrayField name="pdop" type="float">
#[HEAD]        <displayName>Dilution of Precision</displayName>
#[HEAD]      </gx:SimpleArrayField>
#[HEAD]    </Schema>
# MM: start of the definition of data structure from source to KML formatting
#[HEAD]  <Folder>
#[HEAD]   <name>${main:directory;$_=$self->GetValue('Directory') if $self->Options('ExtractEmbedded')}</name>  <!-- MM: This is the name of the folder -->
#[SECT]    <Placemark>
#[SECT]    <name>${main:directory;$_=$self->GetValue('FileName') if $self->Options('ExtractEmbedded')}</name> <!-- MM: This is a name of the Placemark in Google Earth-->
#[SECT]    <description>${main:directory;$_=$self->GetValue('FileName') if $self->Options('ExtractEmbedded')}</description>   <!-- MM: This is just to show something in the buble in Google Earth-->
#[SECT]    <styleUrl>#multiTrack</styleUrl>
#[SECT]      <gx:Track>
#[SECT]        <altitudeMode>clampToGround </altitudeMode>
#[IF]  $gpsdatetime $gpslatitude $gpslongitude
#[BODY]                <when>${gpsdatetime#;my ($ss)=/\.\d+/g;DateFmt("%Y-%m-%dT%H:%M:%SZ");s/Z/${ss}Z/ if $ss}</when>
#[IF]  $gpsdatetime $gpslatitude $gpslongitude
#[BODY]                <gx:coord>$gpslongitude# $gpslatitude# $gpsaltitude#</gx:coord>
#[BODY]          <ExtendedData>
#[BODY]            <SchemaData schemaUrl="#schema">
#[BODY]              <gx:SimpleArrayData name="speed"><gx:value>$GPSSpeed</gx:value></gx:SimpleArrayData>
#[BODY]              <gx:SimpleArrayData name="magvar"><gx:value>$GPSTrack</gx:value></gx:SimpleArrayData>
#[BODY]              <gx:SimpleArrayData name="sat"><gx:value>$GPSSatellites</gx:value></gx:SimpleArrayData>
#[BODY]              <gx:SimpleArrayData name="pdop"><gx:value>$GPSDOP</gx:value></gx:SimpleArrayData>
#[BODY]            </SchemaData>
#[BODY]          </ExtendedData>
#[ENDS]      </gx:Track>
#[ENDS]    </Placemark>
#[TAIL]   </Folder>
#[TAIL]  </Document>
#[TAIL]</kml>



This has been based Google KML elements defined in KML Version 2.2, works well with ExifTool 12.56 and NextBase 622GW dashcam source MP4 files.

The file can be easily imported to Goole Earth and visualized as visible in the attachment.

PH Edit: Insert image inline


Phil Harvey

Thanks for sharing this.  I've inserted the image into your post to make it easier for people to see the result.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).