What Are KML and KMZ?
KML — Keyhole Markup Language — is an XML-based file format for expressing geographic annotations and visualizations in two-dimensional maps and three-dimensional Earth browsers. Originally created by Keyhole Inc. for its EarthViewer 3D application, KML became a household name when Google acquired Keyhole in 2004 and integrated KML support into Google Earth. In 2008, the Open Geospatial Consortium (OGC) adopted KML as an international standard (OGC KML 2.2), cementing its place alongside GeoJSON and Shapefile as a cornerstone of geospatial data exchange.
KMZ is a ZIP-compressed archive containing one or more KML files plus any referenced assets — icon images, embedded textures, COLLADA 3D model files. KMZ is the preferred exchange format because it bundles everything into a single portable container and reduces size by 50–80% compared to uncompressed KML with linked external images.
Core KML Elements
KML documents describe geographic features using a hierarchy of XML elements.
Placemarks
The fundamental annotation unit — a location with geometry and optional description:
<?xml version="1.0" encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2">
<Document>
<name>My Locations</name>
<Placemark>
<name>Eiffel Tower</name>
<description>Built for the 1889 World's Fair in Paris.</description>
<Point>
<coordinates>2.2945,48.8584,324</coordinates>
</Point>
</Placemark>
</Document>
</kml>
Coordinates are specified as longitude,latitude,altitude — note the order. Longitude first. Altitude is optional and in meters above the reference surface defined by altitudeMode.
Geometry Types
| Type | KML Element | Use Case |
|---|---|---|
| Point | <Point> |
Location markers, pins, waypoints |
| Line | <LineString> |
Paths, routes, pipelines, roads |
| Polygon | <Polygon> |
Areas, administrative boundaries, zones |
| Multi-geometry | <MultiGeometry> |
Compound shapes combining the above |
| Model | <Model> |
3D objects referencing COLLADA .dae files |
Altitude Modes
<Point>
<altitudeMode>relativeToGround</altitudeMode>
<coordinates>-73.985,40.748,443</coordinates>
</Point>
| Mode | Behavior |
|---|---|
clampToGround |
Feature pressed flat to terrain surface (default) |
relativeToGround |
Altitude above the local terrain at that lat/lon |
absolute |
Altitude above WGS84 ellipsoid sea level |
clampToSeaFloor |
Clamped to ocean floor (gx: extension) |
Styles and Icons
KML separates geometry from presentation using named Style elements:
<Style id="blueMarker">
<IconStyle>
<color>ffff0000</color>
<scale>1.3</scale>
<Icon>
<href>http://maps.google.com/mapfiles/kml/paddle/blu-circle.png</href>
</Icon>
</IconStyle>
<LabelStyle>
<color>ffffffff</color>
<scale>0.9</scale>
</LabelStyle>
<LineStyle>
<color>ffff0000</color>
<width>4</width>
</LineStyle>
<PolyStyle>
<color>7fff0000</color>
<fill>1</fill>
<outline>1</outline>
</PolyStyle>
</Style>
<Placemark>
<styleUrl>#blueMarker</styleUrl>
<Point><coordinates>2.2945,48.8584,0</coordinates></Point>
</Placemark>
Colors in KML use AABBGGRR order (alpha, blue, green, red) — the inverse of web hexadecimal RGB. A fully opaque red is ff0000ff; a 50%-transparent red is 7f0000ff. The alpha channel ff = fully opaque, 00 = fully transparent.
StyleMap elements allow separate styles for normal and highlighted states, enabling hover effects in Google Earth.
NetworkLink: Dynamic Data Feeds
NetworkLink allows KML documents to load remote KML/KMZ data on demand or on a timer:
<NetworkLink>
<name>Live Earthquake Feed</name>
<Link>
<href>https://earthquake.usgs.gov/earthquakes/feed/v1.0/summary/all_hour.kml</href>
<refreshMode>onInterval</refreshMode>
<refreshInterval>300</refreshInterval>
</Link>
</NetworkLink>
This enables real-time data overlays — earthquake alerts, flight tracking positions, weather radar — all pulling from a URL that regenerates every N seconds. NetworkLink is the mechanism behind Google Earth's live data layers: traffic, weather, borders, and community pins. A single KML file can chain multiple NetworkLinks, each pointing to different servers with different refresh rates.
viewRefreshMode combined with viewRefreshTime triggers reloads whenever the camera view changes — critical for large datasets loaded in spatial tiles, where you only request data for the current viewport.
GroundOverlay: Raster Image Draping
Draping raster images (satellite imagery, custom maps, heatmaps, historical maps) over the 3D terrain:
<GroundOverlay>
<name>Flood Extent Map — 2024-03-15</name>
<color>aaffffff</color>
<Icon>
<href>flood_extent.png</href>
<viewBoundScale>0.75</viewBoundScale>
</Icon>
<LatLonBox>
<north>40.850</north>
<south>40.700</south>
<east>-73.900</east>
<west>-74.050</west>
<rotation>0</rotation>
</LatLonBox>
</GroundOverlay>
The <color> element controls global opacity (aa = ~67% transparent). GroundOverlay is used heavily in emergency management to drape aerial survey imagery and damage assessment maps over Google Earth for situational awareness during disasters.
Folders, Playlists, and Tours
Folder elements organize features hierarchically — exactly like a file system. Google Earth displays these as collapsible layers in the Places panel.
gx:Tour elements (from the Google Extensions namespace) define animated fly-through sequences:
<gx:Tour>
<name>European Capitals Tour</name>
<gx:Playlist>
<gx:FlyTo>
<gx:duration>4.0</gx:duration>
<LookAt>
<longitude>2.3522</longitude>
<latitude>48.8566</latitude>
<altitude>1500</altitude>
<range>3000</range>
<tilt>55</tilt>
<heading>0</heading>
</LookAt>
</gx:FlyTo>
<gx:Wait><gx:duration>2.0</gx:duration></gx:Wait>
</gx:Playlist>
</gx:Tour>
The gx: namespace prefix indicates Google Extension elements — they are valid in Google Earth but may be silently ignored by strict OGC implementations. Tours are used extensively in journalism, education, and real estate visualization.
Creating and Converting KML
Creating KML with Python using simplekml:
import simplekml
kml = simplekml.Kml()
# Add a point marker
pnt = kml.newpoint(name="Colosseum, Rome")
pnt.coords = [(12.4924, 41.8902, 0)]
pnt.description = "Built between 70–80 AD. Capacity: ~50,000 spectators."
pnt.style.iconstyle.icon.href = (
"http://maps.google.com/mapfiles/kml/paddle/grn-circle.png"
)
# Add a polygon
pol = kml.newpolygon(name="Approximate footprint")
pol.outerboundaryis = [(12.4915, 41.8896),
(12.4935, 41.8896),
(12.4935, 41.8910),
(12.4915, 41.8910),
(12.4915, 41.8896)]
pol.style.polystyle.color = "7f00ff00" # 50% transparent green
kml.save("colosseum.kml")
kml.savekmz("colosseum.kmz") # compressed version
Converting between formats with ogr2ogr (GDAL):
# KML → GeoJSON
ogr2ogr -f GeoJSON output.geojson input.kml
# KML → ESRI Shapefile
ogr2ogr -f "ESRI Shapefile" output_folder/ input.kml
# GeoJSON → KML
ogr2ogr -f KML output.kml input.geojson
# Simplify geometry (reduce vertex count, tolerance in map units)
ogr2ogr -f KML simplified.kml input.kml -simplify 0.0001
GDAL's ogr2ogr is the universal Swiss Army knife for vector format conversion. GDAL 3.x includes KML read/write support enabled by default, recognizing both .kml and .kmz extensions automatically.
KML vs GeoJSON
| Feature | KML | GeoJSON |
|---|---|---|
| Syntax | XML | JSON |
| Built-in styling | Yes (IconStyle, LineStyle, PolyStyle) | No (requires external style spec) |
| 3D support | Full (altitude, extrusion, models) | Limited (Z coordinate only) |
| Google Earth native | Yes | Via conversion |
| Leaflet / MapboxGL | Plugin needed | Native |
| OGC standard | Yes (KML 2.2, 2008) | Yes (RFC 7946, 2016) |
| Typical compression | KMZ (ZIP) | FlatGeobuf / GeoPackage |
| Streaming/tiling | NetworkLink + Region LOD | Vector tiles (MVT) |
GeoJSON has largely displaced KML for web mapping applications — it integrates natively with JavaScript environments, REST APIs, and modern map libraries. KML remains dominant for Google Earth desktop workflows, aerial survey deliverables, FAA airspace filings, and any scenario requiring rich 3D visualization, tour animations, or timed dynamic overlays.
Validating KML
KML 2.2 has a formal XML Schema (XSD) downloadable from OGC:
xmllint --schema ogckml22.xsd --noout yourfile.kml
Common KML errors include:
- Coordinate order mistake: writing
latitude,longitudeinstead oflongitude,latitude— places Paris in the Atlantic Ocean - Unclosed polygon ring: outer boundary must repeat the first coordinate as the last coordinate
- Invalid altitudeMode: typos like
relativeToTerraininstead ofrelativeToGround - Missing namespace declaration:
xmlns="http://www.opengis.net/kml/2.2"on the root<kml>element
Google Earth is forgiving of many validation errors; strict OGC implementations reject them outright.
Real-World Applications
- Emergency management: FEMA publishes evacuation zone KML files during hurricanes and wildfires; emergency managers load them into Google Earth for field team briefings
- Aviation: FAA Temporary Flight Restrictions (TFRs) and drone flight zones are distributed as KML by the FAA's UAS Data Delivery System
- Real estate: property boundary overlays and development zone maps for site due diligence and investment analysis
- Conservation: WWF, NPS, and IUCN distribute protected area boundary datasets as KMZ for field teams without GIS expertise
- Urban planning: city planning departments publish zoning maps, transit corridors, and infrastructure overlays as KML for public consultation
- Precision agriculture: field boundary maps, soil sampling grids, and variable-rate application zones distributed to farm equipment via KML
Performance note: Google Earth begins degrading at approximately 10,000 simultaneously visible features. For large datasets, use NetworkLink combined with Region elements and Level of Detail (LOD) settings to load data progressively as the user zooms in.
Related conversions
Frequent conversions across the catalogue: