WallpaperMachine
The wallpapers you love. A new home on your Mac.
Rotas a pé, de bike e de carro em São Paulo que equilibram tempo e exposição a ocorrências registradas.
Translation pending
LifestylePython · JavaScriptGitHub @alexzjssOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
Rotas a pé e de carro em São Paulo que equilibram tempo e exposição a ocorrências criminais registradas (SSP-SP).
Translation pending
Taken from the repository README
Loading the full README.
Read the full README ↗Rotas a pé, de bicicleta ou de carro em São Paulo que equilibram tempo de deslocamento e exposição a ocorrências criminais registradas pela SSP-SP.
Para cada trajeto, o SampaNav calcula até três opções e mostra quanto cada uma reduz a exposição em troca de quanto tempo a mais:
| Perfil | Peso do risco (α) | Para quem |
|---|---|---|
| Mais rápida | 0 | menor tempo, sem considerar risco |
| Equilibrada | 2 | compromisso entre tempo e exposição |
| Mais segura | 6 | menor exposição, aceitando desvios maiores |
Alternativas que não reduzem a exposição em pelo menos 5% são descartadas, e o app diz quando nenhum desvio vale a pena. A rota selecionada é colorida trecho a trecho pelo risco, e a camada de calor mostra o risco por região em cada período do dia.
Capturas geradas com o backend real e os dados de setembro/2024 a agosto/2026
(660 mil ocorrências), sobre o mapa do OpenFreeMap usado no app. Para regerar:
tools/screenshots.
A interface usa a linguagem da sinalização do Metrô de São Paulo: cada perfil de rota é
uma linha numerada, e o passo a passo aparece como uma sequência de estações. As cores
das linhas nunca representam risco; o risco segue a escala própria, do verde ao vermelho.
Detalhes em docs/IDENTIDADE.md.
Rotas
Navegação
Uso no dia a dia
Leia antes de usar ou apresentar os resultados.
.xlsx):
https://www.ssp.sp.gov.br/estatistica/consultas. Cada ano ocupa cerca de
126 a 196 MB.flowchart LR
subgraph Offline["Pipeline mensal (GitHub Actions)"]
SSP[("SSP-SP<br>planilhas .xlsx")] --> R[build_risk<br>grade H3 de risco]
GS[("GeoSampa<br>iluminação")] --> R
OSM[("OpenStreetMap<br>via OSMnx")] --> G[build_graph<br>grafos a pé e de carro]
R --> G
G --> V{validate_data}
V -- ok --> REL[("GitHub Release<br>sampanav-data.tar.gz")]
end
REL -- docker build --> API
subgraph Render["API (Render, 512 MB)"]
API[FastAPI + igraph<br>Dijkstra por perfil]
end
subgraph Vercel["Frontend (Vercel)"]
FE[HTML/CSS/JS sem build<br>MapLibre + h3-js]
end
FE -- "HTTPS /api" --> API
API -- geocodificação --> PH[("Photon")]
1 + 0,3 · (1 − luz), em que luz é a densidade de postes do GeoSampa (0 a 1).tempo × (1 + α · risco). A exposição de
uma rota é Σ comprimento × risco, em km equivalentes. Penalidades mais fortes (r², r³)
foram testadas e geravam rotas mais longas sem reduzir a exposição total.O contrato completo entre as partes (formatos de dados, esquema da API, regras de
risco) está em docs/ARQUITETURA.md.
| Métrica | Valor |
|---|---|
| Ocorrências no modelo | 660 mil (set/2024 a ago/2026) |
| Memória da API com os três modos | ~330 MB (limite do plano: 512 MB) |
| Carga dos grafos | ~1 s em CPU comum |
| Tempo de cálculo (3 perfis) | 60 a 300 ms; até ~700 ms em 20 km a pé com parada |
Resposta de /api/routes (gzip) | 2 a 21 KB |
| Testes | 136 no backend, 65 unitários no frontend, smoke test no navegador |
Execute os comandos na raiz do projeto:
uv sync
uv run python -m pipeline.download_ssp --years 2024 2025 2026
uv run python -m pipeline.build_risk
uv run python -m pipeline.build_graph
uv run uvicorn backend.app.main:app --reload
uv sync instala por padrão os grupos pipeline e dev. Os pontos de iluminação
do GeoSampa são baixados pelo build_risk e cacheados em data/raw/.
Depois, abra http://localhost:8000 no navegador. O uvicorn usa a porta 8000 por padrão.
Refazer só o risco, depois de reconstruir o modelo de risco, sem reprocessar
o OSM (reutiliza graph_{mode}.npz já existente):
uv run python -m pipeline.build_graph --risk-only
Testes e lint (os mesmos rodam no CI):
uv run ruff check .
uv run pytest
Testes do frontend (Node 22, sem dependências) e smoke test no navegador, em modo mock:
node --test 'frontend/tests/unit/*.test.mjs'
node frontend/tests/smoke/smoke.mjs # com o frontend servido em localhost:8000 e Playwright instalado
Capturas de tela do README: tools/screenshots/run.sh <pasta_dos_dados> sobe a
API com os dados, desenha o mapa base, captura as cenas e otimiza as imagens em
docs/img/ (detalhes em tools/screenshots/README.md).
Desenvolvimento só do frontend: abra http://localhost:8000/?mock=1. Nesse
modo, frontend/js/api.js usa respostas falsas de frontend/js/mock.js em vez
de chamar a API, o que permite trabalhar na interface sem os dados processados.
Todos os endpoints ficam sob o prefixo /api. O formato detalhado de cada um
está em docs/ARQUITETURA.md, seção 5.
GET /api/health: status do servidor e tamanho dos grafos carregados.GET /api/meta: metadados do modelo de risco, perfis e períodos disponíveis.GET /api/geocode?q=...: busca de endereços dentro de São Paulo.GET /api/reverse?lat=...&lon=...: endereço mais próximo de um ponto (ou null).POST /api/routes: calcula as rotas entre origem e destino (com via opcional), para
um modo (walk, drive ou bike) e período. Cada rota traz steps (manobras),
exposure_by_period e level_by_period.GET /api/risk?bbox=...&mode=...&period=...: células H3 com risco, para a camada de calor.Três serviços gratuitos:
frontend/ (vercel.json, sem build). A URL
da API fica em frontend/config.js (apiBase, hoje https://sampanav-api.onrender.com); em
localhost o app usa a mesma origem (dev local).Dockerfile e render.yaml) no plano free,
com 512 MB de RAM. Dorme após 15 min sem uso e leva cerca de 1 a 2 min para acordar.
As origens permitidas vêm de ALLOWED_ORIGINS./api/routes, 60 em /api/geocode, 120 em /api/risk; acima disso, 429 com
Retry-After). Os cálculos de rota rodam um por vez; se a fila passar de 20 s, a API
responde 503 e o frontend tenta de novo. Variáveis: SAMPANAV_RATE_ROUTES,
SAMPANAV_RATE_GEOCODE, SAMPANAV_RATE_RISK (0 desliga) e
SAMPANAV_ROUTE_QUEUE_TIMEOUT (segundos). Cada rota gera uma linha de log com modo,
período, distância e tempos de cálculo e de fila, sem coordenadas.pipeline/package_data.py gera sampanav-data.tar.gz
(grafos, risco e metadados) e sampanav-inputs.tar.gz (pontos de iluminação). O
Dockerfile baixa o sampanav-data.tar.gz da Release mais recente durante o build.pipeline/validate_data.py: volume mínimo, queda máxima de 30% frente à Release
anterior, data mais recente que não regride, risco entre 0 e 1 em todos os modos e
períodos) e só então publica nova Release. Com o segredo
opcional RENDER_DEPLOY_HOOK_URL, também dispara o deploy no Render.main e em pull requests roda ruff check e pytest, os testes
unitários do frontend, o docker build da imagem e um smoke test com Playwright no modo mock.Depois do deploy, siga o guia pós-deploy: ligar o frontend à API, conferir CORS e o limite por IP, e configurar a atualização mensal.
Dados: gere os pacotes e publique a primeira Release.
uv run python -m pipeline.package_data
gh release create data-AAAA-MM-DD data/dist/sampanav-data.tar.gz data/dist/sampanav-inputs.tar.gz --latest
Render: em New → Blueprint, escolha o repositório (ele usa o render.yaml).
Preencha ALLOWED_ORIGINS com a URL da Vercel, sem barra no final. Se ainda não
a tiver, ajuste a variável depois do passo 3.
Vercel: importe o repositório (o vercel.json já aponta para frontend/) e
defina apiBase em frontend/config.js, com a URL do Render (ex.:
https://sampanav-api.onrender.com).
Opcional: em Settings → Secrets and variables → Actions, crie
RENDER_DEPLOY_HOOK_URL com a deploy hook do serviço no Render.
SampaNav/
├── pyproject.toml, uv.lock # projeto Python único (uv)
├── Dockerfile, render.yaml # deploy da API (Render)
├── vercel.json # deploy do frontend (Vercel)
├── .github/workflows/ # ci.yml e data-refresh.yml (mensal)
├── docs/
│ ├── ARQUITETURA.md # contrato entre pipeline, API e frontend
│ ├── LICENCAS-DADOS.md # licenças e atribuições dos dados
│ ├── GUIA-POS-DEPLOY.md # checklist depois do deploy
│ └── img/ # capturas usadas neste README
├── tools/screenshots/ # gera as capturas com dados reais (Playwright)
├── pipeline/ # scripts offline
│ ├── config.py # pesos, categorias, períodos, caminhos e parâmetros v2
│ ├── download_ssp.py # baixa as planilhas da SSP-SP
│ ├── build_risk.py # ocorrências -> grade H3 de risco
│ ├── footfall.py # proxy de movimento pela malha a pé
│ ├── lighting.py # pontos de iluminação (GeoSampa) -> densidade H3
│ ├── evaluate.py # diagnóstico do modelo de risco
│ ├── validate_data.py # checagens antes de publicar a Release
│ ├── build_graph.py # rede OSM + risco -> grafos por modo
│ └── package_data.py # empacota os dados para a Release
├── backend/
│ ├── app/
│ │ ├── main.py # FastAPI; também serve o frontend em /
│ │ ├── routing.py # carga dos grafos e cálculo de rotas
│ │ ├── steps.py # manobras e instruções em português
│ │ ├── geocode.py # proxy para o Photon, com bbox de SP
│ │ └── ratelimit.py # limite de requisições por IP
│ └── tests/
├── frontend/ # HTML, CSS e JS estáticos, sem build
│ ├── index.html
│ ├── config.js # apiBase (URL da API em produção)
│ ├── img/, css/ # logo e estilos
│ └── js/
│ ├── api.js # chamadas à API (ou mock, com ?mock=1)
│ ├── mock.js # respostas falsas para desenvolvimento
│ ├── map.js # mapa, rotas e camada de calor
│ ├── ui.js # painel, busca, cartões de rota e recentes
│ ├── nav.js # navegação com GPS
│ ├── navui.js # banner de navegação
│ ├── icons.js # ícones das manobras
│ ├── speech.js # instruções faladas
│ ├── gpx.js # exportação em GPX
│ ├── history.js, urlstate.js # histórico local e estado na URL
│ ├── pwa.js # registro do service worker e aviso de versão nova
│ ├── format.js, main.js
│ ├── sw.js, manifest.webmanifest # PWA
│ └── tests/ # testes unitários (node --test) e smoke test
└── data/ # gitignored
├── raw/ # planilhas da SSP, OSM e pontos de iluminação
├── processed/ # saídas do pipeline (parquet, npz, json)
└── dist/ # pacotes para a Release
O código está sob a licença MIT (veja LICENSE). Os dados de terceiros
(OpenStreetMap, SSP-SP, GeoSampa, Photon, OpenFreeMap) seguem as próprias licenças e
exigências de atribuição, descritas em docs/LICENCAS-DADOS.md.
O histórico de versões está em CHANGELOG.md.
O SampaNav nasceu de um protótipo desenvolvido em hackathon (DustNav), feito pela equipe original do projeto. A versão atual é uma reescrita focada em roteamento com dados criminais reais de São Paulo.