Shapefile no lugar errado (ou no oceano): o .prj ausente
Resposta curta: o arquivo não tem .prj, então nada sabe o que os seus números significam. O .shp guarda doubles nus; o .prj ao lado dele é a única coisa que diz se eles são graus ou metros UTM. Sem ele, o GDAL não imprime nenhum sistema de coordenadas, o QGIS pergunta por um CRS, e o visualizador do navegador assume WGS 84 e avisa isso — o que coloca um arquivo geográfico no lugar certo e um arquivo UTM fora da borda do mundo, com a mesma mensagem nos dois casos. A seguir: como saber qual dos dois você tem só pelos números, e as duas linhas de ogr2ogr que resolvem isso, que não são intercambiáveis.
Tudo foi testado em 16 de setembro de 2026 com o GDAL 3.13.3 e o shapefile-viewer na versão static-page-tools@442f8d8, com a sua mensagem de setembro de 2026 para arquivos sem .prj, ainda não lançada no momento em que este texto foi escrito. O dataset é a malha de 2022 do IBGE dos 27 estados brasileiros em coordenadas geográficas SIRGAS 2000, convertida uma vez para SIRGAS 2000 / UTM zona 23S, de forma que os mesmos 27 polígonos existem em graus e em metros. O guia do Shapefile cobre esse arquivo-satélite em "Se o .prj estiver faltando"; este post é a reprodução e a correção.
Três ferramentas, três comportamentos
GDAL não chuta: o ogrinfo -so na camada UTM com o .prj apagado ainda reporta Feature Count: 27 e a extensão em metros, e depois imprime Layer SRS WKT: com (unknown) na linha seguinte. O QGIS, com a sua configuração padrão de CRS, pergunta por um CRS quando você adiciona a camada. O visualizador lê os números como graus WGS 84 e acrescenta um aviso na linha da camada. O aviso é novo — ainda não estava lançado quando isto foi escrito e é publicado antes deste post — mas o chute não é: um zip sem .prj sempre foi lido como graus; o que mudou é que agora a linha avisa.
Quatro variações no visualizador
Cada variação foi solta no visualizador e exportada com Exportar GeoJSON; o primeiro vértice do Acre nessa exportação é o oráculo de posição, porque é a própria geometria desenhada pelo visualizador projetada de volta para graus.
- Zip UTM com seu
.prj: a linha lê27 polígonos, o mapa mostra o Brasil, e o primeiro par da exportação é[-68.7928173712301, -10.999569659337354]. O-t_srs EPSG:4326do GDAL para o mesmo vértice dá[-68.792817347, -10.999569268]. O vértice do visualizador fica a 0,0436 m do vértice do GDAL — os dois tratam SIRGAS 2000 → WGS 84 como uma transformação nula (o PROJ avalia isso em 1 m:EPSG:15894,+proj=noop), e os 4 cm são inteiramente da própria grade de desenho de 0,2 m do visualizador: o vértice exportado em Web Mercator é um múltiplo exato de 0,2 m nos dois eixos. - O mesmo zip sem o seu
.prj: a linha lê27 polígonos · CRS desconhecido — assumindo WGS 84, o mapa base continua visível, e nada é desenhado onde o Brasil deveria estar. O primeiro par da exportação é[-2171693.959168141, -53.911070387188786]: a longitude exportada é a sua easting, dígito por dígito — o.shparmazena-2171693.959168141, 8673426.088929612para esse vértice — e a latitude é um artefato da matemática de Mercator, que é periódica na northing e devolveu um valor que parece uma latitude real na Patagônia. Uma easting de −2.171.693 lida como graus cai cerca de 6.032 vezes ao redor do planeta, para o oeste. A mensagem é o único indício, porque o mapa parece normal. - Os mesmos três arquivos soltos, não zipados: idêntico ao zip — a mesma linha, o mesmo mapa transparente, uma exportação byte a byte idêntica. Essa paridade também é nova: até a mudança de setembro de 2026, arquivos soltos sem
.prjeram desenhados como metros brutos em Web Mercator sobre uma tela cinza com o mapa base oculto, o que colocava um arquivo em graus numa caixa de 45 m por 39 m junto à origem, irreconhecível e sem nenhuma mensagem. - O arquivo geográfico sem o seu
.prj: a linha traz o mesmo aviso, e a forma está no Brasil. O primeiro par da sua exportação é[-68.7928173712301, -10.999569659337354], bit a bit o mesmo par do zip original do IBGE. Funciona, e o visualizador avisa que chutou: o chute está certo porque graus é o que o arquivo contém, e a mensagem existe para que um chute com sorte não seja confundido com um CRS conhecido.
Como saber o CRS de um arquivo sem .prj
Olhe os números antes do mapa. Valores dentro de ±180 e ±90 são graus, e o chute do visualizador está certo. Valores de seis ou sete dígitos são metros projetados, e o chute está errado: uma easting UTM dentro da sua zona fica entre 166.000 e 834.000, uma northing do hemisfério sul chega a 10.000.000 por causa da false northing, e um arquivo que atravessa várias zonas, como este, tem eastings que ficam negativas ou passam de um milhão (nesta camada, de −2.839.536 a 2.201.621). Metros em Web Mercator chegam a cerca de 20.037.508. Exportar e olhar é um diagnóstico de um passo só: se o visualizador diz que assumiu WGS 84 e a longitude exportada é um número de seis ou sete dígitos, isso é a sua easting, e o arquivo estava projetado. Depois, encontre a zona — o guia de códigos EPSG lista os códigos do Brasil e da América Latina.
Atribuir ou reprojetar: dois comandos, dois verbos
Atribuir diz o que os números já são; reprojetar muda os números. No arquivo cujo ogrinfo -so imprimiu (unknown) sob Layer SRS WKT:, o ogr2ogr -a_srs EPSG:31983 fixed.shp in.shp escreve um .prj e não move nada: o ogrinfo -so no resultado imprime PROJCRS["SIRGAS 2000 / UTM zone 23S" terminando em ID["EPSG",31983], a extensão continua igual, e o primeiro vértice ainda é -2171693.95916814 8673426.08892961. Solto no visualizador, o arquivo com o CRS atribuído cai no Brasil com a linha de volta a 27 polígonos e sem aviso. O ogr2ogr -s_srs EPSG:31983 -t_srs EPSG:4326 out.shp in.shp faz o outro trabalho: -s_srs é o que o .prj que falta teria dito, -t_srs é para onde você quer ir, e o ogrinfo -so do resultado mostra GEOGCRS["WGS 84" com a extensão em graus e o primeiro vértice em -68.792817347 -10.999569268 — o double armazenado no arquivo de origem, recuperado. Atribua um arquivo que já está em graus e você mentiu para ele; reprojete com o -s_srs errado e cada vértice se move para um lugar errado que agora tem um .prj como aval. Confira o código antes: gdalsrsinfo -o wkt1 EPSG:31983 | grep -m1 -o '^\(GEOGCS\|PROJCS\)\["[^"]*"' imprime PROJCS["SIRGAS 2000 / UTM zone 23S"; o vizinho 31984 imprime a zona 24S.
Se o visualizador diz que assumiu WGS 84 e a forma não está onde deveria, corrija o .prj antes de exportar — e se você já exportou, a coluna da longitude é a sua easting, sem alteração.
A mesma falha no GeoJSON
Um GeoJSON com um membro crs nomeando EPSG:31983 falha da mesma forma no navegador: o membro não é entendido, a transformação é ignorada, e o primeiro vértice do Acre é exportado em [-19.5086591263066, 61.20664023081724], no Atlântico Norte — o guia de GeoJSON explica em "O membro CRS desapareceu" por que o formato não tem mais esse membro.
Arquivos de teste que você pode usar
O dataset é a malha estadual de 2022 do IBGE, 13.717.460 bytes, SHA-256 282ec7f0f0beeeead45e6609f4ffffce161bda04cb8ee0afcad2316d1c841bcb; a listagem do diretório não imprime nenhuma linha de licença, então credite o IBGE e confira os termos do portal antes de republicar.
Para gerar a variante quebrada, projete o arquivo com ogr2ogr -f "ESRI Shapefile" -t_srs EPSG:31983 -lco ENCODING=UTF-8 utm/BR_UF_2022_utm.shp BR_UF_2022.shp, depois apague utm/BR_UF_2022_utm.prj e solte os outros três arquivos no visualizador, zipados ou soltos. O -lco ENCODING=UTF-8 está ali por um motivo fora deste post: sem ele o ogr2ogr escreve uma tabela de atributos em Latin-1 sem .cpg, e os acentos nos nomes dos estados quebram no navegador — um problema de .cpg, não de .prj.
Para times
Um .prj se perde num anexo de chat, numa pasta copiada, numa exportação que nunca escreveu um — e o mapa que recebe o arquivo não pode perguntar para quem enviou. O Geodocs mantém o sistema de coordenadas junto com os dados num mapa compartilhado, então o time desenha e coleta num único CRS e a pergunta só aparece na exportação, quando você já sabe a resposta.