GeoPackage (.gpkg): O Guia Definitivo

Alguém te mandou um .gpkg e você não sabe o que fazer com ele. Ou você tem uma pasta cheia de Shapefiles, já te disseram que GeoPackage é "o substituto moderno", e você quer saber se isso é verdade ou só moda.

As duas respostas estão abaixo, e tudo o que há de factual nesta página foi testado, não copiado. Construímos GeoPackages e Shapefiles com GDAL 3.13.1 e SQLite 3.53.3, rodamos as conversões, abrimos os arquivos com um cliente SQLite comum e lemos os bytes. Quando uma afirmação vem da especificação da OGC em vez do nosso terminal, a gente avisa. Tudo o que está aqui foi verificado em 14 de julho de 2026.

Uma coisa logo de cara, porque a maioria dos artigos erra nisso: um Shapefile não perde os seus booleanos. Ele perde outras coisas — coisas piores — e vamos te mostrar exatamente quais.

A virada de chave mental: um GeoPackage é um banco SQLite

É isso, é tudo. Depois que a ficha cai, todo o resto decorre daí.

Um arquivo .gpkg é um banco de dados SQLite comum, com um conjunto padronizado de tabelas definido pela especificação GeoPackage da OGC. Não é um container binário novo. Não é um zip. É SQLite, e toda ferramenta SQLite do planeta já sabe abrir.

Rode file parcelas.gpkg e você recebe de volta SQLite 3.x database (OGC GeoPackage file), user version 10400. Leia os primeiros dezesseis bytes e eles são, literalmente, SQLite format 3\0. O que faz dele um GeoPackage em vez de um banco qualquer é um application_id de quatro bytes no offset 68, que soletra GPKG em ASCII, mais um user_version — medimos 10400, ou seja, GeoPackage 1.4.

Então isto funciona, sem nenhum software de GIS instalado:

  • Ver o que tem dentro: sqlite3 parcelas.gpkg "SELECT table_name, data_type FROM gpkg_contents;"gpkg_contents é o registro de camadas. O nosso voltou com parcelas|features, vias|features, hillshade|tiles.
  • Consultar os seus dados com SQL: sqlite3 parcelas.gpkg "SELECT fid, owner_name FROM parcelas WHERE status = 1;"
  • Despejar os atributos em CSV: sqlite3 -header -csv parcelas.gpkg "SELECT owner_name, area_m2 FROM parcelas;"
  • Achar a coluna de geometria: sqlite3 parcelas.gpkg "SELECT table_name, column_name, geometry_type_name, srs_id FROM gpkg_geometry_columns;"

Quando o GDAL escreve um GeoPackage, ele cria cerca de catorze tabelas. Junto com a sua tabela de dados vêm gpkg_contents, gpkg_geometry_columns, gpkg_spatial_ref_sys (as projeções, guardadas dentro do arquivo — nunca mais um .prj perdido), gpkg_extensions, gpkg_metadata, a família gpkg_tile_matrix para rasters, e um conjunto de tabelas rtree_* que são o índice espacial. Ele também instala uns dezenove triggers para manter a R-tree e as contagens de feições honestas conforme você insere e apaga.

Essa última parte importa: o índice espacial é uma tabela real, viva e consultável. sqlite3 parcelas.gpkg "SELECT id, minx, miny FROM rtree_parcelas_geom WHERE minx > -38.55;" retorna linhas. A sua consulta por bounding box está sendo respondida por uma R-tree dentro do arquivo, e não por um scan.

O que um Shapefile realmente te custa

Pegamos um dataset pequeno — parcelas de levantamento brasileiras, nomes acentuados, um timestamp, um booleano, alguns NULLs — e passamos pelos dois formatos. Eis o que o Shapefile fez com ele.

Ele trunca os nomes dos seus campos em 10 caracteres, em silêncio

Esse é o famoso, e é pior do que as pessoas lembram. O formato .dbf limita os nomes de campo a 10 caracteres. Converta e o GDAL avisa, e então mutila:

  • identificacao_do_proprietario virou identifica
  • area_construida_m2 virou area_const
  • data_da_vistoria virou data_da_vi
  • situacao_regular virou situacao_r

E quando dois nomes colidem, ele inventa nomes novos. Demos a ele observacao_tecnica_inicial e observacao_tecnica_final. Os dois truncam para observacao, então o GDAL renomeou o segundo para observac_1. O seu schema agora é trivia posicional. Quem abrir esse arquivo depois vai ter que adivinhar qual dos dois era o "inicial".

Isso é permanente. Nos mordeu no meio da escrita deste texto: convertemos um Shapefile para GeoPackage e depois rodamos um filtro SQL em situacao_regular, e o SQLite cuspiu no such column: situacao_regular — porque a ida e volta pelo .dbf já tinha destruído o nome. Converter de volta para GeoPackage não restaura nada. A informação foi embora.

Ele não tem datetime de verdade

Converta um campo DateTime para Shapefile e o GDAL te diz na lata: Field data_da_vi created as String field, though DateTime requested. O tipo de data do .dbf guarda uma data e mais nada — sem hora, sem fuso. Então o seu timestamp é rebaixado a um String(29) e toda ferramenta lá na frente agora tem que parsear texto e torcer. No GeoPackage, o mesmo campo continua sendo um DateTime de verdade.

Ele não sabe diferenciar NULL de string vazia

Essa é a que ninguém demonstra, então nós demonstramos. Criamos duas feições: uma com nota em NULL, outra com nota igual a "".

Pelo GeoPackage, o SQL devolve exatamente o que entrou — typeof() reporta null para a primeira e text para a segunda. Pelo Shapefile, as duas voltam como `(null)`. O .dbf preenche campos não definidos com espaços em branco e não tem sentinela de NULL, então "nunca medimos isso" e "medimos e estava vazio" viram o mesmo valor, para sempre. Se você faz QA de dados de campo, essa distinção é o trabalho inteiro.

A bagunça de encoding é real, e o padrão do GDAL vai te queimar

Aqui está a descoberta que mais nos surpreendeu. Convertemos a nossa fonte em UTF-8 para Shapefile com uma chamada ogr2ogr simples, sem flags. O GDAL não produziu nenhum arquivo `.cpg`, e setou o byte de language driver do .dbf (offset 29) para 87 — que significa Latin-1. E aí transcodificou o nosso texto: os bytes crus no .dbf contêm Jo\xe3o, a grafia Latin-1 de "João". A sequência de bytes UTF-8 não está em lugar nenhum do arquivo.

O GDAL relê a própria saída corretamente, porque ele checa esse byte. Mas entregue esse Shapefile para qualquer coisa que assuma UTF-8 — o que em 2026 é quase tudo — e "João Conceição" vira mojibake. É exatamente por isso que datasets em português e espanhol chegam com João e María dentro, e por que todo time de GIS da América Latina tem uma pasta de tabelas de atributos corrompidas.

A correção, se você for obrigado a escrever um Shapefile: ogr2ogr -f "ESRI Shapefile" out_dir input.gpkg -lco ENCODING=UTF-8. Confirmamos que isso escreve um arquivo .cpg contendo o texto UTF-8, seta o byte de language para 0 e grava bytes UTF-8 de verdade.

Lendo um Shapefile em Latin-1 que outra pessoa fez: ogr2ogr -f GPKG out.gpkg in.shp --config SHAPE_ENCODING ISO-8859-1. Rodamos isso contra o nosso próprio arquivo mutilado e os acentos voltaram intactos.

Um GeoPackage não tem esse problema. O SQLite armazena texto como UTF-8. Não existe byte para errar.

É uma pilha de arquivos, e um deles vai sumir

A nossa conversão produziu quatro arquivos — .shp, .shx, .dbf, .prj — e esse é o mínimo. No mundo real, acrescente .cpg, .sbn, .sbx, .qix, .qmd. Perca o .prj e a sua camada fica sem projeção. Perca o .dbf e ela fica sem atributos. Mande "o shapefile" por e-mail para um colega e você mandou nada.

Um GeoPackage é um arquivo só. Não dá para perder metade dele.

Um tipo de geometria por arquivo

Um Shapefile guarda pontos, ou linhas, ou polígonos. Não dois deles. Uma malha viária e os seus nós de cruzamento são dois arquivos, duas camadas, duas de cada coisa.

Colocamos uma camada de pontos, uma de linhas e um raster dentro de um único GeoPackage, e o ogrinfo listou tudo limpinho como 1: parcelas (Point) e 2: vias (Line String), com o gpkg_contents carregando também hillshade|tiles. Um arquivo, três camadas, tipos misturados.

O teto de 2 GB — e o padrão perigoso do GDAL

A especificação do Shapefile guarda o tamanho do arquivo como uma contagem de palavras de 16 bits num inteiro de 32 bits com sinal, e é daí que vem o famoso limite prático de 2 GB (essa parte é spec, não é do nosso terminal).

O que nós de fato verificamos é mais interessante. O driver de Shapefile do GDAL expõe uma opção de criação chamada literalmente 2GB_LIMIT, e o padrão dela é `NO`. Leia de novo: por padrão, o GDAL vai alegremente escrever um .shp ou .dbf maior que 2 GB — um arquivo fora da spec, que outros softwares vão recusar ou ler errado. O limite do formato não te protege; ele só espera.

O GeoPackage herda os limites do SQLite, que chegam à casa dos terabytes. Na prática, a sua paciência acaba muito antes do formato.

O que o Shapefile não quebra

Credibilidade vale para os dois lados, então: aquela história de que "Shapefile não tem booleano", que você lê em todo lugar, está errada. O formato .dbf tem um tipo de campo lógico, e nós vimos um booleano sobreviver à ida e volta — ele voltou como Integer(Boolean) com largura 1, valores 1 e 0, correto. Não migre por esse motivo. Migre pelos quatro acima, que são reais.

Rasters também moram lá dentro

Quase todo artigo sobre GeoPackage trata o formato como se fosse vetorial. Não é. O gpkg_contents.data_type pode ser features ou tiles, e os tiles são uma pirâmide de verdade.

Empurramos um raster para dentro do mesmo arquivo que já tinha duas camadas vetoriais, com gdal_translate -of GPKG raster.png parcelas.gpkg -co APPEND_SUBDATASET=YES -co RASTER_TABLE=hillshade -a_srs EPSG:4326. Depois disso, o gdalinfo parcelas.gpkg reporta Driver: GPKG/GeoPackage e Size is 64, 64, enquanto o ogrinfo no mesmo arquivo continua listando as camadas vetoriais.

Os tiles são armazenados como blobs, uma linha por tile, chaveados por nível de zoom, coluna e linha. Rodamos SELECT zoom_level, tile_column, tile_row, length(tile_data) FROM hillshade; e obtivemos 0|0|0|338 bytes, com os magic bytes do blob dizendo 504E47 — hexadecimal para PNG. É um cache de tiles dentro de uma tabela. O TILE_FORMAT deixa você escolher PNG, JPEG ou WEBP.

Ou seja: um único .gpkg pode carregar a imagem do seu basemap, os seus pontos de levantamento e os polígonos das suas parcelas, e você entrega um arquivo só.

Como abrir um .gpkg

  • QGIS: arraste o arquivo para dentro do canvas. Se ele tiver várias camadas, o QGIS pergunta quais você quer. É o caminho de menor resistência e é genuinamente bom.
  • Listar as camadas pelo terminal: ogrinfo -so parcelas.gpkg imprime todas as camadas e os seus tipos de geometria sem carregar os dados.
  • Inspecionar o schema de uma camada: ogrinfo -so parcelas.gpkg parcelas te dá nomes de campo, tipos e a contagem de feições.
  • SQLite puro: sqlite3 parcelas.gpkg ".tables" funciona. Qualquer GUI de SQLite também — DB Browser for SQLite, DBeaver, DataGrip. A coluna de geometria é um blob com um pequeno cabeçalho GeoPackage envolvendo WKB padrão.
  • Python: geopandas.read_file("parcelas.gpkg", layer="parcelas") é o one-liner. Por baixo dos panos é fiona/pyogrio, e ambos aceitam o argumento layer= — você vai precisar dele, porque um GeoPackage com várias camadas não vai adivinhar por você.
  • PostGIS: ogr2ogr -f PostgreSQL PG:"dbname=gis" parcelas.gpkg carrega todas as camadas direto.

Convertendo, com comandos que realmente rodam

Todo comando desta seção foi executado contra arquivos reais antes da publicação.

  • Shapefile para GeoPackage: ogr2ogr -f GPKG output.gpkg input.shp
  • Shapefile para GeoPackage quando a fonte está em Latin-1 (assuma que está, a não ser que haja um .cpg dizendo o contrário): ogr2ogr -f GPKG output.gpkg input.shp --config SHAPE_ENCODING ISO-8859-1
  • GeoPackage para Shapefile, sem destruir os acentos: ogr2ogr -f "ESRI Shapefile" out_dir input.gpkg -lco ENCODING=UTF-8
  • Uma pasta inteira de Shapefiles dentro de um GeoPackage — rode uma vez por arquivo, e eles se acumulam como camadas: ogr2ogr -f GPKG combined.gpkg roads.shp -nln roads e depois ogr2ogr -f GPKG -update -append combined.gpkg parcels.shp -nln parcels
  • Explodir um GeoPackage multicamada de volta num diretório de Shapefiles: ogr2ogr -f "ESRI Shapefile" out_dir input.gpkg — o GDAL escreve um Shapefile por camada, e trunca todo nome de campo com mais de 10 caracteres no caminho de saída.
  • Reprojetar durante a conversão: ogr2ogr -f GPKG out.gpkg in.gpkg -t_srs EPSG:3857 -nln parcels_3857
  • Filtrar com SQL durante a conversão: ogr2ogr -f GPKG regulars.gpkg source.gpkg -sql "SELECT * FROM parcels WHERE status = 1" -nln regulars
  • Resolver aquele erro de geometria single/multi misturada que o QGIS e o PostGIS jogam na sua cara: ogr2ogr -f GPKG out.gpkg in.shp -nlt PROMOTE_TO_MULTI
  • GeoPackage para GeoJSON para a web — sempre reprojete para 4326, a spec do GeoJSON exige: ogr2ogr -f GeoJSON web.geojson input.gpkg parcels -t_srs EPSG:4326
  • GeoPackage para FlatGeobuf: ogr2ogr -f FlatGeobuf out.fgb input.gpkg parcels

A flag -nln nomeia a camada de saída. Pule ela e você herda como a fonte se chamava, que é como as pessoas acabam com uma camada em produção chamada OGRGeoJSON.

Onde o GeoPackage é a resposta errada

Se a gente só te contasse as partes boas, você deveria parar de acreditar no resto da página.

Não sirva ele para um navegador. Um GeoPackage é um arquivo de banco de dados. Para ler uma feição, o cliente precisa buscar e parsear páginas do banco. Não existe história de streaming que preste sobre HTTP. Para entrega web, use GeoJSON para camadas pequenas, vector tiles ou PMTiles para as grandes, ou FlatGeobuf se você quiser acesso aleatório com HTTP range requests. Publicar um .gpkg de 400 MB e pedir para o navegador baixar ele antes do primeiro pixel aparecer é um tiro no próprio pé.

Não use ele como store de escrita multiusuário. O SQLite pega um lock de escrita sobre o banco inteiro. Um escritor por vez, ponto final. Duas equipes de campo sincronizando no mesmo .gpkg num compartilhamento de rede vão corromper o arquivo ou travar uma à outra — e SQLite em cima de um sistema de arquivos de rede como NFS ou SMB é explicitamente uma má ideia, porque as primitivas de lock das quais ele depende não são confiáveis ali. Se você tem escritores concorrentes, o que você quer é PostGIS. Isso não é uma crítica ao formato; é um arquivo de banco de dados, e ele se comporta como um.

Não presuma que toda ferramenta fala o formato. Um monte de software municipal e de concessionárias legado ainda só importa .shp. Alguns pacotes de engenharia e topografia, algumas instalações antigas de ArcGIS, e mais de um portal de governo vão exigir um Shapefile de você. Quando isso acontecer, exporte um Shapefile, aceite a truncagem, e mantenha o GeoPackage como a sua fonte da verdade.

Não recorra a ele para uma camada de rascunho com cinco feições. Se você está passando três pontos para um colega, o GeoJSON é legível por humano, dá diff no git, e não precisa de ferramenta nenhuma para conferir se está certo. Nem tudo precisa de um banco de dados.

Shapefile vs GeoPackage vs GeoJSON vs FlatGeobuf

Sem tabela — só escolha o que corresponde à sua frase.

Vá de GeoPackage quando os dados são o entregável, ou o arquivo morto, ou a coisa que você entrega para um cliente. Muitas camadas, tipos de geometria misturados, rasters ao lado de vetores, tipos de verdade, NULLs de verdade, nomes de campo honestos, um arquivo só. É o padrão correto para GIS de desktop e para dados de campo. É a resposta para "aqui está o dataset".

Vá de GeoJSON quando um navegador ou uma API vai ler o arquivo, a camada é pequena (digamos, alguns MB no máximo), ou um humano precisa ler o arquivo. É texto, é universal, dá diff no git. Também é verboso, não tem índice, e está preso ao EPSG:4326 por especificação. É a resposta para "manda isso pro frontend".

Vá de FlatGeobuf quando você tem um dataset vetorial grande que precisa ser lido sobre HTTP sem um servidor de tiles. É um formato binário, indexado e streamável, e um cliente consegue puxar só as feições dentro de uma bounding box usando HTTP range requests. É a resposta para "camada grande, sem backend".

Vá de vector tiles ou PMTiles quando os usuários vão dar pan e zoom por cima de um dataset grande num mapa web. Pré-renderizado, piramidado, cacheado. É a resposta para "deixa o mapa rápido".

Vá de Shapefile quando alguém te obrigar. Essa é a lista inteira. É um formato dos anos 1990 com um limite de schema de 10 caracteres e um byte de encoding de outra era. Continua sendo o formato de GIS mais interoperável do planeta, que é exatamente por que ele vai sobreviver a todos nós.

E se existirem escritores concorrentes, nenhum destes — use PostGIS.

Armadilhas que vão realmente te morder

Os arquivos-satélite `-wal` e `-shm`. O SQLite em modo WAL escreve dois arquivos extras ao lado do seu banco. Abrimos um GeoPackage, começamos a escrever, e confirmamos que o diretório então continha big.gpkg, big.gpkg-wal e big.gpkg-shm. Depois de um fechamento limpo, os dois sumiram. Mas se um processo cair — ou se você copiar o .gpkg enquanto alguma coisa está com ele aberto — você pode capturar um arquivo cujos commits mais recentes moram num -wal que ficou para trás. Quando você fizer backup ou enviar um GeoPackage, garanta que nada está com ele aberto, ou copie os arquivos-satélite junto. A promessa de arquivo único só vale com o arquivo fechado.

O arquivo cresce e nunca encolhe. O SQLite marca as páginas apagadas como livres e as reutiliza; ele não devolve o espaço ao sistema de arquivos. Inserimos dados em massa num GeoPackage até ele bater 43,335,680 bytes, rodamos DROP TABLE, e o arquivo continuava com 43,335,680 bytes — com 10,554 páginas livres sentadas lá dentro. Aí rodamos sqlite3 file.gpkg "VACUUM;" e ele desabou para 106,496 bytes. Se você anda editando um GeoPackage no QGIS e ele silenciosamente ficou gigantesco, o motivo é esse. O VACUUM é a resposta, e é seguro.

ArcGIS antigo engasga com os GeoPackages do GDAL. O GDAL 3.13 escreve GeoPackage 1.4 por padrão — lemos o user_version como 10400 e o application_id como a string ASCII GPKG. Produtos mais antigos da Esri esperam a era 1.0/1.1, cujo application_id é GP10 e cujo user_version é 0. Se o ArcMap ou um ArcGIS Pro mais velho recusar o seu arquivo, gere de novo com ogr2ogr -f GPKG out.gpkg in.gpkg -dsco VERSION=1.0 — rodamos exatamente isso e confirmamos que o application_id vira GP10 e o user_version cai para 0. O GDAL aceita 1.0, 1.1, 1.2, 1.3, 1.4 e AUTO.

Nomes de camada são nomes de tabela. O nome da camada vira um nome de tabela SQL, então uma camada chamada 2024 parcels (final) é um problema de aspas para o resto da vida. Use minúsculas, underscores, sem espaços, sem dígito no começo. Defina explicitamente com -nln.

O índice espacial não é garantido. O GDAL cria um por padrão — SPATIAL_INDEX tem padrão YES, e contamos 22 objetos rtree_* num arquivo normal de duas camadas. Passe -lco SPATIAL_INDEX=NO e você tem zero. Nós checamos. Arquivos produzidos por outras ferramentas, ou por alguém otimizando uma importação, podem não ter índice nenhum, e aí toda consulta espacial vira um full scan. Confira com sqlite3 file.gpkg "SELECT name FROM sqlite_master WHERE name LIKE 'rtree%';" — se vier vazio, esse é o seu mapa lento.

Não edite os blobs de geometria na mão. A coluna de geometria é WKB padrão embrulhado num pequeno cabeçalho binário do GeoPackage. Escreva nela com GDAL, QGIS ou uma extensão espacial do SQLite. Não construa os bytes você mesmo, a não ser que você goste de depurar geometrias inválidas.

Então: você deve migrar?

Sim, para qualquer coisa que seja sua — de olhos abertos.

Mantenha o GeoPackage como fonte da verdade. Exporte um Shapefile quando um cliente ou um portal exigir, e trate essa exportação como um render com perdas, do jeito que você trataria um JPEG de um arquivo de design em camadas. Nunca faça ida e volta pelo Shapefile esperando o seu schema de volta, porque os nomes dos campos não sobrevivem à viagem.

Se os seus dados vão para um navegador, eles não deveriam ser um GeoPackage para começo de conversa. Converta para GeoJSON, FlatGeobuf ou tiles.

Onde o Geodocs entra

A gente constrói o Geodocs, uma plataforma para times de dados de campo e de GIS, e escreveu este guia porque lida com as bordas afiadas desse formato todo dia. Nossos usuários sobem GeoPackages, Shapefiles, KML e GeoJSON, e a gente resolve exatamente os problemas acima para que eles não precisem — detectando o encoding do .dbf em vez de chutar, mantendo NULL distinto de vazio, e não truncando o nome de campo de ninguém em dez caracteres.

Se você prefere que o seu time pare de mandar Shapefiles de quatro arquivos por e-mail torcendo para o .prj ter chegado junto, é exatamente isso que a gente faz.

Trabalhando no sentido contrário? Nosso guia completo do formato Shapefile cobre, no mesmo nível de detalhe, o formato do qual você está migrando. E se você só precisa olhar um arquivo agora, temos um visualizador de Shapefile gratuito, direto no navegador, que não exige instalação nenhuma.

Achou um erro, ou uma armadilha que a gente deixou passar? Fala com a gente. Esta página é retestada, não copiada e colada.

Última verificação: 14 de julho de 2026.

Artigos Relacionados

Navegação