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.kml imprimiu POINT Z (-46.63 -23.55 0), no Brasil. Escrito -23.55,-46.63,0, o mesmo placemark imprimiu POINT 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) — e ogr2ogr -f GeoJSON escreveu isso sem dizer nada. Na escrita as checagens entram em ação: um GeoJSON com esse par passado por ogr2ogr -f KML falhou com ERROR 1: Latitude 7395000.000000 is invalid. Valid range is [-90,90].; o escritor LIBKML disse ERROR 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:4326 produziu <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.55 foi lida sem aviso, e depois ERROR 1: Latitude -93.550000 is invalid na escrita.
  • Graus, minutos e segundos colados direto. Uma tupla escrita 46°37'48"W,23°33'0"S,0 não é um erro para nenhum dos dois drivers, e esse é o problema: o KML retornou POINT EMPTY; o LIBKML retornou POINT (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, .kmz e 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 ExtendedData como uma linha — tanto pares Data quanto SchemaData; 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ótulo escolhe o atributo desenhado ao lado de cada feição.
  • Sobreposições e exportação. Um GroundOverlay cuja imagem está dentro do KMZ é desenhado sobre a sua LatLonBox; 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 escreveu Wells em out.geojson e depois parou com ERROR 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. Com LIBKML o .kmz abre direto e cada pasta vira uma camada — 1: Wells, 2: Access roads no 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 — Description voltou como Descriptio com Warning 6: Normalized/laundered field name: 'Description' to 'Descriptio', e no LIBKML, que também lê os campos do schema, observation_notes voltou como observatio — e um arquivo só guarda um tipo de geometria, então o placemark MultiGeometry falhou com ERROR 6: Geometry type of '3D Geometry Collection' not supported in shapefiles. As pastas ficam bem, um Shapefile cada: recebemos Wells.shp e Access roads.shp numa ú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 driver KML converte para WGS 84 a partir do .prj sozinho e escreve os atributos como SchemaData; um campo Date gera Warning 1: The output driver does not natively support Date type for field visit_date e vira a string 2026/09/01.
  • Escrevendo um KMZ de verdade: ogr2ogr -f LIBKML out.kmz in.gpkg. Só o LIBKML compacta. O driver KML aceita um nome de saída .kmz sem reclamar e escreve XML puro dentro dele — file test_write.kmz reportou XML 1.0 document, ASCII text — e o nosso visualizador recusou com Erro ao processar o arquivo. Verifique se o arquivo é um KML ou KMZ válido.; renomear para .kml resolve.

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 KML só lê Name e Description: o nosso arquivo com cinco campos tipados em SchemaData listou Name: String (0.0), Description: String (0.0) e nada mais, os pares Data foram descartados da mesma forma, e ogr2ogr -f GeoJSON passando por ele produziu propriedades {"Name":"S1","Description":""}. O LIBKML leu o mesmo arquivo como site_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 pares Data como String. Só com o KML, todo atributo que você converte é descartado silenciosamente.
  • Atributos na escrita. Os dois escrevem um <Schema> mais SchemaData. O KML declara type="float" e escreve um booleano como 1; o LIBKML declara type="double", type="bool" e escreve true. Nenhum dos dois tem tipo data: os dois declaram visit_date como type="string".
  • Pastas na escrita. O KML emite um <Folder> por camada; o LIBKML emite <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, &lt;b&gt;Gate locked&lt;/b&gt;. 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.

Quando o arquivo está quebrado: quatro sintomas, quatro respostas

As seções acima respondem "qual formato, e como eu converto". Estas quatro respondem "meu arquivo está quebrado e eu não sei por quê" — uma página para cada uma, escritas a partir das mensagens do visualizador e dos comandos de reparo que a gente rodou de verdade.

Meus pontos caíram no mar

Todos os pontos aparecem no Atlântico Sul, ou na costa da África Ocidental, ou num continente onde você nunca pisou. "Coordenadas", acima, enuncia a regra; o sintoma é a história mais longa — as faixas de magnitude que deixam você reconhecer a troca a olho, e o reparo em cada um dos dois visualizadores — e ela está em lon,lat, não lat,lon: por que seus pontos do KML caíram no mar.

O KMZ não abre

Você tem um KMZ que nada abre, e o visualizador te devolve um aviso em vez de um mapa. "Abrir e visualizar um KMZ online sem o Google Earth", acima, parte do princípio de que o pacote está íntegro; esta é para quando ele não está, e começa lendo o aviso em vez de adivinhar: O KMZ não abre: leia o aviso, depois corrija o arquivo.

O símbolo do marcador depois da ida e volta

Você exportou de um visualizador, reabriu o arquivo, e o símbolo parece certo mas não responde mais ao controle de cor. Essa é uma pergunta diferente da perda de estilo pelo GDAL em "Erros, decodificados", acima — outro mecanismo com outra resposta — e tratar as duas como uma só é como as pessoas concluem que o estilo delas foi embora quando não foi. A distinção, e o que a exportação do próprio visualizador faz de verdade, está em O símbolo do marcador sobrevive à ida e volta do KML, como imagem.

Quando o Google Earth não basta

O Google Earth abre o arquivo e desenha um relevo melhor sob os seus pontos do que qualquer outra opção gratuita, e para uma pessoa olhando pontos isso encerra o assunto. "Para times", abaixo, é sobre o que a gente constrói; esta é sobre o passo anterior, antes de você precisar de uma plataforma, com os limites documentados e as datas em que a gente leu cada um: Quando o Google Earth não basta para uma equipe de campo.

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.

Artigos Relacionados

Navegação