Skip to content

Instantly share code, notes, and snippets.

@postspectacular
Last active August 27, 2023 11:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save postspectacular/f69a3b0899ec4212fa59c3410536ee85 to your computer and use it in GitHub Desktop.
Save postspectacular/f69a3b0899ec4212fa59c3410536ee85 to your computer and use it in GitHub Desktop.
#HowToThing #007 — Converting Google Maps Saved Places (exported via Google Takeout) to KML
import { readJSON, writeText } from "@thi.ng/file-io";
import { XML_PROC, serialize } from "@thi.ng/hiccup";
// source path of the Google Takeout (GT) places
const path = "/Downloads/Takeout/Maps (your places)/Saved Places.json";
// load GT places
const places = readJSON(path).features;
// FYI: partial structure of a GT place
interface Place {
geometry: { coordinates: number[] };
properties: {
Title: string;
Published: string; // ISO8601 datetime
Location?: {
Address?: string;
"Business Name"?: string;
};
};
}
// convert a single GT place into a KML placemark in thi.ng/hiccup format
// (aka S-expression-like, tagged, nested, plain JS arrays)
// see thi.ng/hiccup readme for full details & options...
const convertPlace = ({ geometry, properties }: Place) => [
"Placemark",
["Point", ["coordinates", geometry.coordinates.join(",")]],
["name", properties.Title],
["TimeStamp", ["when", properties.Published]],
// conditionally include address
// null values will be skipped later during serialization
properties.Location?.Address
? ["address", {}, properties.Location?.Address]
: null,
];
// define a full KML document in hiccup format
const kmlDoc = [
// XML processing instruction/header
XML_PROC,
[
"kml",
{ xmlns: "http://www.opengis.net/kml/2.2" },
[
"Document",
["name", "Google Takeout"],
["visibility", 1],
...places.map(convertPlace),
],
],
];
// output as UTF-8 file
writeText(
// write result in same place but with `.kml` extension
path.replace(/\.json$/, ".kml"),
// serialize hiccup document
// the `true` arg ensures, XML entities (e.g. &) are being auto-encoded
serialize(kmlDoc, null, true)
);
// resulting KML:
// <?xml version="1.0" encoding="UTF-8"?>
// <kml xmlns="http://www.opengis.net/kml/2.2">
// <Document>
// <name>Google Takeout</name>
// <visibility>1</visibility>
// <Placemark>
// <Point>
// <coordinates>9.4286111,47.2866667</coordinates>
// </Point>
// <name>Talstation Luftseilbahn Wasserauen-Ebenalp AG</name>
// <TimeStamp>
// <when>2017-09-01T20:56:41Z</when>
// </TimeStamp>
// <address>Schwendetalstrasse 82, 9057 Wasserauen, Switzerland</address>
// </Placemark>
// ...
// </Document>
// </kml>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment