O Que É o GeoJSON? O Guia Definitivo

O GeoJSON é um formato de texto em JSON puro para feições geográficas, padronizado como RFC 7946 em 2016, e suas coordenadas são sempre longitude primeiro, depois latitude, no WGS 84. Alguém te mandou um .geojson e ele abre como uma parede de números. Ou você exportou um do QGIS e ele desenha no Atlântico Norte. Ou um mapa web o rejeita como "não é um GeoJSON válido" quando todo linter de JSON diz que está tudo certo. Todo comando e todo número abaixo foram rodados em 15 de setembro de 2026 contra um dataset real, os limites estaduais de 2022 do IBGE para o Brasil, e toda afirmação sobre o nosso visualizador foi medida na ferramenta ao vivo.

O que é GeoJSON?

O GeoJSON é um formato de texto para feições geográficas, escrito como JSON puro e padronizado pela RFC 7946 em agosto de 2016. Um arquivo costuma ser uma FeatureCollection contendo um array de objetos Feature, e cada Feature tem uma geometry (a forma) e um objeto properties (os atributos, qualquer JSON que você quiser). Não há schema, não há arquivo-satélite e não há seção binária, e é por isso que toda biblioteca de mapas web fala GeoJSON nativamente.

O menor arquivo útil é uma única feição, e este aqui é uma fixture real do nosso laboratório: {"type":"Feature","properties":{"name":"Brasília"},"geometry":{"type":"Point","coordinates":[-47.8825,-15.7942]}}. Leia as coordenadas com atenção, porque esta é a frase que todo mundo pula e depois perde uma tarde inteira por causa dela: uma posição GeoJSON é escrita com a longitude primeiro, depois a latitude. Brasília é [-47.8825, -15.7942], não o -15.79, -47.88 que você digitaria numa busca. A especificação diz [longitude, latitude]; um par trocado é interpretado sem reclamar e desenha no hemisfério errado.

Os sete tipos de geometria, e o oitavo que os contém

Toda geometry tem um type e um array de coordinates; só a profundidade de aninhamento muda.

  • Point — uma posição, [lon, lat].
  • MultiPoint — um array de posições.
  • LineString — duas ou mais posições, na ordem do desenho.
  • MultiLineString — um array de arrays de coordenadas de LineString.
  • Polygon — um array de anéis fechados; o primeiro é o limite externo, o resto são buracos.
  • MultiPolygon — um array de arrays de coordenadas de Polygon. Os 27 estados do Brasil são 12 Polygon e 15 MultiPolygon, porque um estado costeiro com ilhas é formado por vários anéis que não são buracos uns dos outros.
  • GeometryCollection — o oitavo tipo: um array geometries com qualquer um dos anteriores, sem coordinates própria. Ele aparece onde você não esperava, como mostramos abaixo.

O que a RFC 7946 mudou, e por que seu arquivo pode ser mais antigo que a especificação

Antes de 2016 o formato era a "especificação GeoJSON" de 2008, um documento da comunidade, e muitos exportadores ainda escrevem esse sabor por padrão, o GDAL incluído. A RFC 7946 apertou cinco coisas, e cada uma explica um arquivo que "deveria funcionar" e não funciona.

  • Só WGS 84, e o membro CRS desaparece. Um arquivo RFC 7946 é sempre longitude e latitude em graus decimais no WGS 84. A especificação de 2008 permitia um objeto crs de nível superior nomeando qualquer sistema de coordenadas; a RFC o removeu. Um arquivo com um membro crs é um arquivo do padrão 2008, e se ele nomeia qualquer coisa que não seja WGS 84 você tem o problema da próxima seção.
  • A regra da mão direita para os anéis. Um anel externo roda no sentido anti-horário, os buracos no sentido horário. Shapefiles guardam anéis externos no sentido horário, então todo polígono convertido sem a flag da RFC fica "ao contrário"; a maioria dos leitores não liga.
  • A caixa delimitadora ganhou uma ordem fixa. O bbox já existia em 2008; a RFC fixa o significado dele em [west, south, east, north], ainda opcional em qualquer objeto.
  • Três dimensões, no máximo. Uma posição é [lon, lat] ou [lon, lat, elevation]; um quarto número não deveria estar lá; a RFC diz SHOULD NOT, não MUST NOT.
  • Corte no antimeridiano. Uma forma que cruza 180° de longitude deveria ser dividida em duas. Uma recomendação para quem escreve; os leitores variam.

O que a flag realmente fez com um arquivo real

Convertemos o mesmo Shapefile duas vezes, no modo padrão de 2008 e com -lco RFC7946=YES, e comparamos as saídas.

  • O membro CRS desapareceu. O arquivo no modo 2008 abre com "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } } na quarta linha; o arquivo RFC vai direto de "name": "BR_UF_2022" para "features". Nenhum dos dois tem bbox, que é opcional.
  • As coordenadas foram arredondadas para 7 casas decimais. O primeiro vértice do Acre foi de [-68.792817347,-10.999569268] para [-68.7928173,-10.9995693]. O driver usa 15 casas decimais por padrão no modo 2008 e 7 no modo RFC; 7 casas decimais é cerca de um centímetro.
  • Os anéis foram reorientados. O anel externo do Acre, 41.498 vértices nos dois arquivos, começa no mesmo vértice e anda no sentido contrário: horário no arquivo 2008, anti-horário no arquivo RFC.
  • O arquivo encolheu um quarto. 39.274.442 bytes viraram 29.108.343, quase toda essa diferença vindo dos números mais curtos.
  • Três polígonos mudaram de tipo, em silêncio. O arquivo 2008 tem 12 Polygon e 15 MultiPolygon; o arquivo RFC tem 11 Polygon, 13 MultiPolygon e três feições GeometryCollection, para Alagoas, Paraná e Goiás. Uma segunda rodada com -lco RFC7946=YES -lco COORDINATE_PRECISION=15 devolveu 12 e 15, então a causa é o arredondamento: em 7 casas decimais anéis minúsculos em Alagoas e Goiás colapsam para menos de quatro pontos distintos e um anel do Paraná cruza a si mesmo; o modo RFC do GDAL os conserta com MakeValid(), e as partes colapsadas saem como membros LineString e MultiLineString empacotados junto com o polígono numa coleção, 36 vértices perdidos. O GDAL não diz nada sobre isso a menos que você rode com --debug on, que imprime uma linha Running MakeValid() por estado consertado. O modo 2008 com -lco COORDINATE_PRECISION=7 segue outro caminho, SetPrecision(), e mantém 12 Polygon e 15 MultiPolygon. Precisão é uma decisão de geometria, e rodar um validador depois da conversão sai barato.

O erro clássico: metros num formato que significa graus

A reclamação é sempre parecida: "exportei minha camada para GeoJSON e ela está no oceano" ou "ela não está em lugar nenhum". A causa é quase sempre coordenadas que não são [longitude, latitude] em graus: eixos trocados, ou metros projetados.

Nosso dataset vem em coordenadas geográficas SIRGAS 2000, então para reproduzir o bug nós o exportamos para SIRGAS 2000 / UTM zona 23S: ogr2ogr -f GeoJSON utm.geojson BR_UF_2022.shp -t_srs EPSG:31983. O GDAL não recusa. Ele escreve um arquivo de 55.908.110 bytes, 1,4 vezes o arquivo em graus do modo 2008 (1,9 vezes o arquivo RFC, que também arredonda para 7 casas decimais), e o primeiro vértice do Acre vira [-2171693.959168141, 8673426.088929612], enquanto o arquivo correto tem [-68.7928173, -10.9995693]. A coordenada leste tem sete dígitos e é negativa porque o Acre fica quatro zonas UTM a oeste da zona 23. O GDAL também faz o que a especificação de 2008 permitia: ele escreve "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::31983" } } no topo, honesto sobre os números mas não é GeoJSON no sentido da RFC 7946. O GDAL respeita esse membro na hora de ler de volta, o ogrinfo reporta o arquivo como SIRGAS 2000 / UTM zone 23S, e o QGIS lê arquivos vetoriais através do GDAL, e é por isso que um arquivo desses "funciona no QGIS e quebra na web".

O que acontece depois depende do leitor, então medimos o nosso. Nosso visualizador gratuito de GeoJSON lê arquivos com o OpenLayers, que só respeita um membro crs quando ele nomeia um sistema de coordenadas que o OpenLayers já conhece: os apelidos do WGS 84, incluindo urn:ogc:def:crs:OGC:1.3:CRS84, e o Web Mercator. EPSG:31983 não está nessa lista. Seis fixtures, cada uma solta na ferramenta ao vivo:

  • Um CRS nomeando EPSG:31983, em qualquer uma das grafias. O visualizador não mostra erro nenhum. O painel de camadas diz 27 feições e 27 Polígono, tudo parece carregado, e o GeoJSON exportado coloca o primeiro vértice do Acre em [-19.5086591263066, 61.20664023081724]: o Atlântico Norte entre a Islândia e a Noruega, a uns 9.000 km do Acre. Os metros da UTM foram tratados como metros de Web Mercator e convertidos de volta para graus. A grafia do próprio GDAL, urn:ogc:def:crs:EPSG::31983, deu o mesmo par.
  • Os mesmos metros sem nenhum CRS. Ainda sem erro, ainda 27 feições. Sem crs o leitor assume graus, então -2171693.96 vira uma longitude de dois milhões de graus. O primeiro vértice exportado é [-2171693.959168141, -53.911070387188786]: a latitude deu a volta pela fórmula de Mercator até −53,9°, a longitude voltou sem mudar, e a forma não fica em lugar nenhum para onde você consiga navegar no mapa. Duas falhas silenciosas a partir de um único arquivo: "Brasil ao lado da Islândia" e "nada em mapa nenhum".
  • Um arquivo no estilo 2008 declarando CRS84. Desenha corretamente. O primeiro vértice do Acre é exportado como [-68.7928173712301, -10.999569659337354], o mesmo par que o arquivo RFC deu; os dígitos extras vêm da ida e volta pelo Web Mercator.
  • Um CRS cujo tipo o OpenLayers não reconhece. Tanto a forma "type":"link" da especificação de 2008 quanto um "type":"bogus" inventado interrompem o parse com o banner Erro ao processar o arquivo. Verifique se o arquivo é um GeoJSON válido. Um crs malformado falha alto; um crs bem formado nomeando o sistema errado falha em silêncio. Essa assimetria é o problema de interoperabilidade que a RFC 7946 §4 cita ao remover o membro.

A correção é do lado de quem exporta, e é uma única flag: acrescente -t_srs EPSG:4326 à exportação para que o arquivo contenha graus. Não edite a linha crs na mão; os números lá dentro continuam sendo metros, e nenhuma declaração os transforma em [longitude, latitude]. Reprojete com ogr2ogr -t_srs EPSG:4326; no modo 2008 padrão o GDAL ainda escreve uma declaração CRS84, que é inofensiva (o visualizador a respeita, como a terceira fixture acima mostrou), e -lco RFC7946=YES a remove por completo.

Convertendo para GeoJSON com o ogr2ogr

O comando que produz um arquivo que todo leitor aceita é ogr2ogr -f GeoJSON out.geojson in.shp -t_srs EPSG:4326 -lco RFC7946=YES. A página do driver GeoJSON do GDAL lista todas as opções de criação de camada; estas quatro mudam o arquivo de um jeito que dá para ver.

  • RFC7946=YES — tudo da seção sobre o que a flag fez com um arquivo real: sem crs, anéis reorientados, 7 casas decimais, e possivelmente uma mudança de tipo de geometria onde o arredondamento invalida um anel. O padrão é NO.
  • COORDINATE_PRECISION=6 — uma casa decimal a menos que o padrão da RFC. Um milionésimo de grau é cerca de 0,11 m no equador (111.320 m por grau, dividido por um milhão), ainda abaixo da precisão da maioria dos dados vetoriais. Isso levou nosso arquivo de 29.108.343 bytes para 26.839.688, uma economia de 7,8%, e o primeiro vértice do Acre virou [-68.792817,-10.999569]. Cinco casas decimais é mais ou menos um metro.
  • WRITE_BBOX=YES — adiciona um bbox à coleção e a cada feição: nosso arquivo ganhou 28 deles, [ -73.9904500, -33.7511780, -28.8476399, 5.2718411 ] no topo e um por estado, totalizando 1.626 bytes a mais.
  • ID_FIELD=CD_UF — promove um atributo para o "id" no nível da feição e o remove de properties. Nossos estados saíram como "id":"12", "id":"13", "id":"15", strings porque o campo do Shapefile era texto. Útil quando um mapa web precisa de uma chave estável.

Três outras coisas que o laboratório resolveu.

  • A elevação sobrevive, apesar do aviso. Converter um ponto [-47.8825,-15.7942,1172] com -dim XYZ imprime Warning 1: Attempt to write Z geometries to layer pz that does not support them. Z component will be discarded, e depois escreve [-47.8825,-15.7942,1172.0], que ao ler de volta é um 3D Point. Não confie no aviso.
  • GeoJSONSeq é a forma de streaming. ogr2ogr -f GeoJSONSeq out.geojsonl in.shp -t_srs EPSG:4326 escreve uma Feature por linha, sem coleção envolvendo tudo: 27 linhas, coordenadas com 7 casas decimais, sem crs, 29.108.905 bytes. Uma ferramenta orientada a linha pode fazer streaming disso; um leitor que espera uma única FeatureCollection não consegue, porque o arquivo inteiro não é um único valor JSON.
  • TopoJSON não é GeoJSON. Ele codifica arcos compartilhados uma única vez e costuma ser bem menor, mas seu objeto de nível superior é uma Topology. O GDAL lê, mas não consegue escrever: ogr2ogr -f TopoJSON responde ERROR 1: TopoJSON driver does not support data source creation. Nosso visualizador rejeita de duas formas, dependendo do nome: um .topojson nunca chega ao parser e recebe Tipo de arquivo não suportado. Use GeoJSON (.geojson ou .json).; os mesmos bytes renomeados para .json chegam ao parser e recebem Erro ao processar o arquivo. Verifique se o arquivo é um GeoJSON válido.

Tamanho, medido

O GeoJSON é grande sem compactar e é o menor dos três formatos vetoriais comuns depois de zipado, porque texto comprime muito melhor do que formas binárias. Estes números vêm do nosso laboratório de comparação de formatos de 15 de setembro de 2026, no mesmo dataset: o BR_UF_2022.zip do IBGE, 13.717.460 bytes como baixado, SHA-256 282ec7f0f0beeeead45e6609f4ffffce161bda04cb8ee0afcad2316d1c841bcb, 27 estados, 1.138.650 vértices.

  • Shapefile — 18.227.115 bytes somando os cinco arquivos, o .shp e seus quatro arquivos-satélite; 13.794.222 bytes rezipado na compressão máxima.
  • GeoPackage — 18.386.944 bytes, um pouco maior que o Shapefile porque as páginas do SQLite e o índice espacial custam mais do que o .shx que eles substituem; 13.828.105 bytes zipado.
  • GeoJSON no padrão da RFC, 7 casas decimais — 29.108.343 bytes, o maior em disco, de longe; 8.457.365 bytes zipado, o menor dos três por cerca de 5,1 MiB.
  • GeoJSON com 6 casas decimais — 26.839.688 bytes; 7.132.808 bytes zipado.

Ou seja, em disco e na memória do navegador, o GeoJSON custa 1,6 vez o que um Shapefile custa; zipado, custa 61%, e o argumento do tamanho contra ele praticamente desaparece. A comparação completa, com os oito critérios e os tempos de carregamento no navegador, está no nosso post Shapefile vs GeoPackage vs GeoJSON: qual usar.

Como abrir um arquivo GeoJSON

Você não precisa de um GIS de desktop para olhar um. Solte o arquivo no nosso visualizador de GeoJSON e ele desenha as feições num mapa base, lista elas num painel de camadas com uma contagem por tipo de geometria, e abre uma tabela de atributos que dá para ordenar. O passo a passo está em como abrir um arquivo GeoJSON online; os fatos abaixo foram medidos na ferramenta ao vivo com os arquivos deste guia.

  • O que ele aceita. O seletor de arquivos filtra por extensão, .geojson, .json, .kml e .kmz, mas um arquivo arrastado pula esse filtro e é julgado pelo sufixo dentro do parser: um GeoJSON renomeado para .txt recebe Tipo de arquivo não suportado. Use GeoJSON (.geojson ou .json). Não há limite de tamanho e não há limite de feições; o arquivo UTM de 56 megabytes acima carregou em menos de dois segundos, e o teto é a memória do seu navegador, para a qual não vamos inventar um número.
  • Um arquivo por vez, dez por sessão. Soltar dois arquivos de uma vez carrega o primeiro e ignora o segundo. Depois do décimo arquivo o botão Adicionar no painel de camadas simplesmente some; não há mensagem de "muitos arquivos".
  • O que as contagens significam. O arquivo RFC 7946 mostra 27 feições e 24 Polígono, porque os três estados GeometryCollection não pertencem a nenhum grupo de geometria; o arquivo no modo 2008 mostra 27 feições e 27 Polígono. Uma coleção é rotulada como Coleção na coluna Tipo da tabela de atributos e no painel da feição, não na linha de camadas.
  • Uma geometria pura funciona. Um arquivo cujo nível superior é uma única Feature, ou até um Point sozinho, carrega como uma feição; o ponto sozinho mostra 0 campos.
  • Anéis não são verificados. Um anel externo no sentido horário desenha normalmente e a exportação mantém o sentido horário; o visualizador não valida nem corrige o sentido do anel.
  • O estilo em properties é aplicado e depois escondido. As chaves do simplestyle, fill, fill-opacity, stroke, stroke-width, marker-color, marker-size, marker-symbol, estilizam o mapa e ficam escondidas da tabela de atributos: uma feição com sete chaves de estilo mais name e plain lista 2 campos.
  • Linhas e polígonos são suavizados em 20 cm. Toda geometria que não é ponto é simplificada com uma tolerância de 0,2 metro antes de desenhar e antes de exportar. Uma linha de teste cujo vértice do meio estava a 5 cm da linha reta perdeu esse vértice; uma a 1 m de distância manteve os 3 vértices. Para os limites estaduais isso é 15.249 vértices de um total de 1.138.614, invisível em qualquer zoom; onde 5 cm importa, guarde o original e trate a exportação como uma imagem.

Como conselho geral para o QGIS, não algo que este guia mediu: arraste o arquivo para a tela do mapa. Se as propriedades da camada mostrarem qualquer coisa diferente de EPSG:4326, exporte de novo com -t_srs EPSG:4326 antes de publicar.

Arquivos de teste que você pode usar

Toda URL aqui foi requisitada em 15 de setembro de 2026 com um user agent de navegador, registrando o status, Accept-Ranges e o cabeçalho de CORS. Uma lista como essa apodrece; leia-a como a foto de um único dia.

  • Natural Earth 1:110m dos países, o arquivo para começar. tem 838.726 bytes, responde 206 com accept-ranges: bytes e access-control-allow-origin: *, e é pequeno o bastante para baixar e soltar. Licença: o LICENSE.md do repositório começa com "Everything here is public domain." (tudo aqui é domínio público).
  • O contorno do Brasil pela própria API do IBGE. devolve GeoJSON direto: 65.655 bytes, uma única feição MultiPolygon, sem membro crs, lida pelo GDAL como WGS 84. Responde 200 com access-control-allow-origin: * mas sem accept-ranges, então está no ar e aberta para baixar e soltar, não para uma requisição de intervalo. A resposta não traz texto de licença; são dados públicos do IBGE, então cite a fonte.
  • Os 27 estados que usamos. O BR_UF_2022.zip do geoftp.ibge.gov.br, citado na seção de tamanho, é um Shapefile; converta-o com o comando acima e você tem exatamente o nosso arquivo de 29.108.343 bytes.
  • Um que está morto, para você parar de procurar. A cópia do portal de dados da OKFN dos limites mundiais em data.okfn.org/data/datasets/geo-boundaries-world-110m/data/countries.geojson ainda está linkada em tutoriais antigos e o hostname não resolve mais. Quando uma URL de exemplo falha no DNS, os dados geralmente se mudaram para o GitHub; procure pelo nome do arquivo.

Onde o Geodocs entra

A gente constrói o Geodocs, uma plataforma para times de dados de campo e de GIS, e escrevemos este guia porque o GeoJSON é o formato que os nossos usuários mais nos entregam, e o membro crs é o que mais quebra.

Trabalhando com os outros formatos? Nosso guia completo do formato Shapefile cobre os arquivos-satélite e o problema do .prj que a seção do lugar errado deste guia herda; o guia de GeoPackage é a alternativa de um arquivo só; e o guia de KML e KMZ cobre o outro formato de texto que o mesmo visualizador abre. Para olhar um arquivo agora mesmo, o visualizador de GeoJSON linkado acima é gratuito e roda no seu navegador.

Encontrou um erro, ou uma pegadinha que a gente deixou passar? Fala com a gente. A gente retesta esta página em vez de copiar e colar.

Última verificação: 15 de setembro de 2026.

Artigos Relacionados

Navegação