Skip to content
QGIS
Guide

What Is a KML File? Open, Edit and Convert KML and KMZ

Published

A KML file is an XML text file that stores places on a map: points, lines, polygons and image overlays, each with a name, a description and a style. KML stands for Keyhole Markup Language, an OGC standard, and its coordinates are always longitude and latitude in WGS 84. A KMZ is the same file zipped.

Google Earth, QGIS and most GIS software open both. I opened, edited and converted three public files on 11 October 2026 in QGIS 3.44.15: the City of Nice's KMZ of 193 parks and gardens, the US Geological Survey's live earthquake KML, and a USGS ShakeMap KMZ with an image overlay. Opening was the easy part; the trouble started when I saved.

Left, an aerial photo of the old town of Nice with the Parc du Château filled in yellow and other city parks in pale green. Right, the QGIS feature form of the Parc du Château, where the description field shows an HTML table with NOM, NOM_ANCIEN, TYPE, SOUS_TYPE, IDENT and NOM_CARTO.
The City of Nice's parks KMZ in QGIS, over IGN aerial imagery. The six attributes the city publishes are not columns: they sit in an HTML table inside each park's description.

The short answer

Opening a KML takes one drag and drop in QGIS or one click in Google Earth. Saving and converting are where data goes missing, so the right column says what each route did to the test files.

You want toDo thisWhat happened on the test files
See the file on a globeGoogle Earth on the web, Earth Pro or the mobile appGoogle's own limit: 10,000 features in an editable project
Open it in QGISDrag it onto the map, pick the layers, Add Layers193 parks, 13 fields, the city's colours kept
Read its attributesLook inside description, not only the columnsSix city fields were hidden in HTML
Edit itSave as GeoPackage first, export KML at the endEditing the KMZ in place left a 134-byte empty file
Convert itOur browser converters, QGIS Export or ogr2ogr193 of 193 features every time, but not every field
Do all of it at onceOne sentence to AI Agent in QGISGeoPackage in Lambert-93 in under 30 seconds

What is a KML file? KML meaning in one paragraph

KML means Keyhole Markup Language. Keyhole, Inc. wrote it for a product called Keyhole Earth Viewer, the Library of Congress format record notes, and it became the format Google Earth reads and saves. The Open Geospatial Consortium approved it as an open standard in April 2008, as Route Fifty reported that month, and KML 2.3 was approved in 2015. The OGC page lists both versions.

A KML file is plain XML, so you can read it in any text editor. Every coordinate is a tuple of longitude, latitude and an optional altitude, in that order, separated by commas, with a space between tuples. The OGC text defines the system as WGS 84 with a longitude, latitude axis order, and Google's KML reference gives altitude in metres. GDAL's KML driver page puts it in one line: "KML by specification uses only a single projection, EPSG:4326."

That has a practical consequence. A KML never needs a CRS fixed on import, but it is in degrees, so an area or a length measured on it is meaningless until you reproject. What a CRS is covers that step.

KML vs KMZ: how to tell them apart

A KMZ is a zip archive with one main KML inside, plus any icons, images or models that KML points to. Google's KMZ page names the main file doc.kml by default. The Library of Congress adds that Google Earth reads the first .kml entry whatever its name, and the ShakeMap file I tested calls its main file shakemap.kml. QGIS and our converters both read it.

KMLKMZ
What it isOne XML text fileA zip holding a KML, plus images
Opens in a text editorYesNo, unzip it first
Can carry icons and image overlaysOnly as linksYes, inside the archive
First bytes of the file<?xmlPK, the zip signature
Size, measuredUSGS feed: 363,602 bytesSame 358 earthquakes zipped: 28,250 bytes

To see what a KMZ holds, rename it to .zip and double-click it, or list it from a terminal. This is the ShakeMap KMZ for the magnitude 7.7 earthquake in Panama on 9 October 2026:

$ unzip -l shakemap.kmz
  Length      Name
   129092     ii_overlay.png
      678     triangle.png
     1225     circle.png
     7733     intensity_legend.png
  2010531     shakemap.kml

What is inside a KML file

Here is one park from the City of Nice's KMZ, trimmed. The description really is a whole HTML page, and the polygon has 433 coordinate tuples:

<Placemark id="ID_00141">
  <name>Chateau (Parc du)</name>
  <description><![CDATA[<html> ... <td>TYPE</td>
    <td>Parc, Jardin et Square</td> ... </html>]]></description>
  <styleUrl>#PolyStyle00</styleUrl>
  <MultiGeometry>
    <Polygon>
      <extrude>0</extrude><altitudeMode>clampToGround</altitudeMode>
      <outerBoundaryIs><LinearRing><coordinates>
        7.28112662500007,43.69936091800008,0 7.281111207000038,43.69935487300006,0 ...
      </coordinates></LinearRing></outerBoundaryIs>
    </Polygon>
  </MultiGeometry>
</Placemark>

Six elements do almost all the work in the files you'll meet. The right column is what I counted in the three test files.

ElementWhat it holdsIn my test files
Document, FolderGroups of features, nested like directoriesUSGS feed: 6 folders, one per magnitude
PlacemarkOne feature: name, description, geometryNice: 193, USGS: 358, ShakeMap: 1,040
Style, styleUrlColours, line widths, iconsNice: 1 shared style, ShakeMap: 607
ExtendedDataAttribute fields, as Data pairs or a SchemaData blockNice: none, attributes in the HTML instead
GroundOverlayAn image draped on a latitude and longitude boxShakeMap: 1, a 732 × 684 px intensity map
NetworkLinkA link to another KML on the web, which can refresh on a timerUSGS link file: 2, ShakeMap: 1

Altitude has its own element. altitudeMode is clampToGround by default, which ignores the altitude, and relativeToGround or absolute use it, according to Google's reference. Google adds clampToSeaFloor and relativeToSeaFloor under its own gx: prefix.

How to open a KML file

In Google Earth, on the web or with Earth Pro

On Google Earth for the web, sign in, click New, then Import file to project, then Upload from device. Google caps that route at 10,000 features or about 250,000 vertices per project, and a larger file comes in as a read-only data layer. To skip the sign-in and the cap, click Open local KML editor on the home screen, then Open KML from device. Changes there are lost unless you save or download them.

Google Earth Pro is the free desktop version and opens both formats from its File menu. I didn't time either for this post, because the test session had no Google account. The steps above are Google's own.

In QGIS

Drag the file onto the map

Or use Layer > Add Layer > Add Vector Layer…, pick the .kml or .kmz and click Add. Both go through GDAL's LIBKML driver.

Pick the folders you want

QGIS opens a Select Items to Add dialog. Each KML folder is listed as its own layer with its geometry and feature count. It appeared even for the Nice KMZ, which has a single folder.

Click Add Layers

The layers land in EPSG:4326, and QGIS draws them over a project in any CRS.

With a file built in folders, the dialog is where you choose what to load. The USGS feed is the clearest case:

The QGIS Select Items to Add dialog for the USGS earthquake KML, listing Magnitude 2 to Magnitude 7 as PointZ layers with 78, 62, 176, 38, 3 and 1 features, and an empty seventh item marked Unknown (0).
The USGS past-week feed in QGIS: six magnitude folders become six layers. The seventh item is the document itself, with no features. Leave it unticked.

QGIS keeps the colours. It gave the Nice layer the Embedded Symbols renderer, so the parks came in with the city's pale green fill rather than a random colour. The QGIS manual describes that renderer as the one that displays "the 'native' symbology of a provided datasource", mostly KML and TAB files.

To see the parks against something, adding a basemap puts imagery under them in a minute. If what belongs under your KML is a scanned plan, georeferencing an image in QGIS gives the scan coordinates first.

In a text editor, or on a phone

A .kml opens in any text editor, which is the fastest way to see whether it holds data or only a link (more on that below). A .kmz has to be unzipped first.

On a phone, Google's import page says Google Earth for the web and for mobile "primarily supports KML, KMZ, GeoJSON, and Shapefile (.zip) for direct import". I didn't test the Android or iOS apps.

Where the attributes went: the HTML description trap

The City of Nice's KMZ carries six attributes per park, and none of them is a column in QGIS. The attribute table has 13 fields, every one of them KML plumbing: id, Name, description, timestamp, begin, end, altitudeMode, tessellate, extrude, visibility, drawOrder, icon and snippet. The park's type, subtype, identifier and map label sit inside an HTML table in description, 1,133 characters of it for the first park.

The file looks machine-exported: it ships an XSL stylesheet, and every description is the same generated table. You can't filter, style or join on a field that only exists inside HTML, and nothing in the layer tells you it's there. Three ways out, in the order I'd try them:

  1. Check the portal for another format. Nice publishes the same 193 parks as GeoJSON, CSV and Shapefile, with the fields as real columns. Take that one and skip the KMZ.
  2. Read them in the form. In Layer Properties > Attributes Form, set the description widget to Text Edit with Multiline and HTML ticked, as in the figure at the top. That's for looking, not for analysis.
  3. Pull them out with the field calculator. Add a text field and fill it with an expression like the one below. It filled TYPE for 193 of 193 parks.
regexp_substr("description", '<td>TYPE</td>\\s*<td>([^<]*)</td>')

How to edit a KML file in QGIS and save it back

Don't edit a KMZ in place. I opened a copy of Nice's equipment KMZ (914 points, 46,694 bytes), started editing, renamed one point and saved. QGIS reported success. The file on disk was 134 bytes, a zip holding one empty layers/ folder and no features, and it was still 134 bytes after I closed QGIS. GDAL logged layers/ already exists in ZIP file.

I ran it four times on two KMZ files, including once in standalone PyQGIS with the same commit call the Save Layer Edits button makes, and lost the file every time. A plain .kml survived the same edit: all 38 features of the layer I touched were still there. But QGIS rewrote the whole file, from 363,602 to 445,659 bytes, so treat that as a new file too.

The safe route takes four steps:

Save a working copy

Right-click the layer, Export > Save Features As…, format GeoPackage, or ask AI Agent to do it as in the run below. Edit that copy, never the KMZ.

Edit and check validity

Edit as usual. Before export, run Vector > Geometry Tools > Check Validity with the GEOS method and fix what it flags. The two Nice polygons the KMZ export refused, below, both fail GEOS's check.

Export to KML

Export > Save Features As…, format Keyhole Markup Language [KML]. Under the data source options, set NameField to the column that should label each placemark.

Zip it if you need a KMZ

Use the KML to KMZ converter, or ogr2ogr -f LIBKML from the GeoPackage (command in the next section).

Here is what came out when I exported Nice's parks back to KML. All 193 placemarks, with NOM_CARTO as the label and all 37 accented names intact. The fields went into ExtendedData as a SchemaData block, which QGIS and Google Earth both read, and the original Name and id columns came back as Name2 and id2 beside KML's own.

The styling did not survive. With Feature symbology selected, QGIS wrote each park's grey outline and switched the fill off, so the beige fill was gone. With no symbology, every polygon got a red outline. If colours matter, set them in Google Earth at the end.

The KMZ route through GDAL's LIBKML driver stopped short: 191 of 193 parks. The two polygons that fail the validity check, the Promenade Verany and the Grand Parc de la Plaine du Var, were refused with Cannot translate feature. Fix them before you export.

How to convert KML and KMZ: Shapefile, GeoJSON, CSV, GPX

Every route out of KML I tried kept every feature: 193 of 193 parks, 358 of 358 earthquakes. What changes from one route to the next is which fields, folders and styles survive. There are three routes: a browser converter, QGIS's Save Features As…, and ogr2ogr on the command line.

Free browser converters

We build these converters. They run in your browser, the file never leaves your machine, and the limit is 50 MB. I ran their code on the same test files and reopened every output in QGIS or with GDAL:

ConversionToolResultWhat changed
KMZ to ShapefileKMZ to Shapefile, KML to Shapefile193 of 193description cut to 254 characters and renamed descriptio, the DBF limits
KMZ to CSVKMZ to CSV, KML to CSV193 rowsPolygons in a wkt column; points get longitude and latitude
KML to GeoJSONKML to GeoJSON358 of 358Six folders merged into one layer, with a folder field
KML to GPXKML to GPX, KMZ to GPX358 waypointsFolder name dropped: GPX has no field for it
KML to KMZKML to KMZ358, 363,602 to 28,250 bytesStyles not carried over
KMZ to KMLKMZ to KML193 of 193Icons and images inside the KMZ dropped, with a warning
CSV to KML or KMZCSV to KML, CSV to KMZ914 rows to 914 placemarksKMZ of 43,431 bytes

The reverse directions exist too: Shapefile to KML and GPX to KML, the second being the route Google suggests for a GPX track it won't import. They don't follow network links, and they don't touch HTML descriptions: the Nice attributes come out as one long description text. The whole set is on the free GIS tools page.

QGIS Export

Right-click the layer, Export > Save Features As…, and pick the format. For a CSV, set the GEOMETRY layer option to AS_WKT so polygons aren't dropped. QGIS keeps all 13 KML fields, which you'll probably want to delete before sharing.

ogr2ogr, for scripts and folders

ogr2ogr ships with QGIS. These are the commands I ran, with their time on the Nice KMZ:

ogr2ogr -f GPKG nice-parks.gpkg nice-parcs-2026.kmz              # 0.27 s, 193 features
ogr2ogr -f "ESRI Shapefile" nice-parks-shp nice-parcs-2026.kmz    # 0.34 s
ogr2ogr -f CSV nice-parks.csv nice-parcs-2026.kmz -lco GEOMETRY=AS_WKT
ogr2ogr -f GPX quakes-m5.gpx 2.5_week_age.kml "Magnitude 5" -nln waypoints -nlt POINT -dsco GPX_USE_EXTENSIONS=YES
ogr2ogr -f LIBKML nice-parks.kmz nice-parks.gpkg

ogr2ogr keeps each KML folder as its own layer: the USGS feed became a GeoPackage of 7 layers in 0.71 seconds. That's better than our converters when the folders mean something, and worse when you wanted one table. GPX is the fussy one. It refused the earthquakes until I added -nlt POINT and the extensions option, and it takes one folder per run (38 waypoints for magnitude 5). The ogr2ogr command builder writes these lines for you.

My pick: a browser converter for a one-off file you'll hand to someone, ogr2ogr when you'll run it again next month, and QGIS Export when the layer is already open.

One sentence to an AI agent: KMZ to a clean GeoPackage

We build one of these tools, AI Agent, a chat panel inside QGIS that runs the steps in the project you have open. This section is about our own tool.

The Nice file needs three things at once: the hidden fields pulled out, a projected CRS for measuring, and a format you can edit safely. In a QGIS project with only an IGN orthophoto loaded, I typed one sentence (the folder path is shortened here):

Load the KMZ at …/nice-parcs-2026.kmz, turn the TYPE, SOUS_TYPE and IDENT values hidden in each park's HTML description into real fields, switch the project to Lambert-93 and save the parks as a GeoPackage next to the KMZ.

The second run, in a new chat, finished in under 30 seconds. The first had written the GeoPackage 20 seconds after I pressed Enter. Both times it loaded the 193 parks, read all six fields out of the HTML (not only the three I named), set the project and the saved layer to Lambert-93 (EPSG:2154), and left the KMZ untouched.

I checked the result against the GeoJSON the city publishes: IDENT, TYPE and SOUS_TYPE match for 193 of 193 parks. With the fields free, a count by type is one click: 186 parks, gardens and squares, and 7 natural areas.

QGIS with the parks of central Nice in beige over an IGN aerial photo, the Layers panel showing Nice parks 2026, and the AI Agent panel reporting 193 parks with TYPE, SOUS_TYPE and IDENT filled, Lambert-93 and the saved nice-parcs-2026.gpkg. The status bar reads EPSG:2154.
The run beside its result: 193 parks with real fields, saved as a GeoPackage in Lambert-93. The original KMZ was not touched.

The output is an ordinary GeoPackage, so you can edit it without the KMZ risk above and export a fresh KML when you're done. For a file whose fields are already columns, QGIS's own export dialog is just as quick.

Try it free in QGIS, no card needed

Common problems with KML and KMZ files

The KMZ or KML opens empty

The file most likely holds a link, not data. The USGS "past week" network link file is 889 bytes: two NetworkLink elements and no placemark, with an instruction to refresh the first link every 60 seconds. Google Earth follows links like these. QGIS showed one layer with 0 features, and our converter said it found no placemarks.

Open the file in a text editor, copy the URL inside <href>, download that and open it instead. For USGS, that's the 363,602-byte feed with 358 earthquakes. Google My Maps produces the same trap: its export dialog has an option to "Keep data up to date with network link KML (only usable online)", and a user who ticked it found only a URL in the file. Untick it to get the data.

Image overlays don't show in QGIS

A GroundOverlay is an image draped on a box of latitudes and longitudes. QGIS reads the vector part only: in the ShakeMap KMZ, it showed the overlay as an empty rectangle with an icon field reading ii_overlay.png. GDAL's raster side didn't recognise the KMZ either.

The fix takes one command. Unzip the KMZ, read the north, south, east and west values of the overlay's LatLonBox, and give them to gdal_translate in west, north, east, south order:

gdal_translate -a_srs EPSG:4326 -a_ullr -84.5333 11.1833 -76.6975 3.9256 ii_overlay.png ii_overlay.tif

Then add the GeoTIFF to the project. Drag the slider to compare the KMZ as QGIS opened it with the overlay put back:

Two QGIS views of the same ShakeMap. On one, only the contour lines and the empty overlay rectangle. On the other, the shaking intensity image over Panama, cyan on the coasts to red near the epicentre, with the same contours on top. (after)
Two QGIS views of the same ShakeMap. On one, only the contour lines and the empty overlay rectangle. On the other, the shaking intensity image over Panama, cyan on the coasts to red near the epicentre, with the same contours on top. (before)
KMZ as QGIS opens itOverlay restored
Drag to compare
USGS ShakeMap of the magnitude 7.7 earthquake in Panama, 9 October 2026

The GeoTIFF took 0.06 seconds to make and lines up with the contours from the same KMZ. Our converters drop overlay images and icons too, and say so with a warning.

3D coordinates and altitude modes

QGIS reads KML with a Z value, so the Nice parks come in as MultiPolygonZ and the earthquakes as PointZ, with the altitudeMode written into a field. That Z travels into a Shapefile or a GeoPackage, where it adds nothing when every altitude is 0 and can trip up software that expects 2D. Add -dim XY to ogr2ogr (the Nice parks came out as plain Polygon, 193 of 193), or run Drop M/Z Values in QGIS. Our Shapefile converter writes 2D geometry.

Google My Maps exports

My Maps exports KML or KMZ from its menu, and many people import KML into it, within limits. Google's import page caps unzipped KML and KMZ at 5 MB, warns against files with more than 2,000 rows, and lists what may not import: folders, image and screen overlays, time-based elements, tours, 3D models, MultiGeometries and HTML in balloons. The Nice KMZ hits three of those. A map can have up to 10 layers.

Very large files

KML is wordy. The USGS feed shrank from 363,602 bytes to 28,250 once zipped, and Nice's 976,116-byte doc.kml travels in a 203,777-byte KMZ. Google Earth's project import stops at 10,000 features, My Maps at 5 MB, our converters at 50 MB. QGIS and ogr2ogr have no such cap, so for a big file, convert it to a GeoPackage once with ogr2ogr and work from that.

Accents and encoding

KML is XML, and the Nice file declares UTF-8 on its first line. Accents came through every route I tried: 37 accented park names like "Camin de l'Ariéta" survived QGIS's KML export and the AI Agent GeoPackage. Shapefile is the weak link. ogr2ogr wrote no .cpg file and a DBF in ISO-8859-1. QGIS still read the accents, because the DBF header names its code page, but other software may guess wrong. Our Shapefile converter writes UTF-8 and a .cpg that says so.

What to remember

  • A KML file is XML map data in WGS 84 longitude and latitude; a KMZ is a zip holding a KML and its images. Rename a KMZ to .zip to look inside.
  • QGIS opens both by drag and drop and turns each folder into a layer. Check description before you trust the attribute table: Nice's six fields were only there.
  • Never save edits to a KMZ in place: in QGIS 3.44.15 it left a 134-byte empty file. Save as GeoPackage, edit, export to KML at the end.
  • Every conversion out of KML kept every feature. Shapefile cuts long text at 254 characters, GPX drops folder names, and styles rarely survive a round trip.
  • A KML that opens empty usually holds a NetworkLink, and an overlay that won't show is a GroundOverlay you can georeference in one command.

Questions people ask

What does KML stand for?

Keyhole Markup Language, after Keyhole, Inc., the company that wrote it for its Keyhole Earth Viewer. It has been an OGC standard since 2008 and is the format Google Earth reads and saves. The current version, KML 2.3, was approved in 2015.

What is the difference between KML and KMZ?

A KML is one XML text file. A KMZ is a zip archive with a KML inside, usually doc.kml, plus the icons and images it uses. The same 358 earthquakes took 363,602 bytes as KML and 28,250 as KMZ. Rename a KMZ to .zip to see its contents.

How do I open a KML file without Google Earth?

Drag it into QGIS, which is free, or open it in a text editor to read it. To get a table, convert it with the KML to CSV converter or the KMZ to CSV converter, which give one row per placemark.

How do I convert KML to Shapefile in QGIS?

Open the KML, right-click the layer, Export > Save Features As…, and choose ESRI Shapefile. Long descriptions get cut at 254 characters and field names at 10. The KML to Shapefile converter does the same in a browser tab.

Why is my KML file empty in QGIS?

Most often it contains a NetworkLink and no placemarks, as Google My Maps' network link export and the USGS link file do. Open it in a text editor, follow the URL inside <href>, and open the file it points to. A KMZ you saved edits into from QGIS can also end up empty.

What coordinate system does KML use?

Always WGS 84, longitude first, then latitude, then an optional altitude in metres (EPSG:4326). Reproject to a metric CRS before you measure areas or distances.

Can I edit a KML in Google Earth instead?

Yes. Google Earth on the web edits a KML imported into a project up to 10,000 features, or opened as a local file with no feature limit, as long as you save or download your changes before you leave. It's the better place to set colours and icons at the end, since QGIS lost the polygon fill in my KML export.

If your KML came from an Overpass Turbo export, downloading OSM data in QGIS shows the faster routes to the same data. For everything else the agent can do once the layer is in QGIS, the QGIS AI hub and the AI Agent guide are the next stops.

Try AI Agent free in QGIS, no card needed