# FBDS Map Data Extractor / Extrator de Datas dos Mapas FBDS
FBDS Map Data Extractor / Extrator de Datas dos Mapas FBDS
Automated Releases / Publicações Automáticas
GitHub Actions workflows included:
ci.yml: lint (ruff,black --check), tests (pytest), build &twine checkon pushes and PRs.release.yml: manual dispatch with a version bump (patch,minor,major) that updatespyproject.tomland fallback version inextrator_fbds/__init__.py, commits and creates a tagvX.Y.Z. Any push of a tag matchingv*triggers build and publish to PyPI.
To enable PyPI publishing, add a repository secret PYPI_API_TOKEN containing a PyPI API token (username __token__).
This Python package asynchronously downloads geospatial data from the public FBDS repository (geo.fbds.org.br) and performs OCR on MAPAS images to extract two key metadata fields: ANO_BASE (image/satellite year) and ANO_SIRGAS (datum year). It offers CLI commands for scraping and batch OCR (sequential and multiprocessing) plus easy integration with Airflow for scheduled pipelines.
Resumo em Português: Este pacote Python faz download assíncrono de geodados do repositório público da FBDS (geo.fbds.org.br) e executa OCR em imagens de MAPAS para extrair dois metadados principais: ANO_BASE (ano da imagem/satélite) e ANO_SIRGAS (ano do datum). Inclui comandos de CLI para scraping e OCR em lote (sequencial e multiprocessing) e integração simples com Airflow para execuções agendadas.
Extração de datas (ANO BASE / SIRGAS) a partir dos MAPAS da FBDS
Este pacote Python fornece ferramentas para:
- Download assíncrono de geodados do site geo.fbds.org.br
- OCR (reconhecimento óptico de caracteres) em imagens de mapas para extrair metadados
- Integração com Airflow para execuções periódicas e automatizadas
Dados extraídos por OCR das imagens em MAPAS:
- ANO_BASE – ano da imagem/satélite (ex.:
2012emImagens Rapideye - Ano 2012) - ANO_SIRGAS – ano do datum (ex.:
2000emDatum SIRGAS 2000) - FULL – texto completo reconhecido na área de interesse (limpo para caber bem em CSV)
Os resultados são gravados em arquivos CSV (fbds_mapas_ocr.csv e
fbds_mapas_ocr_mp.csv).
Instalação
Como pacote Python (recomendado para Airflow)
# Instalação direta do repositório
pip install git+https://github.com/CEPAD-IFSP/extrator_fbds.git
# Ou em modo editável para desenvolvimento
git clone https://github.com/CEPAD-IFSP/extrator_fbds.git
cd extrator_fbds
pip install -e .
Dependências do sistema
É necessário ter o Tesseract OCR instalado:
# Ubuntu/Debian
sudo apt-get update
sudo apt-get install tesseract-ocr tesseract-ocr-por
# Outras distribuições: consulte a documentação do Tesseract
Uso
1. Linha de comando (CLI)
Após a instalação, três comandos ficam disponíveis:
# Scraper assíncrono
fbds-scraper --help
# OCR sequencial
fbds-ocr --help
# OCR paralelo (multiprocessing)
fbds-ocr-mp --help
2. Uso programático (Python/Airflow)
import asyncio
from pathlib import Path
from extrator_fbds import FBDSAsyncScraper
from extrator_fbds.run_fbds_ocr_batch_mp import run_batch_mp
# Download de dados
async def download_example():
scraper = FBDSAsyncScraper(
download_root=Path("/data/fbds"),
max_concurrency=8,
city_concurrency=3,
)
results = await scraper.download_all(
state_filter=["SP", "MG"],
folder_filter=["MAPAS"],
)
scraper.save_exceptions()
return results
# Executar
results = asyncio.run(download_example())
# OCR batch
run_batch_mp(
download_root=Path("/data/fbds"),
output_csv=Path("/data/results/ocr_output.csv"),
max_workers=4,
)
3. Integração com Airflow
Veja o exemplo completo em examples/airflow_dag_example.py.
Instalação no ambiente Airflow:
# No ambiente Python do Airflow
pip install git+https://github.com/CEPAD-IFSP/extrator_fbds.git
Exemplo simplificado de DAG:
from airflow import DAG
from airflow.operators.python import PythonOperator
from extrator_fbds import FBDSAsyncScraper
from extrator_fbds.run_fbds_ocr_batch_mp import run_batch_mp
import asyncio
def download_task():
scraper = FBDSAsyncScraper(download_root="/data/fbds")
asyncio.run(scraper.download_state("SP", folder_filter=["MAPAS"]))
scraper.save_exceptions()
def ocr_task():
run_batch_mp(download_root="/data/fbds", output_csv="/data/results.csv")
with DAG("fbds_monthly", schedule_interval="@monthly") as dag:
download = PythonOperator(task_id="download", python_callable=download_task)
ocr = PythonOperator(task_id="ocr", python_callable=ocr_task)
download >> ocr
Componentes do pacote
Módulos principais
-
extrator_fbds.fbds_coreFBDSAsyncScraper: classe principal para download assíncrono- Lista estados e cidades diretamente do site
geo.fbds.org.br - Baixa recursivamente arquivos de
APP,HIDROGRAFIA,MAPAS,USO, etc. - Mantém a estrutura de diretórios do site
- Registra exceções em
exceptions.json
- Lista estados e cidades diretamente do site
-
extrator_fbds.fbds_async_scraper- Interface de linha de comando (CLI) para o scraper
- Comando:
fbds-scraper
-
extrator_fbds.fbds_ocrextract_year_and_datum(image_path): função OCR para extrair metadados de uma imagem
-
extrator_fbds.run_fbds_ocr_batchrun_batch(): processamento OCR sequencial- Comando:
fbds-ocr
-
extrator_fbds.run_fbds_ocr_batch_mprun_batch_mp(): processamento OCR paralelo (multiprocessing)- Comando:
fbds-ocr-mp
Parâmetros do scraper CLI
-
--base-url(opcional)- URL raiz do repositório FBDS (padrão:
https://geo.fbds.org.br/)
- URL raiz do repositório FBDS (padrão:
-
--output(opcional)- Pasta onde os arquivos serão salvos (padrão:
downloads)
- Pasta onde os arquivos serão salvos (padrão:
-
--max-concurrency(opcional)- Número máximo de downloads simultâneos por arquivo (padrão:
5) - Valores maiores aceleram o download, mas podem sobrecarregar a conexão/servidor
- Número máximo de downloads simultâneos por arquivo (padrão:
-
--city-concurrency(opcional)- Número de cidades processadas em paralelo (padrão:
1) - Permite processar múltiplas cidades simultaneamente
- Número de cidades processadas em paralelo (padrão:
-
--folders(opcional)- Lista de pastas de topo a baixar para cada cidade
- Exemplo:
--folders APP MAPASbaixa apenas as pastasAPPeMAPAS
-
--exceptions(opcional)- Caminho do arquivo JSON onde o log de exceções será salvo/lido
- Se não informado, usa
downloads/exceptions.json
-
--retry-failures- Em vez de fazer um novo scrape, lê o
exceptions.jsone tenta novamente apenas os downloads/requisições que falharam
- Em vez de fazer um novo scrape, lê o
Comandos de listagem/inspeção:
-
--list-states- Lista os códigos de estados disponíveis
-
--list-cities UF-
Lista as cidades de uma UF, por exemplo:
fbds-scraper --list-cities SP
-
-
--describe-city UF CIDADE- Mostra a estrutura de pastas/arquivos para uma cidade específica
Comandos de download (usar um de cada vez):
-
--download-city UF CIDADE1 [CIDADE2 ...]Exemplo: baixar apenas
APPeMAPASpara duas cidades específicas:fbds-scraper \ --download-city SP SAO_PAULO SANTOS \ --folders APP MAPAS \ --max-concurrency 5
-
--download-state UFExemplo: baixar todas as cidades de
SP, somente pastaMAPAS:fbds-scraper \ --download-state SP \ --folders MAPAS \ --max-concurrency 8 \ --city-concurrency 3
-
--download-allBaixa todos os estados disponíveis. Pode ser combinado com
--statespara filtrar alguns estados.Exemplo: baixar apenas
SPeMG, todas as pastas padrão:fbds-scraper \ --download-all \ --states SP MG \ --max-concurrency 8 \ --city-concurrency 3
Exemplo de uso do --retry-failures após falhas:
fbds-scraper --retry-failures --exceptions downloads/exceptions.json
Exemplos de uso detalhados
Download via CLI
Listar estados disponíveis:
fbds-scraper --list-states
Listar cidades de um estado:
fbds-scraper --list-cities SP
Ver estrutura de uma cidade:
fbds-scraper --describe-city SP SAO_PAULO
Baixar apenas MAPAS para todas as cidades de SP:
fbds-scraper \
--download-state SP \
--folders MAPAS \
--max-concurrency 8 \
--city-concurrency 3
Baixar APP + MAPAS para SP, MG, RJ:
fbds-scraper \
--download-all \
--states SP MG RJ \
--folders APP MAPAS \
--max-concurrency 10 \
--city-concurrency 4
OCR via CLI
Processamento sequencial:
fbds-ocr
# Usa defaults: downloads/ como entrada, fbds_mapas_ocr.csv como saída
Processamento paralelo (recomendado):
fbds-ocr-mp
# Usa defaults: downloads/ como entrada, fbds_mapas_ocr_mp.csv como saída
Com variável de ambiente:
export DOWNLOAD_ROOT=/data/fbds/downloads
fbds-ocr-mp
Detalhes técnicos do OCR
A função extract_year_and_datum(image_path):
- Abre a imagem com Pillow (
PIL.Image) - Recorta a região inferior direita (onde ficam as legendas da FBDS)
- Roda Tesseract via
pytesseractpara extrair o texto - Usa regex para encontrar:
ANOouANO BASEseguido de 4 dígitos (qualquer combinação de maiúsculas/minúsculas)SIRGASseguido de 4 dígitos
- Retorna um dicionário:
{"ano": "2012" | None, "sirgas": "2000" | None, "raw_text": texto_original}
Os scripts run_batch() e run_batch_mp():
- Percorrem a árvore de downloads procurando imagens
.jpg/.jpegemMAPAS:downloads/UF/CIDADE/MAPAS/*.jpg
- Para cada imagem, chamam
extract_year_and_datume gravam uma linha no CSV- Colunas:
ESTADO, CIDADE, ANO_BASE, ANO_SIRGAS, FULL
- Colunas:
- Versão
_mpusaProcessPoolExecutorpara paralelizar
português. Em distribuições baseadas em Debian/Ubuntu, por exemplo:
sudo apt-get update
sudo apt-get install tesseract-ocr tesseract-ocr-por
Em outras distribuições, procure pelos pacotes equivalentes ou instale a partir do site oficial do Tesseract.
Estrutura de diretórios
Após o download, os dados seguem a estrutura:
downloads/
SP/
ADAMANTINA/
MAPAS/
SP_3500105_APP.jpg
SP_3500105_HIDROGRAFIA.jpg
SP_3500105_RGB532.jpg
SP_3500105_USO_DO_SOLO.jpg
...
MG/
...
Ajustando paralelismo/concorrência
Você pode acelerar os downloads ajustando dois parâmetros:
--max-concurrency: número de requisições/arquivos em paralelo (nível por arquivo)--city-concurrency: número de cidades processadas em paralelo (nível por cidade)
Recomendações gerais:
- Comece com valores moderados e aumente aos poucos.
- Se notar muitos timeouts ou instabilidade, reduza um pouco.
- Combine com
--folders MAPASquando o objetivo for apenas o OCR dos mapas (reduz o volume total).
Exemplos para um estado (SP):
-
Mais conservador (máquina/rede modestas):
python scripts/fbds_async_scraper.py \ --download-state SP \ --folders MAPAS \ --max-concurrency 3 \ --city-concurrency 1
-
Intermediário (bom equilíbrio):
python scripts/fbds_async_scraper.py \ --download-state SP \ --folders MAPAS \ --max-concurrency 8 \ --city-concurrency 3
-
Mais agressivo (use com cautela):
python scripts/fbds_async_scraper.py \ --download-state SP \ --max-concurrency 12 \ --city-concurrency 6
Exemplos para Brasil (todos os estados ou um conjunto grande):
-
Intermediário, filtrando alguns estados:
python scripts/fbds_async_scraper.py \ --download-all \ --states SP MG RJ ES \ --folders MAPAS \ --max-concurrency 8 \ --city-concurrency 3
-
Todos os estados, foco completo (sem filtrar pastas):
python scripts/fbds_async_scraper.py \ --download-all \ --max-concurrency 10 \ --city-concurrency 4
Se a execução for interrompida ou ocorrerem falhas pontuais (timeouts etc.), é possível retomar apenas o que falhou usando o log de exceções:
python scripts/fbds_async_scraper.py --retry-failures --exceptions downloads/exceptions.json
2. Versão sequencial (single process) do OCR
Roda em um único processo; é mais simples de depurar e mais leve em termos de uso de CPU.
Comando:
python scripts/run_fbds_ocr_batch.py
- Pasta padrão de entrada:
downloads/no diretório do repositório. - Saída:
fbds_mapas_ocr.csvna raiz do repositório.
Durante a execução, o script imprime algo como:
Scanning MAPAS JPEGs under: /caminho/para/downloadsProcessed 50 images so far...Done. Wrote 1234 rows to /caminho/para/fbds_mapas_ocr.csv
3. Versão multiprocessada (usa todos os cores)
Roda várias instâncias do Tesseract em paralelo, usando até os.cpu_count()
processos. Ideal quando há muitas imagens e você quer reduzir o tempo total.
Comando:
python scripts/run_fbds_ocr_batch_mp.py
Formato de saída (CSV)
Os scripts de OCR escrevem CSVs com as colunas:
ESTADO– código da UF (ex.:SP,MG)CIDADE– nome da cidade (como aparece na estrutura de diretórios)ANO_BASE– ano extraído da legenda (ANOouANO BASEseguido de 4 dígitos)ANO_SIRGAS– ano do datum extraído deSIRGAS XXXXFULL– texto completo da legenda usado para o OCR, mas normalizado:- quebras de linha substituídas por espaços
- múltiplos espaços colapsados em um só
- vírgulas removidas
- aspas duplas (
") trocadas por aspas simples (')
Metadata
Release files for extrator-fbds 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| extrator_fbds-0.1.2.tar.gz | 24.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| extrator_fbds-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 45.7 kB
Release files / extrator_fbds-0.1.2.tar.gz
| Download URL | extrator_fbds-0.1.2.tar.gz |
|---|---|
| Size | 24.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
56fc214bb54f04f79a6a1a92d0f8c590429fd43f2f8299ad0d11f811a4994c39
|
|
BLAKE2b-256 checksum How to use checksums |
309319f9ae8071b91ec9b78f085ad4c9c92a814226884dc3a6095af07b0eef43
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / extrator_fbds-0.1.2-py3-none-any.whl
| Download URL | extrator_fbds-0.1.2-py3-none-any.whl |
|---|---|
| Size | 21.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
04bdf701c60db9c34f0731a4ebd10c0cf8e23e594122e438a4698f669f1f1ad4
|
|
BLAKE2b-256 checksum How to use checksums |
779d6d7d82ebdf396b414db7fcfec46c0916a0a4ae3618ccf0357cc82a8bed94
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|