Coordenadas geográficas das cidades do Brasil

Muitas aplicações web e programas necessitam da localização (coordenadas geográficas) dos municípios do Brasil. Segue uma forma simples de conseguir uma lista grátis de latitude e longitude das cidades brasileiras.

O Instituto Brasileiro de Geografia e Estatística ou IBGE é uma fundação pública da administração federal brasileira criada em 1934. Tem atribuições ligadas às geociências e estatísticas sociais, demográficas e econômicas, o que inclui realizar censos e organizar as informações obtidas nesses censos para suprir órgãos das esferas governamentais federal, estadual e municipal, e para outras instituições e o público em geral.

Considerando o caráter público, é de se esperar que as informações geradas a partir da arrecadação dos contribuintes seja revertido em produtos gratuitos. Desse modo, o IBGE dispõe de um serviço de FTP aberto e gratuito para baixar diversas informações do seu âmbito de atuação. Nesse post, será mostrado o link para download das coordenadas (latitude, longitude e altitude) das cidades do Brasil gratuitamente. Para ver mais sobre o que são coordenadas geográficas e seus conceitos, clique no link.

O IBGE dispõe as coordenadas de várias localidades (chamadas cidades) no seguinte link em arquivo para download grátis: ftp://geoftp.ibge.gov.br/organizacao_do_territorio/estrutura_territorial/localidades/Google_KML/. Existem 5565 registros de cidades, que não é a mesma coisa que município! Para entender melhor, veja as seguintes definições:

  • Município – espaço territorial político dentro de um estado ou unidade federativa administrado por uma prefeitura. Pode possuir zona rural e/ou zona urbana.
  • Cidade – espaço urbano de um município delimitado por um perímetro urbano, com um número mínimo de habitantes e uma infraestrutura que atenda minimamente as condições dessa população, mesmo que essa cidade seja dependente de outras que se localizem próximas a ela.

Assim, um mesmo município pode ter várias cidades. Um distrito é uma divisão administrativa mais geral, que varia muito de tamanho e função. No caso do IBGE, é uma subdivisão de cidade. Veja o exemplo (colunas separadas por vírgula):

Estado,Município,Cidade/Localidade,Distrito,Longitude,Latitude,Altitude
CEARÁ,BEBERIBE,SUCATINGA,BARRA DA SUCATINGA,-38.0096121922668,-4.25330551817535,13.916229
CEARÁ,BEBERIBE,SUCATINGA,URUAÚ,-38.0451677843349,-4.22199237063619,15.083263
Imagem de satélite no programa Google Earth mostrando as localidades listadas acima
Imagem de satélite no programa Google Earth mostrando as localidades listadas acima

Note que os valores são dados em Graus Decimais, onde cada grau é dividido em frações decimais e os valores positivos são para o Norte (latitude) e o Leste (longitude) – o Sul e o Oeste são negativos. Esse sistema é mais fácil de ser utilizado pelos computadores (inclusive no Google Maps), em comparação com o tradicional sistema de Graus, Minutos e Segundos. A parte decimal do número é separada da parte inteira por ponto (tradicional nos EUA) em vez da vírgula (como estamos acostumados no Brasil) – geralmente a vírgula é indicada para separar campos de valores. A altitude é dada em metros a partir do nível do mar.

Para muitas aplicações, bastam a lista das cidades com suas respectivas coordenadas. Porém, o arquivo disponibilizado no link está em formato KML. Veja quais são os campos disponíveis no arquivo:

Nome do campoDescrição
IDContagem automática de geometrias ponto oriundas de setor
IDContagem automática de geometrias ponto oriundas de setor
CD_GEOCODIGOGeocódigo do setor (15 dígitos numéricos)
TIPOClassificação de Tipo (Urbano ou Rural, 6 dígitos alfa-numéricos)
CD_GEOCODBAGeocódigo do bairro (12 dígitos numéricos)
NM_BAIRRONome do bairro
CD_GEOCODSDGeocódigo do subdistrito (11 dígitos numéricos)
NM_SUBDISTRITONome do subdistrito
CD_GEOCODDSGeocódigo do distrito (9 dígitos numéricos)
NM_DISTRITONome do distrito
CD_GEOCODMUGeocódigo do Município (7 dígitos numéricos)
NM_MUNICIPIONome do Município
NM_MICRONome Microrregião
NM_MESONome Mesorregião
NM_UFNome da UF
CD_NIVELCódigo do Nível da Localidade
CD_CATEGORIACódigo da Categoria da Localidade
NM_CATEGORIANome da Categoria da Localidade
NM_LOCALIDADENome da Localidade
LONGLongitude da Localidade em grau decimal
LATLatitude da Localidade em grau decimal
ALTAltitude da Localidade, oriunda de SRTM em metros

O formato KML é muito útil para colocar a informação como uma camada sobre um mapa do Google Maps ou Google Earth, mas para trabalhar com os dados, seria melhor que estivesse em formato de tabela. O script a seguir resolve esse problema em duas linhas de shell script: a primeira baixa o arquivo para o diretório onde o comando for executado e o salva com o nome “coordenadas_BR.kml”; a segunda linha extrai a informação com o nome do estado, nome da localidade, nome do município, código IBGE e coordenadas, gravando o resultado no arquivo “coordenadas_BR.csv” (opção -O) no mesmo formato apresentado em exemplo anteriormente.

wget ftp://geoftp.ibge.gov.br/organizacao_do_territorio/estrutura_territorial/localidades/Google_KML/BR%20Localidades%202010%20v1.kml -O coordenadas_BR.kml
awk -F '[<>]' '$2~/NM_LOCALIDADE|CD_GEOCODMU|NM_MUNICIPIO|NM_UF|coordinates/ {print $3}' coordenadas_BR.kml | tail -n+13 | paste -d ',' - - - - - > coordenadas_BR.csv

O AWK é uma linguagem de programação interpretada muito usada para processar textos em conjunto com o shell script. A opção -F define um delimitador de texto, especificado dentro de aspas simples – no caso, o delimitador são os sinais de menor que OU maior que. O segundo texto delimitado por aspas simples indica os caracteres/palavras que devem conter na linha a ser extraída, separados por pipe; o comando print dentro de chaves indica a impressão do terceiro termo ($3) separado pelos delimitadores definidos anteriormente. Depois, vem o nome do arquivo.

O resultado dessa linha é enviado através do pipe para o comando tail, que irá exibir todas as linhas exceto as 13 primeiras, que estão relacionadas a um cabeçalho do arquivo. Um novo pipe envia o resultado par ao comando paste, que irá imprimir os campos usando a vírgula como delimitador (definido pela opção -d) em quatro colunas (definidas pelo quatro traços separados por espaço). Caso queira os resultados por estado, por exemplo, é possível acrescentar outro pipe para o comando “grep nome_do_estado”.

Caso queira selecionar somente os municípios, é possível usar o shell script abaixo para selecionar somente as linhas que o campo “NM_LOCALIDADE” for igual ao campo “NM_MUNICIPIO” do arquivo gerado acima.

#!/bin/bash

rm -f temp; touch temp
while read line; do
	cod_ibge=$(echo $line | awk -F',' '{print $6}')
	municipio=$(grep $cod_ibge',' coordenadas_BR.csv | head -1 | awk -F',' '{print $2}')
	localidade=$(grep $cod_ibge',' coordenadas_BR.csv | head -1 | awk -F',' '{print $4}')
	if [ "$lacalidade" == "$municipio" ]; then
		lat=$(grep $cod_ibge',' coordenadas_BR.csv | head -1 | awk -F',' '{print $6}')
		lon=$(grep $cod_ibge',' coordenadas_BR.csv | head -1 | awk -F',' '{print $5}')
		echo $line','$lat','$lon >> temp
	else
		echo $line',' >> temp
	fi
done < lista_municipios.csv

Curiosidade: para efeitos de dimensionar o campo com o nome de cidade em uma base de dados, considere que a cidade com o maior nome do Brasil é São José do Vale do Rio Preto, com 29 caracteres (contando os espaços entre as palavras).

Fontes

13 comments

    1. Oi Fernando. Parece que o IBGE reorganizou os diretórios do FTP público deles em junho desse ano, mas como eles permitem listar os arquivos, consegui atualizar o link no post. Se subir um nível na hierarquia de pastas, tem opções SHP e MDB, além do KML.

      Obrigado por avisar!

  1. Vinicius, obrigado pelas dicas, ajudou muito. Uma dúvida que tenho: para selecionar os municípios, não bastaria apenas um comando awk como esse:

    awk -F , ‘{if ($2==$4) print}’ coordenadas_BR.csv > cidades_BR.csv

    Acho que fica mais simples que todo o script que você sugeriu, mas não tenho certeza se são equivalentes.
    Obrigado!

    1. Oi Gabriel, que bom que o post ajudou.Esse comando é basicamente equivalente ao código que coloquei, está bem mais elegante. Faz anos que tinha feito esse script. Obrigado pela dica!

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.