KML e KMZ: o guia definitivo (abrir, converter, erros)
Alguém te mandou um .kmz do Google Earth e o GIS o desenhou no meio do oceano, ou os placemarks vieram sem atributos. KML é o XML que o Google Earth tornou universal; KMZ é o mesmo arquivo zipado, com as imagens. Quase toda falha aqui vem de uma regra: <coordinates> levam a longitude primeiro, lon,lat[,alt], separadas por vírgula, sem espaços, sempre em graus decimais WGS 84. O KML não tem outro sistema de coordenadas; só a ordem pode dar errado. Abrir um KMZ, visualizar um KMZ online sem instalar nada e converter KML para Shapefile têm seção própria abaixo.
Tudo aqui foi testado, não copiado, com dois builds do GDAL, porque o GDAL tem dois drivers de KML que não se comportam da mesma forma. Localmente, GDAL 3.13.3 "Iowa City", onde ogrinfo --formats | grep -i kml imprime uma linha, KML -vector- (rw+v), e grep -c LIBKML imprime 0. Para o LIBKML usamos a imagem Docker da OSGeo ghcr.io/osgeo/gdal:ubuntu-full-latest (digest sha256:98086f71…, GDAL 3.14.0dev de 2026/09/10), que tem os dois; toda frase sobre LIBKML abaixo vem de um comando rodado ali com -if LIBKML. Nada foi escrito só a partir da documentação de um driver; as afirmações sobre o visualizador foram observadas carregando os mesmos arquivos na página ao vivo com um Chromium headless. Tudo aqui foi verificado em 10 de setembro de 2026.
O que é o KML, e o que o KMZ adiciona
KML, Keyhole Markup Language, é XML da Keyhole, a empresa que o Google comprou em 2004 para criar o Google Earth, e o formato seguiu o produto: ele descreve o que desenhar e como, não um conjunto de dados com um esquema. É um padrão OGC desde 2008, 2.2 depois 2.3, com opengis.net/kml/2.2 como valor de xmlns; arquivos mais antigos trazem earth.google.com/kml/2.1 ou 2.0, e a seção sobre namespace, nos erros, mostra o que o GDAL faz com cada um.
Um arquivo mínimo é uma raiz <kml>, um <Document>, e um <Placemark> com um <name> e um <Point> contendo <coordinates>-46.63,-23.55,0</coordinates> — São Paulo, longitude primeiro.
KMZ é esse arquivo dentro de um zip: um doc.kml na raiz e, por convenção, uma pasta files/ para os ícones e as imagens de sobreposição que o KML referencia por caminho relativo. Rodamos ogr2ogr -f KML out.kml props.geojson num GeoJSON de dois pontos, compactamos o resultado como doc.kml dentro de out.kmz, e unzip -l out.kmz listou uma entrada, doc.kml, 1375 bytes. Um KMZ escrito por ogr2ogr -f LIBKML out.kmz props.geojson contém doc.kml mais layers/props.kml, um arquivo por camada. Quando um KMZ está enorme, unzip -l é a primeira coisa a rodar: o tamanho quase sempre está em files/.
A estrutura que importa
Seis elementos respondem por quase tudo que você vai ler, escrever ou perder.
Placemark
Uma feição: um <name>, opcionalmente uma <description>, <styleUrl> e <ExtendedData>, e uma geometria — <Point>, <LineString>, <Polygon> ou um <MultiGeometry> envolvendo várias. Um MultiGeometry pode misturar tipos, e o GDAL o lê como uma única feição: o nosso placemark com um ponto e uma linha voltou como GEOMETRYCOLLECTION Z (POINT Z (-46.63 -23.55 0),LINESTRING Z (-46.63 -23.55 0,-46.6 -23.5 0)) — legal em KML, GeoJSON e GeoPackage, impossível num Shapefile.
Folder e Document
Document guarda as coisas compartilhadas — estilos e schemas — e Folder agrupa placemarks para a barra lateral do Google Earth; ambos podem se aninhar. Os dois drivers do GDAL leem uma pasta como uma camada: o nosso <Document> com uma pasta Wells de dois pontos e uma pasta Access roads de uma linha deu 1: Wells (3D Point) e 2: Access roads (3D Line String) no KML, 1: Wells e 2: Access roads no LIBKML, e ogr2ogr -f GPKG folders.gpkg folders.kml produziu essas duas camadas nos dois casos. O nosso visualizador as mantém: 3 feições · 1 Linha · 2 Ponto · 2 pastas, com Wells e Access roads no painel de camadas e um atributo folder em cada feição.
Style e StyleMap
Um <Style id="siteNormal"> contém blocos IconStyle, LineStyle, PolyStyle e BalloonStyle; um placemark aponta para ele com <styleUrl>#siteNormal</styleUrl>. Um <StyleMap> combina dois estilos sob as chaves normal e highlight para o mouse-over. As cores são aabbggrr — alfa, azul, verde, vermelho — motivo pelo qual um "vermelho" em KML se escreve ff0000ff. Os estilos não sobrevivem a nenhuma conversão para GeoJSON, Shapefile ou GeoPackage; a seção de erros tem as contagens.
ExtendedData e SchemaData
Os atributos vivem em <ExtendedData>, em dois dialetos. O simples é uma lista de pares <Data name="site_id"><value>42</value></Data>, strings sem tipo. O tipado declara um <Schema> dentro do Document com entradas <SimpleField name="site_id" type="int"/> e preenche cada placemark com <SchemaData schemaUrl="#props"><SimpleData name="site_id">42</SimpleData></SchemaData>. O GDAL escreve o dialeto tipado; o que cada driver lê de volta está coberto na seção de conversão. O nosso visualizador lê os dois: os pares Data carregados como observation_notes e site_id com valores Gate locked e 42, e o arquivo com SchemaData trouxe todos os seus cinco campos, editáveis.
NetworkLink
Um <NetworkLink> contém um <Link><href>example.com/layer.kml</href></Link> e manda o Google Earth buscar essa URL; não carrega geometria nenhuma. Um KML cujo único conteúdo é um NetworkLink abriu no KML sem nenhuma camada, e no LIBKML como uma camada, netlink, com Feature Count: 0; nenhum dos dois buscou nada. O nosso visualizador se comporta da mesma forma: 0 feições · 0 campos, e um registro de rede depois de soltar o arquivo mostrou requisições ao servidor de tiles do mapa e nada mais — o visualizador não busca esse link. Os dados estão na URL, não no arquivo; baixe o alvo e abra esse.
GroundOverlay
Um <GroundOverlay> estende uma imagem sobre uma <LatLonBox> de limites <north>, <south>, <east>, <west>, com <Icon><href>files/site.png</href></Icon> apontando para dentro do KMZ — uma planta escaneada do local, uma ortofoto de drone. O driver KML o ignora (o nosso KMZ listou apenas a camada Wells); o LIBKML lê um POLYGON Z dos cantos da caixa com um campo icon de files/site.png — o contorno, não a imagem. O nosso visualizador o renderiza: 1 feições · 1 Ponto · 1 imagens sobrepostas · 1 pastas, com o PNG embutido desenhado sobre a caixa.
Coordenadas: sempre lon,lat, sempre WGS 84
Um KML não tem onde declarar um sistema de coordenadas, então não existe "um KML em UTM" — só um KML com os números errados dentro. Os dois drivers dizem isso em toda leitura: ogrinfo -al -so em qualquer KML imprime GEOGCRS["WGS 84" e ID["EPSG",4326], sejam quais forem os números. Todo "meu KMZ está no lugar errado" é um de três erros.
- Ordem trocada. São Paulo é
<coordinates>-46.63,-23.55,0</coordinates>;ogrinfo -al sp_ok.kmlimprimiuPOINT Z (-46.63 -23.55 0), no Brasil. Escrito-23.55,-46.63,0, o mesmo placemark imprimiuPOINT Z (-23.55 -46.63 0)nos dois drivers, sem aviso nenhum: longitude −23,55, latitude −46,63, o Atlântico Sul, uns 3.300 km a leste da Patagônia. Um arquivo no oceano ou no continente errado tem os pares invertidos; troque a ordem, não reprojete nada. - Metros projetados escritos como graus. Um par UTM para o mesmo ponto é mais ou menos
333000,7395000. Na leitura os dois drivers aceitam sem reclamar —POINT Z (333000 7395000 0)— eogr2ogr -f GeoJSONescreveu isso sem dizer nada. Na escrita as checagens entram em ação: um GeoJSON com esse par passado porogr2ogr -f KMLfalhou comERROR 1: Latitude 7395000.000000 is invalid. Valid range is [-90,90].; o escritorLIBKMLdisseERROR 1: Invalid longitude 333000. Diga ao GDAL o que os números são e deixe ele converter:ogr2ogr -f KML out.kml in.geojson -s_srs EPSG:31983 -t_srs EPSG:4326produziu<coordinates>-46.636073838011,-23.5467532379101</coordinates>. Uma fonte que carrega o próprio CRS (um Shapefile com.prj, um GeoPackage) não precisa de nenhum dos dois. Uma latitude acima de 90 se comporta do mesmo jeito:-46.63,-93.55foi lida sem aviso, e depoisERROR 1: Latitude -93.550000 is invalidna escrita. - Graus, minutos e segundos colados direto. Uma tupla escrita
46°37'48"W,23°33'0"S,0não é um erro para nenhum dos dois drivers, e esse é o problema: oKMLretornouPOINT EMPTY; oLIBKMLretornouPOINT (46 23)— os inteiros iniciais, com os hemisférios descartados, um ponto na Arábia Saudita. Converta DMS para decimal primeiro; o nosso conversor de coordenadas faz isso e mostra o ponto num mapa.
Mais um, menor mas real: um espaço depois da vírgula. -46.63, -23.55, 0 vira três tuplas para o driver KML, que imprimiu POINT (-46.63 0.0) — a latitude sumiu, ponto na linha do equador — enquanto o LIBKML leu certo.
Abrir e visualizar um KMZ online sem o Google Earth
Seis coisas que o visualizador faz com um KMZ, na ordem em que você vai encontrá-las:
- Solte o arquivo no visualizador. O nosso visualizador gratuito de KMZ aceita
.kml,.kmze GeoJSON, descompacta o KMZ no navegador, e desenha os placemarks com a contagem no painel de camadas. - Pastas. Listadas sob a entrada de camada do arquivo, cada uma com um botão de mostrar/ocultar; toda feição carrega um atributo
folder. - Clique num placemark. O painel de atributos mostra o nome, a descrição, o WKT com um botão de copiar, e cada campo
ExtendedDatacomo uma linha — tanto paresDataquantoSchemaData; a tabela de atributos lista todas as feições com uma caixa de busca. - Edite um atributo, defina um rótulo. Os campos são editáveis; o menu suspenso
Rótuloescolhe o atributo desenhado ao lado de cada feição. - Sobreposições e exportação. Um
GroundOverlaycuja imagem está dentro do KMZ é desenhado sobre a suaLatLonBox; o menu de exportação grava GeoJSON, KML, KMZ ou CSV. - Privacidade. A leitura acontece no seu navegador; o arquivo nunca é enviado a um servidor. A única coisa que o visualizador não faz é seguir um
NetworkLink.
No terminal, ogrinfo -al -so in.kml lista camadas, campos e extensão. Só com o driver KML, um .kmz não abre direto: ogrinfo out.kmz falha com 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. — e de fato ajuda: ogrinfo -so /vsizip/out.kmz/doc.kml listou 1: props (Point). Com o LIBKML, ogrinfo out.kmz abre o arquivo diretamente.
Converter KML para Shapefile, GeoJSON ou GeoPackage
Todo comando foi rodado contra os arquivos acima; o driver é sempre citado porque é ele quem decide o resultado.
- KML para GeoJSON:
ogr2ogr -f GeoJSON out.geojson in.kml. GeoJSON é uma camada por arquivo, então um KML com várias pastas converte pela metade: o nosso escreveuWellsemout.geojsone depois parou comERROR 1: Layer 'Access roads' does not already exist in the output dataset, and cannot be created by the output driver.— um arquivo que parece completo e está sem uma pasta. Nomeie a camada como argumento final (ogr2ogr -f GeoJSON wells.geojson in.kml Wells, um arquivo por pasta) ou converta para GeoPackage.Warning 1: Attempt to write Z geometries to layer … that does not support themé inofensivo. - KML ou KMZ para GeoPackage:
ogr2ogr -f GPKG out.gpkg in.kmz. ComLIBKMLo.kmzabre direto e cada pasta vira uma camada —1: Wells,2: Access roadsno nosso caso. O nosso guia de GeoPackage cobre o que você recebe do outro lado. - KML para Shapefile:
ogr2ogr -f "ESRI Shapefile" out in.kml. Duas coisas acontecem que são culpa do Shapefile: os nomes de campo são cortados em dez caracteres —Descriptionvoltou comoDescriptiocomWarning 6: Normalized/laundered field name: 'Description' to 'Descriptio', e noLIBKML, que também lê os campos do schema,observation_notesvoltou comoobservatio— e um arquivo só guarda um tipo de geometria, então o placemarkMultiGeometryfalhou comERROR 6: Geometry type of '3D Geometry Collection' not supported in shapefiles. As pastas ficam bem, um Shapefile cada: recebemosWells.shpeAccess roads.shpnuma única rodada. O nosso guia de Shapefile documenta as duas regras e a armadilha de encoding que vem logo depois. - Shapefile ou GeoPackage para KML:
ogr2ogr -f KML out.kml in.shp. O driverKMLconverte para WGS 84 a partir do.prjsozinho e escreve os atributos comoSchemaData; um campoDategeraWarning 1: The output driver does not natively support Date type for field visit_datee vira a string2026/09/01. - Escrevendo um KMZ de verdade:
ogr2ogr -f LIBKML out.kmz in.gpkg. Só oLIBKMLcompacta. O driverKMLaceita um nome de saída.kmzsem reclamar e escreve XML puro dentro dele —file test_write.kmzreportouXML 1.0 document, ASCII text— e o nosso visualizador recusou comErro ao processar o arquivo. Verifique se o arquivo é um KML ou KMZ válido.; renomear para.kmlresolve.
KML vs LIBKML
KML é o driver antigo, sem dependências, sempre presente; o LIBKML é construído sobre a biblioteca libkml do Google, é o que você quer, e está ausente em muitos builds — inclusive o nosso. Quando os dois estão presentes o GDAL prefere o LIBKML para leitura (o container imprimiu using driver 'LIBKML' successful num arquivo que o KML tinha escrito).
- Atributos na leitura. Este é o que perde dados. O
KMLsó lêNameeDescription: o nosso arquivo com cinco campos tipados emSchemaDatalistouName: String (0.0),Description: String (0.0)e nada mais, os paresDataforam descartados da mesma forma, eogr2ogr -f GeoJSONpassando por ele produziu propriedades{"Name":"S1","Description":""}. OLIBKMLleu o mesmo arquivo comosite_id: Integer,area_ha: Real,observation_notes: String,visited: Integer(Boolean),visit_date: String, mais os campos de manutenção que ele sempre adiciona —id,Name,description,timestamp,begin,end,altitudeMode,tessellate,extrude,visibility,drawOrder,icon— e os paresDatacomoString. Só com oKML, todo atributo que você converte é descartado silenciosamente. - Atributos na escrita. Os dois escrevem um
<Schema>maisSchemaData. OKMLdeclaratype="float"e escreve um booleano como1; oLIBKMLdeclaratype="double",type="bool"e escrevetrue. Nenhum dos dois tem tipo data: os dois declaramvisit_datecomotype="string". - Pastas na escrita. O
KMLemite um<Folder>por camada; oLIBKMLemite<Document>s aninhados e nenhum<Folder>(grep -c '<Folder' lib_folders_out.kml→0).
Erros, decodificados
Sintoma, causa, correção; o QGIS mostra as mesmas mensagens do GDAL no seu painel de log.
A descrição é uma parede de HTML
Sintoma: uma descrição aparece cheia de tags — <b>Gate locked</b> since May. <a href="example.com/page">Site record</a> — numa tabela ou num CSV. Causa: o Google Earth guarda o conteúdo do balão como HTML dentro de <description><![CDATA[…]]></description>. Os dois drivers do GDAL retornam isso ao pé da letra na string description (ou Description), e um KML escrito de volta a partir de GeoJSON carrega isso escapado, <b>Gate locked</b>. O nosso visualizador renderiza: o painel de atributos mostrou texto em negrito e um link clicável, e a tabela mostra o placeholder HTML nessa coluna. Correção: nada está quebrado; remova as tags depois da exportação se precisar de texto limpo, e coloque valores estruturados em ExtendedData, não no balão.
Nomes de campo cortados em dez caracteres
Sintoma: Description vira Descriptio no caminho para o Shapefile, com Warning 6: Normalized/laundered field name. Causa: o .dbf guarda onze bytes por nome, um deles um terminador. Correção: nenhuma dentro de um Shapefile — renomeie os campos para dez caracteres antes de exportar, assim você escolhe as abreviações, ou mantenha um GeoPackage.
Os estilos somem depois da conversão
Sintoma: um KML que tinha ícones vermelhos e linhas verdes no Google Earth volta com os alfinetes padrão. Causa: nenhum dos três formatos comparados aqui tem lugar para os estilos do KML. Pegamos um KML com dois <Style>s e um <StyleMap> (grep -c '<Style' styled.kml → 3), convertemos para GeoJSON e de volta, e grep -c '<Style' roundtrip.kml imprimiu 0 nos dois drivers. Correção: se o estilo importa, fique em KML. ogr2ogr -f LIBKML out.kml in.kml mantém os blocos <Style> e cada <styleUrl>, mas achata um <StyleMap> num <Style> simples com o seu par normal; o estado highlight desaparece.
Um KMZ enorme do Google Earth
Sintoma: um KMZ de algumas centenas de placemarks tem dezenas de megabytes. Causa: files/ — o Google Earth embute toda foto anexada a um placemark e toda imagem de sobreposição em resolução total. Correção: unzip -l big.kmz e leia os tamanhos; unzip big.kmz doc.kml extrai só o KML (o nosso foi de três entradas para uma, 659 bytes) e zip stripped.kmz doc.kml reconstrói um KMZ sem as imagens. Guarde o original se ele tiver sobreposições.
Namespace KML 2.1 vs 2.2
Sintoma: uma ferramenta reclama que o arquivo "não é KML 2.2", ou um validador aponta o xmlns. Causa: arquivos da era do Google Earth 4 declaram earth.google.com/kml/2.1 ou 2.0 onde o padrão OGC é opengis.net/kml/2.2. O GDAL não liga para isso: o mesmo placemark com os namespaces 2.2, 2.1 e 2.0, e até sem nenhum xmlns, imprimiu POINT Z (-46.63 -23.55 0) nos dois drivers, sem aviso. Correção: mude o valor de xmlns para o de 2.2 num editor de texto; qualquer coisa que o GDAL escreve já carrega o certo.
Invalid latitude, ou um ponto fora do globo
Sintoma: ERROR 1: Latitude 7395000.000000 is invalid. Valid range is [-90,90]. do escritor KML, ERROR 1: Invalid longitude 333000 ou ERROR 1: Invalid latitude -93.55 do LIBKML, e uma conversão que para com Terminating translation prematurely. Causa: metros, ou graus fora do intervalo, onde deveriam estar graus WGS 84. Correção: nunca edite os números; diga ao GDAL o sistema de origem com -s_srs e -t_srs EPSG:4326 como na seção de coordenadas. Pares trocados são a outra metade desse sintoma.
KML vs GeoJSON vs Shapefile vs GeoPackage
Sem tabela — escolha a frase que se encaixa.
O KML é a resposta certa quando o destino é o Google Earth, um celular de campo, ou um cliente que vai dar duplo clique no arquivo e esperar que fique igual ao que você vê na tela. É o único dos quatro que carrega o seu próprio estilo, ícones e imagens de sobreposição. Mantenha os atributos em ExtendedData, e uma cópia em algo tipado.
O KML é a resposta errada quando os atributos importam — datas e booleanos chegam como strings, e um build do GDAL sem LIBKML descarta todo atributo na leitura; quando os dados são grandes — XML verboso, sem índice; ou quando precisam ficar num sistema projetado.
O GeoJSON é a resposta certa quando um navegador ou uma API vão lê-lo: atributos tipados, sem estilo, uma camada por arquivo, WGS 84 igual ao KML.
O Shapefile é a resposta certa quando o outro lado não aceita mais nada; o nosso passo a passo para abrir um Shapefile online cobre o que fazer quando um chega até você.
O GeoPackage é a resposta certa quando os dados são seus para guardar: cada pasta uma camada, tipos de campo de verdade, qualquer CRS, um único arquivo. É no que um KMZ deveria virar assim que chega.
Para times
Nós construímos o Geodocs, uma plataforma para dados de campo e equipes de GIS, e uma exportação do Google Earth de uma visita de campo é um upload comum. A plataforma lê os placemarks e o seu ExtendedData, mantém as pastas como camadas, e coloca o resultado num mapa da equipe, então o KMZ vira o insumo da revisão e do relatório em vez de ser aquele arquivo que todo mundo fica reenviando por e-mail.
Encontrou um erro, ou uma pegadinha que a gente deixou passar? Nos conte; a gente roda esta página de novo em vez de copiar e colar o texto.
Última verificação: 10 de setembro de 2026, GDAL 3.13.3 localmente e GDAL 3.14.0dev na imagem Docker da OSGeo.