4 minuto(s) de leitura

A API do IBGE possibilita baixar os dados diretamente para o script. Para baixar as malhas, ou seja, informações geoespaciais, é possivel baixar os dados em três diferentes formatos:

  • ?formato=application/vnd.geo+json, para baixar os dados em GeoJson;
  • ?formato=application/json, para baixar os dados em TopoJson;
  • ?formato=image/svg+xml, para baixar os dados em SVG;

É possível definir a resolução que, na prática, refere-se ao nível de detalhamento do dado obtido.

  • ?resolucao=0, Nenhuma divisão político-administrativa é inserida no interior da malha
  • ?resolucao=1, Inclui na malha as macrorregiões. Válido apenas quando a localidade for BR.
  • ?resolucao=2, Inclui na malha as Unidades da Federação. Válido apenas quando a localidade for BR ou uma macroregião
  • ?resolucao=3, inclui na malha as mesorregiões. Válido apenas quando a localidade for BR, macroregião ou Unidade da Federação
  • ?resolucao=4, Inclui na malha as microrregiões. Válido apenas quando a localidade for BR, macroregião, Unidade da Federação ou mesorregião
  • ?resolucao=5, inclui na malha os municípios

E a qualidade.

  • ?qualidade=1, pior qualidade;
  • ?qualidade=2, razoável qualidade;
  • ?qualidade=3, boa qualidade;
  • ?qualidade=4, melhor qualidade;

Aviso: Esse post tem a finalidade de mostrar os comandos básicos e me deixar com uma “cola” rápida para meu uso cotidiano. Todas os códigos são exemplificativos e podem/devem ser alterados, indicando o nome dos arquivos e diretórios corretamente.

Nota: É possível acessar esse post em formato pdf, diretamente por meio do repositório do GitHub ou ainda, de maneira interativa, usando o Binder.


Pastas: início do projeto

Inicialmente faz-se necessário criar uma pasta que receberão os dados.

# %load '~/Documents/SourceCode/codes/files/create_folders.py'
def create_folders(path, folders=['data', 'docs', 'maps']):
    """
    :param folders: Name os folders that you want create; E.g.: ['folder1', 'folder2']
    :return: Create directories if not exist
    """
    # Import Packages
    import os
    for folder in folders:
        directory=os.path.join(path, folder)
        try:
            if not os.path.exists(directory):
                os.makedirs(directory)
                print('Directory "', directory, '" created!', sep='')
            else:
                print('Directory "', directory, '" already exists...', sep='')
        except OSError:
            print('Error: Creating directory "', directory, '" fail.', sep='')

create_folders('')
Directory "data" already exists...
Directory "docs" already exists...
Directory "maps" already exists...

Com a estrutura de pastas criada, é possivel fazer o download dos arquivos disponiblizados pelo IBGE. Há uma infinidade de dados e ainda, há a API do SIDRA que possibilita obter mais dados.

import os
import urllib.request
import shutil

url = 'https://servicodados.ibge.gov.br/api/v2/malhas/35/?resolucao=5&formato=application/vnd.geo+json&qualidade=4'
#url = 'http://servicodados.ibge.gov.br/api/v1/localidades/estados/35/municipios/?formato=application/vnd.geo+json/?resolucao=5'

filename = os.path.join('data', 'divadmin_sp.json')

# Download the file from 'url' and save it locally under 'filename'
with urllib.request.urlopen(url) as response, open(filename, 'wb') as out_file:
       shutil.copyfileobj(response, out_file)

Enfrentei problemas com o encoding do arquivo baixado. COm a função abaixo é possivel conferir que o encoding está correto (ascii) para dar continuidade.

# %load '~/Documents/SourceCode/codes/files/predict_encoding.py'
def predict_encoding(file_path, n_lines=30):
    """
    ssss
    :param file_path:
    :param n_lines:
    :return:
    """
    import chardet

    # Open the file as binary data
    with open(file_path, 'rb') as f:
        # Join binary lines for specified number of lines
        rawdata = b''.join([f.readline() for line in range(n_lines)])

    return chardet.detect(rawdata)['encoding']

# file_encoding = predict_encoding('./data.csv')
# print(file_encoding)
# df = pd.read_csv('./data.csv', delimiter=';', encoding=file_encoding)

file_encoding = predict_encoding(filename)
print(file_encoding)
ascii
import folium

# Cria o mapa
webmap = folium.Map(
    location=[-23.9619271,-46.3427499],
    zoom_start=8
)

folium.GeoJson(filename, name='Trajetos').add_to(webmap)

webmap

Uma vez com o mapa na mão, de qualquer que seja o meio que foi obtido, é possivel analisar a “tabela de atributos”. Lá descobrimos que existe o par de coordenadas que define o centroide e, ainda, o ‘codarea’ que tem o código do IBGE do município.

Missão é: Renomear o campo. Dar joins entre jsons plotar colorido!

#url = 'http://portalgeo.seade.gov.br/wp-content/uploads/2019/03/LimiteMunicipal_IGC.zip'
# Se lê certo, no notepad aparecer UTF-8 BOM WO


Exportando o Juptyter Notebook para outros formatos

O arquivo .ipynb pode ser exportado em formatos diversos. Abaixo carrego uma função que escrevi para facilitar o processo de exportação do arquivo em diferentes locais do PC para, posteriormente, atualizar os repositórios contidos no GitHub.

# %load '~/Documents/SourceCode/codes/files/export_jupyter.py'
def export_jupyter(path, extensions=['html', 'markdown', 'latex', 'pdf', 'python'], today=True):
    """
    Export .ipynb file to others formats
    :return: File in other formats
    """
    # Import Packages
    import os
    import datetime

    # Data
    timestamp = datetime.datetime.now()
    srt_today = (str(timestamp.year) + '-' +
                 str(f"{timestamp.month:02d}") + '-' +
                 str(f"{timestamp.day:02d}"))

    # Extensions
    for extension in extensions:
        if today==True:
            os.system('jupyter nbconvert --to {} {} --output {}'.
                      format(extension, get_jupyternotebook_name(),
                             os.path.join(path, srt_today+'-'+get_jupyternotebook_name().split('.')[0])))
            print('Arquivo {} exportado corretamente para o formato {} usando prefixo da data.'.
                  format(get_jupyternotebook_name(), extension))

        else:
            os.system('jupyter nbconvert --to {} {} --output {}'.
                      format(extension, get_jupyternotebook_name(),
                             os.path.join(path, get_jupyternotebook_name().split('.')[0])))
            print('Arquivo {} exportado corretamente para o formato {} sem usar prefixo da data.'.
                  format(get_jupyternotebook_name(), extension))

# %load '~/Documents/SourceCode/codes/files/get_jupyternotebook_name.py'
def get_jupyternotebook_name():
    """
    Returns the name of the current notebook as a string
    From https://mail.scipy.org/pipermail/ipython-dev/2014-June/014096.html
    :return: Returns the name of the current notebook as a string
    """
    # Import Packages
    from IPython.core.display import Javascript
    from IPython.display import display

    display(Javascript('IPython.notebook.kernel.execute("theNotebook = " + \
    "\'"+IPython.notebook.notebook_name+"\'");'))

    # Result
    return theNotebook

Com as funções para exportar o Jupyter Notebook e para obter o nome do arquivo .ipynb carregadas, basta exportar o arquivo, inicialmente para a pasta docs dentro do projeto e também, visando atualizar os posts do site, para a respectiva pasta.

export_jupyter('docs',['pdf'], False)
export_jupyter('/home/michel/Documents/SourceCode/michelmetran.github.io/_posts', ['markdown'], True)
<IPython.core.display.Javascript object>



<IPython.core.display.Javascript object>



<IPython.core.display.Javascript object>


Arquivo api_ibge.ipynb exportado corretamente para o formato pdf sem usar prefixo da data.



<IPython.core.display.Javascript object>



<IPython.core.display.Javascript object>



<IPython.core.display.Javascript object>


Arquivo api_ibge.ipynb exportado corretamente para o formato markdown usando prefixo da data.


Atualizando Repositórios

Após as exportações dos arquivos nos formatos necessários, basta atualizar o repositório diretamente pelo Jupyter Notebook. Abaixo é atualizado o repositório desse projeto específico, bem como a derivação desse projeto no site.

%run '~/Documents/SourceCode/codes/git/update_github.py'
git_full('/home/michel/Documents/SourceCode/api_ibge', '.', 'Atualizando')
git_full('/home/michel/Documents/SourceCode/michelmetran.github.io', '.', 'Atualizando')
b'' b''
b'[master 098a00f] Atualizando\n 2 files changed, 110 insertions(+), 470 deletions(-)\n delete mode 100644 .ipynb_checkpoints/api_ibge-checkpoint.ipynb\n' b''
b'' b'To github.com:michelmetran/api_ibge.git\n   0684fb4..098a00f  master -> master\n'
Done!!
b'' b''
b"On branch master\nYour branch is up to date with 'origin/master'.\n\nnothing to commit, working tree clean\n" b''
b'' b'Everything up-to-date\n'
Done!!

Requirements

Abaixo é criado o arquivo requirements.txt na raiz do projeto para possibilitar o correto funcionamento do Jupyter Notebook no My Binder. Após a criação do arquivo, sugere-se a edição manual, visando manter apenas os packages realmente essenciais, listados com o comando import no início do script.

#pip freeze > requirements.txt