I’ve been using my KML/KMZ driving log storage for about a year now, and it’s generally worked really well for me. I can use a single script to import GPX files from my Garmin GPS unit; it handles merging new tracks with existing tracks without duplication, generating a human-readable KML file to act as my canonical driving log storage, and generating a compressed KMZ file for me to open on portable devices.
However, one issue that I haven’t solved is that the GPX data I’m importing often shows gaps on the map:
The main cause of this has to do with how the Garmin unit itself logs data.
As a refresher, GPX files are XML files which store track data in the following tree:
<gpx>(root of the GPX file)
So as I’m driving along, the Garmin unit is appending trackpoints to the most recent track segment of the most recent track. When I import the Garmin’s GPX file into my KML driving log, I simply create a KML
LineString for each GPX
trkseg (in any
track), using the
trkpt elements as coordinates.
A collection of trackpoints can be connected to show the path I took on a map. All trackpoints in a track segment can be connected to show the path I took. However, if one track segment were to end in the middle of a drive, followed immediately by a new track segment, there would be a small gap in the path—the final trackpoint of the first segment would not be connected to the first trackpoint of the next segment.
Normally, this splitting of the tracks is a good thing. If I stop driving for a while, I probably want to start a new track segment. I especially want to create a new track segment if the Garmin is going to be moved while it’s off. For example, if I turn it off in an airport parking lot, pack it in my bag, and fly with it to a new destination to put in a rental car, then I don’t want to connect the trackpoints on either end with a straight line clear across the country. Even locally, I don’t have my Garmin running in my car 100% of the time (there’s no point in running the Garmin for local trips where all the roads are already logged), so I don’t need a bunch of straight lines running across town.
The problem I run into is that turning the car (and Garmin) off isn’t the only time that it starts a new track segment.
If I’m having the Garmin navigate me along a route and the route ends (because I reached a destination and decided to keep driving, or because I manually cancelled navigation), then the unit will end the current track segment and start a new one.
The Garmin unit sometimes starts new track segments when it’s running its rerouting algorithm, either because I missed a turn or because it’s trying to see if there’s a better route around traffic.
If I lose GPS signal entirely for more than a few seconds (for example, driving through a tunnel), then the Garmin will end a track segment with the last known point, and start a new track once it has signal again.
Track Segment Merging Concerns
For a lot of these paths with gaps, the correct thing to do would be to merge two or more GPX
trksegs into a single KML
LineString. However, just merging the track segments isn’t as simple as it sounds.
I needed to come up with a solution that would still allow me to keep track of all which track segments were already in my driving log data–otherwise, so that I could make sure that I didn’t accidentally import a track segment that was already in my driving data.
Secondly, I wouldn’t be able to automatically decide which track segments to merge and which to leave separate. While I could have potentially put some sort of rules in place on whether or not to merge (e.g. the two segments are less than a certain number of seconds apart and a certain distance apart), there would be too many edge cases driving false positives and false negatives no matter what rules I put in place. So I needed a way to manually designate which segments should be merged together.
KML Folder Solution
As discussed in my prior post, I have a KML file as my official driving log data store, and I also export a compressed KMZ file. Up until now, these two files have been essentially identical; the latter has been just a zipped copy of the former, but they both have had the same XML layout.
But there’s no reason they necessarily have to have the same layout; I could store information in the canonical KML file that could be used to process the output KMZ file in a certain way. Specifically, I could store all of the unmerged
LineStrings in the canonical KML file to keep track of which
trksegs were already imported, while also indicating in that KML file which of the
LineStrings should be merged together. Then, when I created the output KMZ file, I could use that information to merge
LineStrings appropriately as I exported them.
I decided to accomplish this by using KML
Before this update, the KML file stored all
LineString elements in
Placemark elements under the root
Document. Now, I can create a
Folder in the KML file, and put two or more
Placemarks in it. If I do that, then all
LineStrings in the
Placemarks in a particular folder will be merged when my script creates the output KMZ file.