KML to CSV Converter
A KML to CSV converter turns Google Earth placemarks into spreadsheet rows. This one reads ExtendedData into real columns, recovers the fields Google My Maps hides inside an HTML description, keeps the folder path a person built by hand, and writes a line or polygon's full shape as WKT rather than shrinking it to one point. Nothing is uploaded.
Want to filter, join or chart the result? Open the app
Where your columns went
The complaint people arrive with is always the same: the map has all the data, the CSV has a name and a coordinate. The reason is that KML has two places to put a field and only one of them is structured.
The structured one is <ExtendedData>, a list of <Data name="staff"><value>14</value></Data> pairs. Every field has a name, so it becomes a column with no guesswork.
The unstructured one is <description>, which is free HTML. Google My Maps writes its exports this way: your original spreadsheet columns come back as a two-column HTML table inside the description, one row per field. A reader that treats the description as one value gives you a single column of <table><tr><td> markup, which is technically correct and completely useless.
So this converter looks for that pattern. When a placemark has no ExtendedData and its description contains paired table cells, the pairs are read as key and value, added as columns, and the markup is dropped. The warning tells you how many placemarks needed it, so you know the file came out of My Maps rather than something that writes proper ExtendedData.
A worked example
A foldered document with two placemarks, one a pin and one a route:
<Folder><name>Europe</name>
<Placemark>
<name>London Bridge</name>
<ExtendedData>
<Data name="store_code"><value>01730</value></Data>
<Data name="staff"><value>14</value></Data>
</ExtendedData>
<Point><coordinates>-0.0877,51.5079,8</coordinates></Point>
</Placemark>
</Folder>
<Folder><name>Routes</name>
<Placemark>
<name>Delivery</name>
<LineString><coordinates>
-73.9840,40.7549,12
-73.9812,40.7580,11
</coordinates></LineString>
</Placemark>
</Folder>
comes back as:
name,folder,geometry,latitude,longitude,elevation,wkt,store_code,staff
London Bridge,Europe,Point,51.5079,-0.0877,8,,01730,14
Delivery,Routes,LineString,40.7549,-73.984,12,"LINESTRING (-73.984 40.7549, -73.9812 40.758)",,
Three things worth pointing at. The store code kept its leading zero, because every value comes out of the XML as text and nothing here turns a digit string into a number. The folder names became a column. And the route's second vertex is not lost: the whole line is in wkt, ready for ST_GeomFromText or GeoPandas, while latitude and longitude hold its start point so the row still plots somewhere sensible.
Columns that are empty in every row are dropped. A file of nothing but pins has no wkt column at all.
Namespaces, whitespace and .kmz
Real KML is messier than the specification. Files in the wild mix bare tags, kml: prefixed tags and the gx: Google extensions, sometimes in the same document. The reader matches on local names with the prefix thrown away, so it does not matter which spelling your exporter chose.
Whitespace inside <coordinates> is treated loosely for the same reason. The specification says tuples are separated by whitespace and the numbers inside a tuple by commas with no spaces, but Google Earth itself writes newlines and tabs between tuples, and plenty of tools put a space after the comma. Any run of whitespace separates tuples here, and a tuple that does not parse as two or three numbers is skipped rather than taken as zero.
A .kmz is a zip archive, not XML, so its first bytes are not something an XML parser can do anything with. Rather than reporting a malformed document, you get a message saying it is a zipped KML and to unzip it first. That is one sentence of difference and about ten minutes of someone's time.
Two elements get their own handling because they appear in GPS exports and break naive readers. <gx:Track> stores each vertex in its own <gx:coord> with space-separated numbers rather than in a coordinates block, and comes out as a LINESTRING. <MultiGeometry> is unwrapped before the geometry types are checked, so a placemark holding a point and a line does not read as having neither.
Questions
My placemarks have data but the CSV only shows a name. Why?
The file probably stores its fields inside the description as an HTML table, which is how Google My Maps exports them. That is markup rather than structured data, so a plain reader gets one column of tags. This converter detects the two-cell table pattern My Maps writes and pulls the key and value pairs out into real columns, then drops the markup. The warning tells you how many placemarks needed that treatment.
Does the folder structure survive?
Yes, as a folder column holding the full path. A placemark two folders deep gets Europe / Retail rather than just Retail, joined with a slash. Folders are usually the categorisation somebody did by hand in Google Earth, so throwing them away loses information that is not anywhere else in the file.
What happens to lines and polygons?
The full shape goes into a wkt column as a LINESTRING or POLYGON literal, and the latitude and longitude columns hold only the first vertex. A geometry column names the type of each row so a mixed file stays readable. Reducing a route to a single point and calling it the location is the common shortcut and it silently deletes the route.
Can it open a .kmz file?
Not directly. A .kmz is a zip archive containing a .kml plus any icons it references. Unzip it, then convert the .kml inside. If you drop a .kmz here you get a message saying exactly that rather than a generic parse failure, because a zip's first bytes are not XML and the reason is worth naming.
Which way round are the coordinates read?
KML stores a coordinate tuple as longitude,latitude,altitude, comma separated. The reader takes them in that order and writes separate latitude, longitude and elevation columns, correctly labelled. Whitespace between tuples is handled loosely because Google Earth itself writes newlines and tabs in there, while the comma order is treated strictly because that is what the format actually specifies.
What about gx:Track and MultiGeometry?
Both are read. A gx:Track keeps each vertex in its own gx:coord element with space-separated values rather than in a coordinates block, so it needs its own path through the reader, and it comes out as a LINESTRING. A MultiGeometry is unwrapped and its first usable geometry is used. Neither is common in hand-made files and both appear in exports from GPS software.
Is the file uploaded?
No. Parsing happens in your browser tab using the browser's own XML parser, with no server round trip, nothing stored between visits and no row cap. Map files often carry customer or site locations, which is a good reason to use a tool that never receives them.
Related
Convert your KML to CSV
No sign-up, no upload, no row cap. ExtendedData as columns, My Maps descriptions unpicked, folders and shapes kept.
Back to the converter