Skip to content

Commit

Permalink
Merge pull request #4 from RJ-SMTR/add-doc-subsidio
Browse files Browse the repository at this point in the history
[WIP] Estrutura repositório de documentação de pipelines
  • Loading branch information
pixuimpou authored Aug 5, 2024
2 parents 06bbe3b + d175cc0 commit 8c482af
Show file tree
Hide file tree
Showing 9 changed files with 256 additions and 2 deletions.
Binary file not shown.
File renamed without changes.
Empty file.
133 changes: 133 additions & 0 deletions docs/pipelines/listagem_pipelines/monitoramento/apuracao_viagens_v1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Subsídio SPPO

* Versão: 2.0.0
* Data de início: 01/06/2022

## Etapas

### 1. Atualização de viagens planejadas

<img width="995" alt="image"
src="https://user-images.githubusercontent.com/20743819/179116129-8f8d56d2-97c8-4e5b-b490-12c58d39bc80.png">

Os serviços e trajetos considerados no subsídio são
atualizados pela equipe de Planejamento,
podendo ser incluídas novas linhas, alteradas rotas ou
mesmo a quilometragem determinada. Essa
rotina acontece a cada quinzena de apuração do subsídio.

Como resultado, obtemos para cada dia de apuração o quadro planejado por
trajeto, conforme exemplo abaixo. Nele, consolidamos:

1. A distância planejada para cada viagem
(`distancia_planejada`, ou extensão do trajeto) e total por dia (`distancia_total_planejada`)

<img width="813" alt="image"
src="https://user-images.githubusercontent.com/20743819/179118003-d97f632c-810b-4f0f-a4ec-825e5d25f01a.png">

2. A geometria do trajeto (`shape`), assim como seu ponto inicial
(`start_pt`) e final (`end_pt`),
que serão usados para identificar as posições de GPS na próxima
etapa.

<img width="1250" alt="image" src="https://user-images.githubusercontent.com/20743819/179119285-063df325-f1d9-4736-b37b-9e0eeaf3b8a7.png">

**Observações**:

* Os trajetos circulares têm seu shape dividido em ida e volta, para
possibilitar a identificação da viagem. Nestes casos, a coluna
`shape_id_planejado` recebe o id "teórico" e `shape_id` recebe o ID
de ida ou volta, trocando-se 11º caractere do ID [ex: 866 -
`O0866AAA0ACDU01` (teórico) x `O0866AAA0AIDU01` (ida)].

* O `tipo_dia` determina a quilometragem total planejada para aquele dia, conforme o [Plano Operacional](https://transportes.prefeitura.rio/subsidio/). Caso o dia seja um feriado, o `tipo_dia` considerado será de Domingo. Caso seja ponto facultativo, será usado `Sabado`.

* Nesta versão, os horários de `inicio_periodo` e `fim_periodo` são desconsiderados e consideramos o planejado para o dia inteiro.

### 2. Cálculo de viagens realizadas

<img width="1026" alt="image"
src="https://user-images.githubusercontent.com/20743819/179116020-37472af3-0b3e-4e94-862a-9c3bbb01f088.png">

O cálculo é realizado cruzando sinais de GPS com o trajeto planejado de
cada serviço. Em resumo, identifica-se potenciais viagens a partir de posições
do GPS emitidas nos pontos inicial e final do trajeto, e depois valida-se a
viagem caso atinja os percentuais de conformidade mínimos de:

* **Cobertura de GPS**: 50% dos minutos entre o início e fim da viagem devem ter pelo menos 1 sinal de GPS;
* **Cobertura do trajeto**: 80% das posições de GPS devem ter sido identificadas dentro
do trajeto planejado (num raio de 500m);

O passo a passo do algoritmo está descrito abaixo.

> Vamos seguir um exemplo com o ônibus B63050 (`id_veiculo`) no
> serviço `349` ao longo da metodologia para facilitar a explicação.
> <img width="367" alt="Screen Shot 2022-07-14 at 21 17 15"
src="https://user-images.githubusercontent.com/20743819/179121947-3bc63cfd-9f81-4ce7-be05-887ee4b6fe61.png">
#### 2.1. Classificação das posições de GPS no trajeto (`aux_registros_status_trajeto`)

As posições de GPS dos ônibus são capturadas a cada minuto, e
posteriormente tratadas a cada hora na tabela
[`gps_sppo`](). A partir dos dados de GPS, sabemos para cada veículo
(`id_veiculo`, ou número de ordem) e datahora (`timestamp_gps`), qual era sua posição
(`latitude`, `longitude`) e o serviço no qual estava operando (`servico`)
naquele momento.

> Para o dia 24/06, recebemos as seguintes informações por GPS do B63050 de 6:15 às 6:16:
<img width="491" alt="image"
src="https://user-images.githubusercontent.com/20743819/179122550-1d502871-7b4f-4b1e-bd7f-0a5959dad565.png">

Cruzamos essa tabela de posições de GPS com o trajeto (`shape`) da
`viagem_planejada` pela data e serviço para classificar cada
posição como:

* `start`: veículo estava no ponto inicial do trajeto (num raio de 500m)
* `end`: ponto final do trajeto (num raio de 500m)
* `middle`: meio do trajeto (num raio de 500m)
* `out`: fora do trajeto (num raio de 500m)

Nesta etapa, as posições são
duplicadas para os trajetos de ida (`I`) e volta (`V`)
pois ainda não temos como dizer qual sentido o veículo está operando.

> Uma vez classificado o `status_viagem`, obtemos para o mesmo intervalo
> de 6:15 às 6:16:
> <img width="819" alt="image" src="https://user-images.githubusercontent.com/20743819/179124464-9f08c16b-0272-4941-a7f8-45f8d5fe5394.png">
#### 2.2. Identificação de início e fim de viagens (`aux_viagem_inicio_fim`, `aux_viagem_circular`)

Uma vez classificadas as posições, buscamos os pares de início e fim que
possivelmente formam uma viagem.

Para isso, identificamos a "movimentação" do veículo: qual é seu
`status_viagem` naquele momento e qual era seu `status_viagem` imediatamente
anterior.
Classificamos, então, como início da viagem (`datetime_partida`) o momento em que o veículo
sai do ponto inicial e entra no trajeto, isto é, movimentação =
`startmiddle`. Da mesma forma, o fim da viagem é classificado como o
momento em que o veículo chega no ponto final a partir do trajeto, isto
é, movimentação = `middleend`.

> Na seção anterior vimos que o B63050 esteve no ponto inicial
(`start`) do trajeto de volta (`V`) às 6:15:26 e logo em seguida, às
6:15:56, esteve no meio do trajeto (`middle`). Logo, 6:15:26 é
potencialmente o início de uma viagem no serviço 349. Para afirmarmos isso, deve haver posteriormente uma movimentação `middleend`,
que é observada às 7:20:57. Realizando esse processo ao longo do dia
24/06, obtemos as seguintes possíveis viagens do B63050:
> <img width="898" alt="image"
> src="https://user-images.githubusercontent.com/20743819/179125623-af731b85-0f9d-4d00-bada-93ca5997dea8.png">
Realizamos um tratamento final nessa etapa para juntar as viagens circulares, separadas
nos trajetos de ida (`I`) e volta (`V`), na tabela `aux_viagem_circular`.
O início de uma viagem circular (`datetime_partida`) corresponde ao
início do trajeto de ida e o final da viagem (`datetime_chegada`) ao
final do trajeto de volta.

#### 2.3. Classificação das posições de GPS nas viagens (`registros_status_viagem`)

#### 2.4. Cálculo dos percentuais de conformidade da viagem (`viagem_conformidade`, `viagem_completa`)

### 3. Sumarização de viagens

<img width="1341" alt="image" src="https://user-images.githubusercontent.com/20743819/179116232-fb73d399-068c-4a79-8165-733c01f597ea.png">
Empty file.
Empty file.
5 changes: 5 additions & 0 deletions docs/pipelines/novos_pipelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<!-- ### Descrição -->

<!-- Datasets são contêineres para organização e controle de acesso de tabelas e views no BigQuery.
O nome do dataset deve ser o mesmo na definição do pipeline e na pasta de modelos do DBT. -->
108 changes: 108 additions & 0 deletions docs/tabelas/manual_estilo_tabelas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Manual de Estilo de Modelos e Tabelas

Esta página é baseada no [manual de estilo da Base dos Dados](https://basedosdados.github.io/mais/style_data/)

## Modelos DBT

### Organização do Diretório models

O diretório `queries/models` deve ser dividido em pastas referentes aos datasets do BigQuery em que cada tabela será criada. Cada pasta
de dataset pode conter uma subpasta `staging`, para armazenar os modelos intermediários para a criação das tabelas e views finais. Além disso, cada
dataset deve contenter um arquivo schema.yml para a criação das descrições das tabelas, views e colunas.

<br>Exemplo:
```
└── queries
   └── models
      └── nome_dataset
   ├── nome_modelo.sql # instruções sql para materialização de uma tabela ou view
   ├── schema.yml # estrutura e documentação do modelo
└── staging
└── nome_modelo_intermediario.sql
```

### Estruturação dos Modelos

## Tabelas e Datasets

### Nomeação de Datasets

- Caso sejam para tabelas de uso geral, os datasets são nomeados de acordo com a categoria dos dados armazenados.
<br><br>Exemplo:
- `bilhetagem`
- `financeiro`
- `subsidio`

- Os datasets também podem ser nomeados de forma a indicar a finalidade específica em que os dados são usados
<br><br>Exemplo:
- `validacao_dados_jae`

- Ou com o nome de um dashboard, utilizando o prefixo `dashboard_`
<br><br>Exemplo:
- `dashboard_subsidio_sppo`

### Nomeação de Tabelas

- As tabelas devem ser sempre nomeadas no singular

- Caso a tabela tenha algum qualificador, por exemplo `aux` e `view`, ele deve ser colocado como prefixo. Exemplo: `aux_gratuidade`

- A nomeação de tabelas não agregadas é menos estruturada, devendo apenas indicar claramente qual informação que se encontra nela.

- Para tabelas agregadas, nós nomeamos de forma a indicar o nivel de agregação do menor para o maior. Exemplo:
`ordem_pagamento_servico_operador_dia`
- Este exemplo indica uma tabela com os dados das ordens de pagamento, agregados por `servico` (campo mais específico), `operador` e `dia` (campo mais geral)

### Nomeação e Tipos de Colunas

- Procurar usar os nomes que já são utilizados. Exemplos: `data`, `servico`, `modo`, `id_veiculo`.
- Ser o mais claro e intuitivo possível.
- O nome das colunas devem ser escritos em snake_case (todas as letras minúsculas e palavras separadas por `_`).
- Colunas do tipo booleano devem ter um prefixo `indicador_`. Exemplo: `indicador_transacao_valida`.
- Colunas numéricas com ponto flutuante que representam valores financeiros devem utilizar o tipo `NUMERIC`.
- Colunas de id devem ser do tipo `STRING`, exceto se este for o campo de partição da tabela.

### Ordenamento de Colunas

- Os primeiros campos devem ser sempre a coluna de partição da tabela (se houver) e a chave única da tabela, nesta ordem.
- Caso não tenha chave única, as chaves primárias devem ser dispostas em ordem decrescente de abrangência (Exemplo: `modo`, `id_servico`, `id_operador`)
- As próximas colunas devem ser outras informações identificadores em ordem decrescente de abrangência.
- Colunas de `id`, sua descrição e outras informações relativas a ele devem permanecer agrupadas. Sempre com o `id` sendo a primeira coluna. Exemplos: `id_servico`, `servico`, `descricao_servico`, `id_operador`, `operador`
- Colunas qualitativas devem ser agrupadas por tema e dispostas em ordem decrescente de relevância.
- O mesmo deve ser feito para colunas quantitativas, em seguida.
- Por fim, deve ser incluídas as colunas de controle: `datetime_captura` (se aplicável), `datetime_ultima_atualizacao`, `versao`

- Exemplo de ordenamento:
`data` (partição)
`id_transacao` (chave única)
`datetime_transacao` (identificador temporal)
`datetime_processamento` (identificador temporal)
`modo` (identificador modo)
`id_consorcio` (identificador consorcio)
`consorcio` (identificador consorcio)
`id_operadora` (identificador operadora)
`operadora` (identificador operadora)
`id_servico_jae` (identificador servico)
`servico_jae` (identificador servico)
`descricao_servico_jae` (identificador servico)
`sentido` (identificador sentido)
`id_veiculo` (identificador veiculo)
`id_validador` (identificador validador)
`id_cliente` (identificador cliente)
`tipo_pagamento` (qualitativa)
`tipo_transacao` (qualitativa)
`tipo_transacao_smtr` (qualitativa)
`tipo_gratuidade` (qualitativa)
`id_tipo_integracao` (qualitativa)
`id_integracao` (qualitativa)
`latitude` (qualitativa)
`longitude` (qualitativa)
`stop_id` (qualitativa)
`stop_lat` (qualitativa)
`stop_lon` (qualitativa)
`valor_transacao` (quantitativa)
`valor_pagamento` (quantitativa)
`datetime_captura` (controle)
`datetime_ultima_atualizacao` (controle),
`versao` (controle)

12 changes: 10 additions & 2 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,19 @@ nav:
- Quick Start: quick_start.md # setar ambiente virtual, instalar com poetry, mencionar o infisical, configuração por OS
- Pastas e arquivos: pastas_arquivos.md # descrição da estrutura de pastas e arquivos
- Ambientes: ambientes.md # descrever ambientes de produção, staging e dev
- Tabelas:
- Manual de Estilo: tabelas/manual_estilo_tabelas.md # manual para criação de tabelas e modelos
- Pipelines:
- Introdução: pipelines/introducao.md # descrição dos motivos para criarmos as pipelines como fazemos atualmente
- Criação de pipelines: pipelines/novos_pipelines.md # como criar novos pipelines
- Pipelines genéricos: pipelines/templates.md # templates de pipelines genéricos, captura, tratamento
- Listagem das pipelines: pipelines/listagem_pipelines.md # histórico das pipelines já existentes, para cada uma falar dos parâmetros e do que se trata
- Listagem das pipelines: # histórico das pipelines já existentes, para cada uma falar dos parâmetros e do que se trata
- Monitoramento:
- Tratamento de GPS: pipelines/listagem_pipelines/monitoramento/tratamento_gps.md # pipeline de tratamento dos dados de GPS
- Apuração de viagens (SPPO) [1.0]: pipelines/listagem_pipelines/monitoramento/apuracao_viagens_v1.md # pipeline de apuração de viagens v1
- Apuração de viagens [2.0]: pipelines/listagem_pipelines/monitoramento/apuracao_viagens_v2.md # pipeline de apuração de viagens
- Financeiro:
- Apuração do subsídio (SPPO): pipelines/listagem_pipelines/financeiro/apuracao_subsidio_sppo.md # pipeline de apuração dos valores do subsídio
- FAQ: pipelines/listagem_pipelines/faq.md # perguntas frequentes sobre as pipelines de apuração do subsídio
- Datasets: datasets.md # histórico dos datasets já existentes
- Ferramentas: ferramentas.md # ferramentas e versões utilizadas

Expand Down

0 comments on commit 8c482af

Please sign in to comment.