SIG-Bus — Plugin QGIS para Análise de Transporte Público¶
Português | English
Plugin do QGIS que integra dados GTFS (General Transit Feed Specification) com dados de demanda de embarque por ponto de ônibus, permitindo visualizar e alocar a carga de passageiros ao longo dos traçados das linhas.
Desenvolvido no contexto do projeto de Iniciação Científica PIBIC DPPG 113/2021.
Funcionalidades¶
O leitor de GTFS é embutido (gtfs_reader.py), adaptado do plugin
GTFS Loader do CTU GeoForAll Lab (GPL v2+). Nenhum plugin externo é
necessário.
Análise de demanda¶
- Verificar GTFS: valida o
.zipe sintetizacalendar.txta partir decalendar_dates.txtquando necessário. - Executar GTFS: importa o feed para um GeoPackage via GDAL (streaming —
eficiente em memória para feeds grandes). Constrói a camada de linhas
(
shapes) e cria índices de join. - Inserir demanda: importa CSV de embarque por ponto/hora para GeoPackage
(
sigt.gpkg). - Filtrar dados: a partir da linha selecionada (
route_short_name), destaca o traçado emshapes, filtradados_demandae carrega horários por parada (horarios_paradas) em segundo plano. - Alocar Demanda: distribui os embarques do CSV nos segmentos (tramos) da
linha, gerando a camada
tramos_demandacom os campos: embarques— embarques alocados à parada de origem do tramopassageiros_acum— carga acumulada no ônibus naquele trechon_viagens— viagens GTFS que iniciaram na hora selecionada- Seletor de hora: filtra a alocação por faixa horária (0h–23h) ou pelo total diário. Quando uma hora é selecionada, usa o shape dominante entre as viagens que iniciaram naquela hora.
- Reconectar GeoPackage: restaura as camadas GTFS ao projeto sem reprocessar o feed (útil após fechar e reabrir o QGIS).
Construir GTFS¶
- Construir GTFS: permite criar um feed GTFS do zero por meio de um assistente interativo (veja sig_bus/GUIA_CONSTRUIR_GTFS.md):
- Agência e Rotas: defina a operadora de transporte e os detalhes da linha.
- Paradas Geocodificadas: busca o endereço da parada por uma cascata de geocodificação — Google (opcional, com chave de API) → Nominatim → Photon → corretor de nomes de rua via Overpass — mostrando um rótulo de status com a procedência (
✓ localizado (Nominatim),✓ localizado (via: <nome real> — OSM)); os endereços seguem um padrão sugerido (Logradouro, Número - Bairro). Um endereço não encontrado nunca bloqueia o fluxo. - Importação em Lote: carregue paradas via arquivo CSV (veja o guia do modelo em sig_bus/MODELO_PARADAS_CSV.md).
- Marcação no Mapa: clique diretamente no canvas para posicionar uma parada, para pontos rurais sem endereço geocodificável.
- Sequência: ordene as paradas no trajeto da linha.
- Horários: gere viagens a partir de até 3 faixas horárias (ex.: pico da manhã, entre-pico, pico da tarde), cada uma com hora de início, hora de fim, intervalo e duração da viagem, e depois ajuste-as viagem a viagem no diagrama (veja Diagrama de Blocos abaixo) antes de qualquer gravação; Restaurar frequência regular descarta os ajustes manuais e regera a grade a partir das faixas.
- Revisão e salvar: a linha é gravada num
feed_edit.gpkgisolado e segue para o mesmo validador e o mesmo exportador da Edição GTFS. - Traçado via OSM: o traçado (
shapes) segue a rede viária real do OpenStreetMap entre paradas consecutivas; a linha reta é usada como fallback apenas nos trechos que a malha buscada não cobre ou não conecta. - Barra de progresso dupla: mostra o quanto falta para um GTFS mínimo (arquivos e campos obrigatórios) e, além dele, para um GTFS completo (campos opcionais,
shapes, segundo sentido), nomeando o que ainda falta a cada etapa.
Editar e exportar GTFS¶
- Edição GTFS: permite editar campos e geometria em uma cópia de trabalho isolada (
feed_edit.gpkg), com validação integrada e exportação normalizada (veja sig_bus/GUIA_EDICAO_GTFS.md). - Ajustar horários: com uma linha escolhida, abre a matriz de horários daquela linha — uma aba por sentido, paradas nas linhas e viagens nas colunas — em que os horários são digitados direto nas células e o Aplicar ao feed os grava no
feed_edit.gpkg, sem tocar nos traçados, nostrip_idnem no número de viagens. A janela abre já ajustada à tela em que foi aberta e pode ser maximizada; ela reabre no tamanho e na posição em que foi deixada (guardados no perfil do QGIS, nunca no arquivo de projeto nem no feed) desde que ainda caibam na tela atual, e a matriz fica acima do diagrama de blocos num divisor que pode ser arrastado para cima ou para baixo para dar mais espaço à tabela ou ao diagrama sem que nenhum dos dois painéis desapareça.
Diagrama de Blocos¶
- Diagrama de Blocos: gráfico tempo × faixa da operação, em dois modos — Modo Viagens (uma barra por viagem do GTFS) e Modo Blocos, em que os blocos de veículo são inferidos encadeando viagens, porque o feed da BHTrans não traz
trips.block_id. Veja sig_bus/DIAGRAMA_BLOCOS.md. - Cota de headway: ao selecionar uma viagem, o intervalo até a saída seguinte da mesma linha e sentido é desenhado como cota de desenho técnico, rotulada só com a medida (ex.:
12 min). - Régua de saídas: um traço curto por partida na base do eixo de tempo — ida na banda de cima, volta na de baixo —, de modo que o pico e o vale se leem pela densidade dos traços.
- Ajuste fino de horários: com uma viagem selecionada,
>e<deslocam só a saída ou só a chegada, enquanto+e-deslocam a viagem inteira preservando a duração; o enquadramento é preservado entre os redesenhos e o Enquadrar tudo reenquadra a grade toda quando se quer. No assistente Construir GTFS o ajuste acontece no diagrama, em memória, antes de a linha ser gravada, e vale para todos os dias cobertos pelocalendardaqueleservice_id; na aba Edição GTFS os mesmos horários são ajustados numa matriz (uma aba por sentido), sobre um feed já gravado na cópia de trabalho. - Relatório PDF: gera um layout de impressão A4 paisagem com o mapa da linha filtrada, legenda, cabeçalho e dois gráficos de barras (ida e volta) dos embarques agrupados por cluster K-means.
Documentação¶
A mesma documentação está navegável em https://sigbus.dcamargo.com.br. Os arquivos da tabela abaixo são a versão offline que acompanha o plugin.
| Documento | O que responde |
|---|---|
sig_bus/DOCUMENTACAO.md |
O que cada botão faz, campos das camadas de saída e limitações conhecidas (EN + PT-BR) |
sig_bus/METHODS.md |
Embasamento teórico do método de alocação de demanda (EN) |
sig_bus/DIAGRAMA_BLOCOS.md |
Como ler o Diagrama de Blocos, seus dois modos e a inferência de blocos (PT-BR) |
sig_bus/GUIA_CONSTRUIR_GTFS.md |
Passo a passo do assistente "Construir GTFS" (PT-BR) |
sig_bus/GUIA_EDICAO_GTFS.md |
Passo a passo da aba "Edição GTFS" e seus erros comuns (PT-BR) |
sig_bus/MODELO_PARADAS_CSV.md |
Formato das colunas do CSV de importação de paradas em lote (PT-BR) |
sig_bus/ARQUITETURA_CONSTRUIR_GTFS.md |
Desenho interno da criação de GTFS (PT-BR) |
sig_bus/ARQUITETURA_EDICAO_GTFS.md |
Desenho interno da edição de GTFS (PT-BR) |
O histórico versão a versão está no CHANGELOG.md; a versão
corrente é a declarada em sig_bus/metadata.txt.
Estrutura do Repositório¶
.
├── CHANGELOG.md # histórico versão a versão
├── docs/
│ ├── gtfsfiles.zip # GTFS de exemplo para testes
│ └── PyQGIS_PIBIC.pdf # documentação da pesquisa de origem
└── sig_bus/ # código do plugin (instalar no QGIS)
├── __init__.py
├── SigBus.py # classe principal do plugin
├── SigBus_dialog.py # lógica da janela + tarefas de fundo
├── SigBus_dialog_base.ui
├── gtfs_reader.py # leitor GTFS embutido
├── gtfs_schema.py # fonte única da verdade da spec GTFS
├── gtfs_builder_core.py # constrói um feed do zero (progresso, expansão)
├── gtfs_edit_core.py # cópia de trabalho isolada (feed_edit.gpkg)
├── gtfs_validator.py # integridade referencial e de formato
├── gtfs_export.py # exportação normalizada para .zip
├── geocoding.py # cascata de geocodificação (Google/Nominatim/Photon)
├── geocoding_config.py # modo de provedor e chave de API no QSettings
├── street_index.py # corretor de nomes de rua via Overpass
├── address_format.py # padrão de endereço sugerido
├── osm_routing.py # shapes sobre a rede viária real do OSM
├── map_tools.py # marcação de parada por clique no canvas
├── stops_csv.py # importação de paradas em lote via CSV
├── schedule_edit_core.py # ajuste fino de horários em memória
├── schedule_table_core.py # matriz de horários (paradas × viagens), sem Qt
├── schedule_grid_widget.py # a tabela de horários em si (grade paradas × viagens)
├── block_core.py # modelo do Diagrama de Blocos e inferência
├── block_scene.py # desenho do diagrama (barras, cota, régua)
├── block_view.py # view do diagrama: zoom, pan, atalhos
├── block_diagram_dialog.py # janela do Diagrama de Blocos
├── test_*.py # suíte de testes, roda fora do QGIS
├── conftest.py # stubs dos módulos qgis usados pela suíte
├── scripts/check_qgis_compat.py # sondagem manual contra o QGIS instalado
├── ARQUITETURA_CONSTRUIR_GTFS.md # arquitetura técnica para criação de GTFS (PT-BR)
├── ARQUITETURA_EDICAO_GTFS.md # arquitetura técnica para edição de GTFS (PT-BR)
├── DIAGRAMA_BLOCOS.md # documentação do Diagrama de Blocos (PT-BR)
├── DOCUMENTACAO.md # documentação detalhada das funcionalidades (EN + PT-BR)
├── GUIA_CONSTRUIR_GTFS.md # guia do usuário para criação de GTFS (PT-BR)
├── GUIA_EDICAO_GTFS.md # guia do usuário para edição de GTFS (PT-BR)
├── METHODS.md # embasamento teórico do método de alocação
├── MODELO_PARADAS_CSV.md # documentação do modelo de importação de paradas em CSV
├── modelo_paradas.csv # arquivo modelo de exemplo para importação em lote
├── metadata.txt
├── icon.png
└── resources.py / resources.qrc
Requisitos¶
- QGIS 3.34 LTR até a série 4.x — roda tanto em Qt 5 (QGIS 3.x) quanto em
Qt 6 (QGIS 4.x) (faixa declarada
3.34–4.99; sondado no 3.34.4, testado em 3.44 e 4.2) - Python embutido do QGIS (sem dependências externas além do QGIS)
Instalação¶
- Copie a pasta
sig_bus/para o diretório de plugins do QGIS: - Linux:
~/.local/share/QGIS/QGIS3/profiles/default/python/plugins/ - Windows:
%APPDATA%\QGIS\QGIS3\profiles\default\python\plugins\ - Ative o plugin SIG-Bus em Complementos → Gerenciar e Instalar Complementos → Instalados.
- Acesse via Complementos → SIG-Bus.
Configuração da Geocodificação¶
Configurar uma chave da API do Google Maps é opcional. Sem chave nenhuma, a cascata OSM (Nominatim → Photon → corretor de nomes de rua via Overpass) continua funcionando igual — não há nada a preparar.
- A chave e o modo de provedor ficam no
QSettingsdo QGIS (SIG-Bus/geocoding/google_api_keyeSIG-Bus/geocoding/provider, tratados porgeocoding_config.py) — nunca no projeto e nunca no feed. - Modo de provedor:
autotenta o Google primeiro quando há chave configurada e cai para a cascata OSM;osmignora qualquer chave e usa só a cascata OSM. - A chave nunca é gravada no
feed_edit.gpkg(que é compartilhado) nem chega ao log do QGIS — toda URL registrada é redigida parakey=***.
Fluxo de Uso¶
O plugin possui três caminhos principais de entrada. Os caminhos (b) e (c) terminam no mesmo validador e no mesmo exportador.
a) Analisar um feed existente¶
Verificar GTFS → Executar GTFS → Inserir demanda
→ Selecionar linha → Filtrar dados
→ Escolher hora → Alocar Demanda
Veja sig_bus/DOCUMENTACAO.md para descrição detalhada de cada etapa,
campos das camadas de saída e limitações conhecidas. Para o embasamento
teórico do método de alocação de demanda, veja sig_bus/METHODS.md.
b) Construir um GTFS do zero¶
Construir GTFS → Assistente por linha → Exportar .zip
Veja sig_bus/GUIA_CONSTRUIR_GTFS.md para o guia do usuário.
c) Editar um feed carregado¶
Edição GTFS → Editar dados → Validar → Exportar .zip
Veja sig_bus/GUIA_EDICAO_GTFS.md para o guia do usuário.
Dados de Exemplo¶
docs/gtfsfiles.zip contém um feed GTFS para testes.
Os dados de demanda esperados seguem o formato do SIU-BHTrans
(CSV separado por ;, colunas 0–23 com embarques por hora).
Testes¶
A suíte de testes roda inteiramente fora do QGIS, sobre stubs dos módulos
qgis (sig_bus/conftest.py) — não é necessária instalação do QGIS. A partir
da raiz do repositório:
python3 -m pytest sig_bus -q
Além dos testes de unidade, a suíte carrega guardas de regressão:
test_qt6_compat.py (enum não qualificado, que quebra o QGIS 4),
test_metadata.py (faixa de versão declarada e CHANGELOG fechado, casando com
o metadata.txt) e test_readme.py (links relativos deste arquivo e simetria
entre as duas metades). O sig_bus/scripts/check_qgis_compat.py é sondagem
manual contra um QGIS instalado e não roda no pytest.
A edição de horários é coberta por test_schedule_table_core.py (matriz de
horários), test_gtfs_edit_stop_times.py (leitura e gravação de stop_times
filtrados por linha, mais a checagem de horário fora de ordem no validador) e
test_block_view_zoom.py (zoom e enquadramento preservado entre redesenhos).
Ritual de Release¶
Para empacotar e publicar uma nova versão do plugin SIG-Bus:
- Atualizar versão: Edite
sig_bus/metadata.txtpara incrementarversion=X.Y.Z(mantendoqgisMinimumVersion=3.34,qgisMaximumVersion=4.99esupportsQt6=True— sem o máximo, o QGIS assume3.99e recusa todo QGIS 4.x). O terceiro algarismo é obrigatório: três algarismos é o padrão dos demais projetos, e otest_metadata.pyrecusa qualquer outro formato. - Atualizar Changelog: Registre as novidades em
CHANGELOG.mdsob o cabeçalho da nova versão. - Executar Testes: Rode
pytestno repositório para garantir que todos os testes e guardas passem. - Sondar o QGIS instalado: Rode
python3 sig_bus/scripts/check_qgis_compat.pycontra o QGIS alvo — ele importa cada módulo, constrói umQgsField, confere o inventário de enums qualificados e carrega o.ui, imprimindoOK/FAILitem a item. - Empacotar o Plugin: Gere o arquivo
.zippara distribuição usandoqgis-plugin-cioumake package: - Via
qgis-plugin-ci:qgis-plugin-ci package <versao> - Via
make:cd sig_bus && make package VERSION=v<versao> - Publicar e Taggear: Crie e envie a tag Git (ex.:
git tag -a v0.5 -m "Release 0.5" && git push origin v0.5) e faça o upload do.zipgerado para o repositório de plugins do QGIS ou GitHub Releases.
Autor¶
Diego Camargo — diegocamargo.bft@gmail.com
Repositório: https://github.com/d-camargo/sig-bus