Pular para conteúdo

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 .zip e sintetiza calendar.txt a partir de calendar_dates.txt quando 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 em shapes, filtra dados_demanda e 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_demanda com os campos:
  • embarques — embarques alocados à parada de origem do tramo
  • passageiros_acum — carga acumulada no ônibus naquele trecho
  • n_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.gpkg isolado 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, nos trip_id nem 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 pelo calendar daquele service_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.344.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

  1. Copie a pasta sig_bus/ para o diretório de plugins do QGIS:
  2. Linux: ~/.local/share/QGIS/QGIS3/profiles/default/python/plugins/
  3. Windows: %APPDATA%\QGIS\QGIS3\profiles\default\python\plugins\
  4. Ative o plugin SIG-Bus em Complementos → Gerenciar e Instalar Complementos → Instalados.
  5. 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 QSettings do QGIS (SIG-Bus/geocoding/google_api_key e SIG-Bus/geocoding/provider, tratados por geocoding_config.py) — nunca no projeto e nunca no feed.
  • Modo de provedor: auto tenta o Google primeiro quando há chave configurada e cai para a cascata OSM; osm ignora 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 para key=***.

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 023 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:

  1. Atualizar versão: Edite sig_bus/metadata.txt para incrementar version=X.Y.Z (mantendo qgisMinimumVersion=3.34, qgisMaximumVersion=4.99 e supportsQt6=True — sem o máximo, o QGIS assume 3.99 e recusa todo QGIS 4.x). O terceiro algarismo é obrigatório: três algarismos é o padrão dos demais projetos, e o test_metadata.py recusa qualquer outro formato.
  2. Atualizar Changelog: Registre as novidades em CHANGELOG.md sob o cabeçalho da nova versão.
  3. Executar Testes: Rode pytest no repositório para garantir que todos os testes e guardas passem.
  4. Sondar o QGIS instalado: Rode python3 sig_bus/scripts/check_qgis_compat.py contra o QGIS alvo — ele importa cada módulo, constrói um QgsField, confere o inventário de enums qualificados e carrega o .ui, imprimindo OK/FAIL item a item.
  5. Empacotar o Plugin: Gere o arquivo .zip para distribuição usando qgis-plugin-ci ou make package:
  6. Via qgis-plugin-ci: qgis-plugin-ci package <versao>
  7. Via make: cd sig_bus && make package VERSION=v<versao>
  8. 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 .zip gerado 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