KML y KMZ: la guía definitiva (abrir, convertir, errores)
Alguien te mandó un .kmz de Google Earth y tu GIS lo dibujó en el medio del océano, o los placemarks llegaron sin ningún atributo. KML es el formato XML que Google Earth hizo universal; KMZ es el mismo archivo comprimido, con sus imágenes. Una sola regla explica la mayoría de las fallas en esta página: las <coordinates> se escriben con la longitud primero — lon,lat[,alt], separadas por coma, sin espacios dentro de una tupla — y siempre son grados decimales WGS 84. KML no ofrece otro sistema de coordenadas, así que no hay nada que declarar y nada que arruinar salvo el orden.
Todo lo que hay acá se corrió, no se copió, con dos builds de GDAL, porque GDAL tiene dos drivers de KML que no se comportan igual. En forma local, GDAL 3.13.3 "Iowa City", donde ogrinfo --formats | grep -i kml imprime una sola línea, KML -vector- (rw+v), y grep -c LIBKML imprime 0. Para LIBKML usamos la imagen Docker de OSGeo ghcr.io/osgeo/gdal:ubuntu-full-latest (digest sha256:98086f71…, GDAL 3.14.0dev del 2026/09/10), que tiene los dos; cada oración sobre LIBKML de acá abajo viene de un comando corrido ahí con -if LIBKML. Nada está escrito solo a partir de la documentación de un driver; las afirmaciones sobre el visor se comprobaron cargando los mismos archivos en la página en vivo con un Chromium headless. Todo esto se verificó el 10 de septiembre de 2026.
Qué es KML, y qué agrega KMZ
KML, Keyhole Markup Language, es XML de Keyhole, la empresa que Google compró en 2004 para hacer Google Earth, y el formato siguió al producto: describe qué dibujar y cómo, no un dataset con un esquema. Es un estándar OGC desde 2008, primero 2.2 y después 2.3, con opengis.net/kml/2.2 como valor de xmlns; los archivos más viejos llevan earth.google.com/kml/2.1 o 2.0, y la entrada sobre el namespace en la sección de errores muestra qué hace GDAL con cada uno.
Un archivo mínimo es una raíz <kml>, un <Document>, y un <Placemark> con un <name> y un <Point> que contiene <coordinates>-46.63,-23.55,0</coordinates> — São Paulo, con la longitud primero.
KMZ es ese archivo adentro de un zip: un doc.kml en la raíz y, por convención, una carpeta files/ para los íconos y las imágenes de superposición que el KML referencia por ruta relativa. Corrimos ogr2ogr -f KML out.kml props.geojson sobre un GeoJSON de dos puntos, comprimimos el resultado como doc.kml dentro de out.kmz, y unzip -l out.kmz listó una sola entrada, doc.kml, 1375 bytes. Un KMZ escrito con ogr2ogr -f LIBKML out.kmz props.geojson contiene doc.kml más layers/props.kml, un archivo por capa. Cuando un KMZ es enorme, unzip -l es lo primero para correr: el tamaño casi siempre está en files/.
La estructura que importa
Seis elementos explican casi todo lo que vas a leer, escribir o perder.
Placemark
Una sola entidad: un <name>, un <description> opcional, <styleUrl> y <ExtendedData>, y una geometría — <Point>, <LineString>, <Polygon> o un <MultiGeometry> que envuelve varias. Un MultiGeometry puede mezclar tipos, y GDAL lo lee como una sola entidad: nuestro placemark con un punto y una línea volvió como GEOMETRYCOLLECTION Z (POINT Z (-46.63 -23.55 0),LINESTRING Z (-46.63 -23.55 0,-46.6 -23.5 0)) — legal en KML, GeoJSON y GeoPackage, imposible en un Shapefile.
Folder y Document
Document guarda las cosas compartidas — estilos y esquemas — y Folder agrupa placemarks para la barra lateral de Google Earth; los dos anidan. Los dos drivers de GDAL leen una carpeta como una capa: nuestro <Document> con una carpeta Wells de dos puntos y una carpeta Access roads de una línea dio 1: Wells (3D Point) y 2: Access roads (3D Line String) desde KML, 1: Wells y 2: Access roads desde LIBKML, y ogr2ogr -f GPKG folders.gpkg folders.kml produjo esas mismas dos capas con cualquiera de los dos. Nuestro visor las conserva: 3 entidades · 1 Línea · 2 Punto · 2 carpetas, con Wells y Access roads en el panel de capas y un atributo folder en cada entidad.
Style y StyleMap
Un <Style id="siteNormal"> contiene bloques IconStyle, LineStyle, PolyStyle y BalloonStyle; un placemark lo referencia con <styleUrl>#siteNormal</styleUrl>. Un <StyleMap> empareja dos estilos bajo las claves normal y highlight para el mouse-over. Los colores son aabbggrr — alfa, azul, verde, rojo — por eso un "rojo" en KML se lee ff0000ff. Los estilos no sobreviven ningún viaje por GeoJSON, Shapefile o GeoPackage; la sección de errores tiene los conteos.
ExtendedData y SchemaData
Los atributos viven en <ExtendedData>, en dos dialectos. El simple es una lista de pares <Data name="site_id"><value>42</value></Data>, cadenas sin tipo. El tipado declara un <Schema> en el Document con entradas <SimpleField name="site_id" type="int"/> y llena cada placemark con <SchemaData schemaUrl="#props"><SimpleData name="site_id">42</SimpleData></SchemaData>. GDAL escribe el dialecto tipado; lo que cada driver lee de vuelta está cubierto en la sección de conversión. Nuestro visor lee los dos: los pares Data se cargaron como observation_notes y site_id con los valores Gate locked y 42, y el archivo SchemaData dio los cinco campos, editables.
NetworkLink
Un <NetworkLink> contiene un <Link><href>example.com/layer.kml</href></Link> y le dice a Google Earth que descargue esa URL; no lleva ninguna geometría. Un KML cuyo único contenido es un NetworkLink abrió bajo KML sin ninguna capa, y bajo LIBKML como una sola capa, netlink, con Feature Count: 0; ninguno de los dos descargó nada. Nuestro visor se comporta igual: 0 entidades · 0 campos, y una traza de red después de soltar el archivo mostró pedidos al servidor de tiles del mapa y nada más — el visor no lo descarga. Los datos están en la URL, no en el archivo; descargá el destino y abrí eso.
GroundOverlay
Un <GroundOverlay> cubre un <LatLonBox> de límites <north>, <south>, <east>, <west> con una imagen, con <Icon><href>files/site.png</href></Icon> apuntando adentro del KMZ — un plano de sitio escaneado, una ortofoto de drone. El driver KML lo ignora (nuestro KMZ listó solo la capa Wells); LIBKML lee un POLYGON Z de las esquinas de la caja con un campo icon de files/site.png — la huella, no la imagen. Nuestro visor lo renderiza: 1 entidades · 1 Punto · 1 imágenes superpuestas · 1 carpetas, con el PNG embebido dibujado sobre la caja.
Coordenadas: siempre lon,lat, siempre WGS 84
Un KML no tiene dónde declarar un sistema de coordenadas, así que no existe eso de "un KML en UTM" — solo un KML con los números equivocados adentro. Los dos drivers lo dicen en cada lectura: ogrinfo -al -so sobre cualquier KML imprime GEOGCRS["WGS 84" e ID["EPSG",4326] sean cuales sean los números. Cada "mi KMZ está en el lugar equivocado" es uno de tres errores.
- Orden invertido. São Paulo es
<coordinates>-46.63,-23.55,0</coordinates>;ogrinfo -al sp_ok.kmlimprimióPOINT Z (-46.63 -23.55 0), en Brasil. Escrito-23.55,-46.63,0, el mismo placemark imprimióPOINT Z (-23.55 -46.63 0)con los dos drivers, sin ningún aviso: longitud -23,55, latitud -46,63, el Atlántico Sur, unos 3300 km al este de la Patagonia. Un archivo en un océano o en el continente equivocado tiene los pares al revés; invertilos, no reproyectes nada. - Metros proyectados escritos como grados. Un par UTM para el mismo punto es más o menos
333000,7395000. Al leerlo, los dos drivers lo aceptan en silencio —POINT Z (333000 7395000 0)— yogr2ogr -f GeoJSONlo escribió sin decir nada. Al escribirlo, los controles saltan: un GeoJSON con ese par pasado porogr2ogr -f KMLfalló conERROR 1: Latitude 7395000.000000 is invalid. Valid range is [-90,90].; el escritorLIBKMLdijoERROR 1: Invalid longitude 333000. Decile a GDAL qué son los números y dejá que convierta:ogr2ogr -f KML out.kml in.geojson -s_srs EPSG:31983 -t_srs EPSG:4326produjo<coordinates>-46.636073838011,-23.5467532379101</coordinates>. Un origen que lleva su propio CRS (un Shapefile con.prj, un GeoPackage) no necesita nada de esto. Una latitud que pasa los 90 se comporta igual:-46.63,-93.55se lee en silencio, y despuésERROR 1: Latitude -93.550000 is invalidal escribir. - Grados, minutos y segundos pegados tal cual. Una tupla escrita
46°37'48"W,23°33'0"S,0no es un error para ningún driver, y ese es el problema:KMLdevolvióPOINT EMPTY;LIBKMLdevolvióPOINT (46 23)— los enteros del principio, los hemisferios descartados, un punto en Arabia Saudita. Convertí de DMS a decimal primero; nuestro conversor de coordenadas lo hace y muestra el punto en un mapa.
Una más, más chica pero real: un espacio después de la coma. -46.63, -23.55, 0 son tres tuplas para el driver KML, que imprimió POINT (-46.63 0.0) — la latitud desaparece, el punto queda en el ecuador — mientras que LIBKML lo leyó bien.
Abrir y visualizar un KMZ en línea sin Google Earth
Seis cosas que el visor hace con un KMZ, en el orden en que te las vas a encontrar:
- Soltá el archivo en el visor. Nuestro visor gratuito de KMZ acepta
.kml,.kmzy GeoJSON, descomprime el KMZ en el navegador, y dibuja los placemarks con el conteo en el panel de capas. - Carpetas. Se listan bajo la entrada de capa del archivo, cada una con un toggle de mostrar/ocultar; cada entidad lleva un atributo
folder. - Hacé clic en un placemark. El panel de atributos muestra el nombre, la descripción, el WKT con un botón de copiar, y cada campo
ExtendedDatacomo una fila — tanto paresDatacomoSchemaData; la tabla de atributos lista todas las entidades con un buscador. - Editá un atributo, poné una etiqueta. Los campos son editables; el desplegable
Etiquetaelige el atributo que se dibuja al lado de cada entidad. - Superposiciones y exportación. Un
GroundOverlaycuya imagen está adentro del KMZ se dibuja sobre suLatLonBox; el menú de exportar escribe GeoJSON, KML, KMZ o CSV. - Privacidad. El parseo pasa en tu navegador; el archivo nunca se manda a un servidor. Lo único que el visor no va a hacer es seguir un
NetworkLink.
Desde la terminal, ogrinfo -al -so in.kml lista capas, campos y extensión. Con solo el driver KML, un .kmz no abre directo: ogrinfo out.kmz falla con ERROR 4: 'out.kmz' not recognized as being in a supported file format. Changing the filename to /vsizip/out.kmz may help it to be recognized. — y funciona: ogrinfo -so /vsizip/out.kmz/doc.kml listó 1: props (Point). Con LIBKML, ogrinfo out.kmz abre el archivo tal cual.
Convertir KML a Shapefile, GeoJSON o GeoPackage
Cada comando se corrió contra los archivos de arriba; el driver se nombra porque decide el resultado.
- KML a GeoJSON:
ogr2ogr -f GeoJSON out.geojson in.kml. GeoJSON es una capa por archivo, así que un KML con varias carpetas se convierte a medias: el nuestro escribióWellsenout.geojsony después se frenó conERROR 1: Layer 'Access roads' does not already exist in the output dataset, and cannot be created by the output driver.— un archivo que parece completo y le falta una carpeta. Nombrá la capa como argumento final (ogr2ogr -f GeoJSON wells.geojson in.kml Wells, un archivo por carpeta) o convertí a GeoPackage.Warning 1: Attempt to write Z geometries to layer … that does not support themes inofensivo. - KML o KMZ a GeoPackage:
ogr2ogr -f GPKG out.gpkg in.kmz. ConLIBKMLel.kmzabre directo y cada carpeta se convierte en una capa —1: Wells,2: Access roadsen el nuestro. Nuestra guía de GeoPackage cubre qué te queda del otro lado. - KML a Shapefile:
ogr2ogr -f "ESRI Shapefile" out in.kml. Pasan dos cosas que son culpa del Shapefile: los nombres de campo se cortan a diez caracteres —Descriptionvolvió comoDescriptioconWarning 6: Normalized/laundered field name: 'Description' to 'Descriptio', y conLIBKML, que también lee los campos del esquema,observation_notesvolvió comoobservatio— y un archivo solo admite un tipo de geometría, así que el placemarkMultiGeometryfalló conERROR 6: Geometry type of '3D Geometry Collection' not supported in shapefiles. Las carpetas andan bien, un Shapefile cada una: nos dioWells.shpyAccess roads.shpen una sola corrida. Nuestra guía de Shapefile documenta las dos reglas y la trampa de encoding que viene después. - Shapefile o GeoPackage a KML:
ogr2ogr -f KML out.kml in.shp. El driverKMLconvierte a WGS 84 a partir del.prjpor su cuenta y escribe los atributos comoSchemaData; un campoDateproduceWarning 1: The output driver does not natively support Date type for field visit_datey termina como la cadena2026/09/01. - Escribir un KMZ de verdad:
ogr2ogr -f LIBKML out.kmz in.gpkg. SoloLIBKMLcomprime. El driverKMLacepta un nombre de salida.kmzsin quejarse y escribe XML plano adentro —file test_write.kmzreportóXML 1.0 document, ASCII text— y nuestro visor lo rechazó conError al procesar el archivo. Verifica que sea un KML o KMZ válido.; renombrarlo a.kmllo arregla.
KML vs LIBKML
KML es el driver viejo, sin dependencias, siempre presente; LIBKML está construido sobre la librería libkml de Google, es el que conviene, y falta en muchos builds — el nuestro incluido. Cuando los dos están presentes, GDAL prefiere LIBKML para leer (el contenedor imprimió using driver 'LIBKML' successful sobre un archivo que había escrito KML).
- Atributos al leer. Este es el que pierde datos.
KMLsolo leeNameyDescription: nuestro archivo con cinco camposSchemaDatatipados listóName: String (0.0),Description: String (0.0)y nada más, los paresDatase descartaron de la misma forma, yogr2ogr -f GeoJSONa través de él produjo propiedades{"Name":"S1","Description":""}.LIBKMLleyó el mismo archivo comosite_id: Integer,area_ha: Real,observation_notes: String,visited: Integer(Boolean),visit_date: String, más los campos de mantenimiento que siempre agrega —id,Name,description,timestamp,begin,end,altitudeMode,tessellate,extrude,visibility,drawOrder,icon— y los paresDatacomoString. Con soloKML, cada atributo que convertís se descarta en silencio. - Atributos al escribir. Los dos escriben un
<Schema>másSchemaData.KMLdeclaratype="float"y escribe un booleano como1;LIBKMLdeclaratype="double",type="bool"y escribetrue. Ninguno tiene un tipo fecha: los dos declaranvisit_datecomotype="string". - Carpetas al escribir.
KMLemite un<Folder>por capa;LIBKMLemite<Document>s anidados y ningún<Folder>(grep -c '<Folder' lib_folders_out.kml→0).
Errores, decodificados
Síntoma, causa, solución; QGIS muestra los mismos mensajes de GDAL en su panel de log.
La descripción es una pared de HTML
Síntoma: una descripción se lee como etiquetas — <b>Gate locked</b> since May. <a href="example.com/page">Site record</a> — en una tabla o un CSV. Causa: Google Earth guarda el contenido del globo como HTML adentro de <description><![CDATA[…]]></description>. Los dos drivers de GDAL lo devuelven tal cual como la cadena description (o Description), y un KML escrito de vuelta desde GeoJSON lo lleva escapado, <b>Gate locked</b>. Nuestro visor lo renderiza: el panel de atributos mostró texto en negrita y un link clickeable, y la tabla muestra el placeholder HTML en esa columna. Solución: no hay nada roto; sacá las etiquetas después de exportar si necesitás texto limpio, y poné los valores estructurados en ExtendedData, no en el globo.
Los nombres de campo se cortan a diez caracteres
Síntoma: Description se convierte en Descriptio camino a Shapefile, con Warning 6: Normalized/laundered field name. Causa: el .dbf guarda once bytes por nombre, uno de ellos un terminador. Solución: ninguna adentro de un Shapefile — renombrá los campos a diez caracteres antes de exportar para elegir vos las abreviaturas, o mantené un GeoPackage.
Los estilos desaparecen después de convertir
Síntoma: un KML que en Google Earth tenía íconos rojos y líneas verdes vuelve como chinchetas por defecto. Causa: ninguno de los tres formatos comparados acá tiene un lugar para los estilos de KML. Tomamos un KML con dos <Style> y un <StyleMap> (grep -c '<Style' styled.kml → 3), lo convertimos a GeoJSON y de vuelta, y grep -c '<Style' roundtrip.kml imprimió 0 con los dos drivers. Solución: si el estilo importa, quedate en KML. ogr2ogr -f LIBKML out.kml in.kml conserva los bloques <Style> y cada <styleUrl>, pero aplana un <StyleMap> en un <Style> simple con su par normal; el estado highlight desaparece.
Un KMZ enorme desde Google Earth
Síntoma: un KMZ de unos pocos cientos de placemarks pesa decenas de megabytes. Causa: files/ — Google Earth embebe cada foto asociada a un placemark y cada imagen de superposición a resolución completa. Solución: unzip -l big.kmz y mirá los tamaños; unzip big.kmz doc.kml extrae solo el KML (el nuestro pasó de tres entradas a una, 659 bytes) y zip stripped.kmz doc.kml reconstruye un KMZ sin las imágenes. Guardá el original si tiene superposiciones.
Namespace KML 2.1 vs 2.2
Síntoma: una herramienta se queja de que el archivo "no es KML 2.2", o un validador marca el xmlns. Causa: los archivos de la era Google Earth 4 declaran earth.google.com/kml/2.1 o 2.0 donde el estándar OGC es opengis.net/kml/2.2. A GDAL no le importa: el mismo placemark con los namespaces 2.2, 2.1 y 2.0, y sin ningún xmlns, imprimió POINT Z (-46.63 -23.55 0) con los dos drivers, sin ningún aviso. Solución: cambiá el valor de xmlns al de 2.2 en un editor de texto; todo lo que GDAL escribe ya lo lleva.
Invalid latitude, o un punto fuera del globo
Síntoma: ERROR 1: Latitude 7395000.000000 is invalid. Valid range is [-90,90]. del escritor KML, ERROR 1: Invalid longitude 333000 o ERROR 1: Invalid latitude -93.55 de LIBKML, y una conversión que se frena con Terminating translation prematurely. Causa: metros, o grados fuera de su rango, donde van grados WGS 84. Solución: nunca edites los números a mano; decile a GDAL el sistema de origen con -s_srs y -t_srs EPSG:4326 como en la sección de coordenadas. Los pares invertidos son la otra mitad de este síntoma.
KML vs GeoJSON vs Shapefile vs GeoPackage
Sin tabla — elegí la frase que coincide.
KML es la respuesta correcta cuando el destino es Google Earth, un teléfono de campo, o un cliente que va a hacer doble clic en el archivo y espera que se vea igual que en tu pantalla. Es el único de los cuatro que lleva su propio estilo, íconos e imágenes de superposición. Guardá los atributos en ExtendedData, y una copia en algo tipado.
KML es la respuesta equivocada cuando los atributos importan — las fechas y los booleanos llegan como cadenas, y un build de GDAL sin LIBKML descarta todos los atributos al leer; cuando los datos son grandes — XML verboso, sin índice; o cuando tienen que quedarse en un sistema proyectado.
GeoJSON es la respuesta correcta cuando lo va a leer un navegador o una API: atributos tipados, sin estilo, una capa por archivo, WGS 84 igual que KML.
Shapefile es la respuesta correcta cuando el otro lado no acepta nada más; nuestra guía para abrir un Shapefile en línea cubre qué hacer cuando te llega uno.
GeoPackage es la respuesta correcta cuando los datos son tuyos para guardar: cada carpeta una capa, tipos de campo reales, cualquier CRS, un solo archivo. Es en lo que un KMZ debería convertirse apenas llega.
Para equipos
Construimos Geodocs, una plataforma para equipos de datos de campo y de GIS, y una exportación de Google Earth de una visita a sitio es una carga común. La plataforma lee los placemarks y su ExtendedData, conserva las carpetas como capas, y pone el resultado en un mapa de equipo, así que el KMZ se convierte en el insumo de la revisión y el informe en vez del archivo que todo el mundo se manda por mail.
¿Encontraste un error, o una trampa que se nos pasó? Contanos; volvemos a correr esta página en vez de copiarla y pegarla.
Última verificación: 10 de septiembre de 2026, GDAL 3.13.3 en forma local y GDAL 3.14.0dev en la imagen Docker de OSGeo.