Google Maps multi-day timeline
Caution: Google frequently updates its products, which can render previous work obsolete. Therefore, this tutorial is relevant as of January 27, 2024.
Prerequisites: This solution utilizes Node JS 18+, so ensure it is installed if you plan to follow along as described.
Recently, I embarked on an amazing three-week journey through California (and a bit of Nevada and Arizona), covering nearly 6,800 km. Along the way, I accumulated 320,000 steps and captured 150,000 photos and videos.
As someone who enjoys tracking key statistics, I envisioned displaying my entire trip on a map. Picture an Instagram post or story featuring a timeline in the background with key stats overlaid — sounds intriguing, right?
It was disappointing to learn that Google Maps does not support multi-day timelines. Even more frustrating was discovering the lack of tools available to achieve this, with many becoming obsolete after various Google Maps updates.
After reviewing the exported timeline and KML data formats, I realized that creating a basic converter wouldn’t be too difficult. With the assistance of ChatGPT (who doesn’t love a bit of boilerplate code?) and a few searches on Google (because sometimes documentation and Stack Overflow reign supreme), I developed a straightforward script that could benefit others in my situation.
Below is a simple tutorial to help you achieve the results shown in the hero image:
- Export your timeline from Google Maps using your mobile device (this feature has been removed from the web version). For Android users (apologies to iOS users), navigate to Settings > Location > Location Services > Timeline, select your Google Account (if you have multiple), and click on Export Timeline Data. Once completed, you will find a Timeline.json file in your storage.
- Transfer the Timeline.json file to your laptop and create a timeline.mjs file in the same directory with the following content:
function convertTimelineToKML(data, start, end) {
const placemarks = data["semanticSegments"]
.filter(item => item.hasOwnProperty("timelinePath"))
.filter(item => !start || item.startTime > start)
.filter(item => !end || item.endTime < end)
.map((item, index) => {
const { timelinePath } = item;
const coordinates = timelinePath
.map(({ point }) => {
const [lat, long] = point.split(",").map(coord => coord.trim());
return `${long},${lat}`.replaceAll("°", "");
})
.join(" ");
return `
<Placemark>
<name>${index + 1}</name>
<styleUrl>#lineStyle</styleUrl>
<LineString>
<tessellate>1</tessellate>
<coordinates>
${coordinates}
</coordinates>
</LineString>
</Placemark>`;
});
return `
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<Style id="lineStyle">
<LineStyle>
<color>ffd18802</color>
<width>4</width>
</LineStyle>
</Style>
${placemarks.join("")}
</Document>
</kml>`;
}
import data from './Timeline.json' assert { type: "json" };
const kmlOutput = convertTimelineToKML(data, "2024-12-24", "2025-01-15");
console.log(kmlOutput);
- Modify this script as needed, adjusting the start date (“2024–12–24” here) and end date (“2025–01–15” here) (use null for open-ended dates), as well as the path colour (ffd18802 here) and width (4 here). Remember that the colour is in the AABBGGRR format.
- After saving the changes run node ./Timeline.mjs > timeline.kml in the terminal to generate a KML file.
- It’s now time to showcase your journey! To do this, navigate to My Maps and create a new map by importing the resulting timeline.kml file into the new layer.
That’s it, enjoy!