diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 000000000..99a407317 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ + +FROM postgres:17-bullseye + +LABEL maintainer="PostGIS Project - https://postgis.net" \ + org.opencontainers.image.description="PostGIS 3.5.2+dfsg-1.pgdg110+1 spatial database extension with PostgreSQL 17 bullseye" \ + org.opencontainers.image.source="https://github.com/postgis/docker-postgis" + +ENV POSTGIS_MAJOR=3 +ENV POSTGIS_VERSION=3.5.2+dfsg-1.pgdg110+1 + +RUN apt-get update \ + && apt-cache showpkg postgresql-$PG_MAJOR-postgis-$POSTGIS_MAJOR \ + && apt-get install -y --no-install-recommends \ + # ca-certificates: for accessing remote raster files; + # fix: https://github.com/postgis/docker-postgis/issues/307 + ca-certificates \ + \ + postgresql-$PG_MAJOR-postgis-$POSTGIS_MAJOR=$POSTGIS_VERSION \ + postgresql-$PG_MAJOR-postgis-$POSTGIS_MAJOR-scripts \ + && rm -rf /var/lib/apt/lists/* + +RUN mkdir -p /docker-entrypoint-initdb.d +COPY ./initdb-postgis.sh /docker-entrypoint-initdb.d/10_postgis.sh +COPY ./update-postgis.sh /usr/local/bin + diff --git a/README.md b/README.md index b6d292cb7..73dc252f7 100644 --- a/README.md +++ b/README.md @@ -1 +1,3 @@ -# GUIA \ No newline at end of file +# GUIA + +# oi tudo bem diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 000000000..720d76c5e --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,17 @@ +version: '3.8' + +services: + db: + image: postgis/postgis:17-3.5 + container_name: guia_db + environment: + POSTGRES_USER: guia_db + POSTGRES_PASSWORD: guia_senha + POSTGRES_DB: guia_db + ports: + - "5432:5432" + volumes: + - guia_postgres_data:/var/lib/postgresql/data + +volumes: + guia_postgres_data: diff --git a/docs/.arquitetura.md.swp b/docs/.arquitetura.md.swp new file mode 100644 index 000000000..7fe48577a Binary files /dev/null and b/docs/.arquitetura.md.swp differ diff --git a/guia-backend b/guia-backend new file mode 160000 index 000000000..107772db6 --- /dev/null +++ b/guia-backend @@ -0,0 +1 @@ +Subproject commit 107772db671f4f642d2558431debb7c04da7ae78 diff --git a/script.sql b/script.sql new file mode 100644 index 000000000..967d905f8 --- /dev/null +++ b/script.sql @@ -0,0 +1,104 @@ +CREATE EXTENSION IF NOT EXISTS postgis; +CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; + +CREATE TYPE report_status AS ENUM ('pending', 'processed', 'reject'); +CREATE TYPE bug_type AS ENUM ('rota', 'visual', 'conexao', 'report', 'outro'); + + +CREATE TABLE users ( + user_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + name VARCHAR(255) NOT NULL, + email VARCHAR(255) UNIQUE NOT NULL, + telefone VARCHAR(11) UNIQUE NOT NULL, + cpf VARCHAR(11) UNIQUE NOT NULL, + password_hash VARCHAR(255) NOT NULL, + icon INTEGER, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + + +CREATE TABLE street_segment ( + segment_id BIGSERIAL PRIMARY KEY, + osm_id BIGINT UNIQUE, + name VARCHAR(255) NOT NULL, + geom geometry(LineString, 4326), + avg_risk_score NUMERIC, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + + +CREATE TABLE reports ( + report_id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), + user_id UUID NOT NULL REFERENCES users(user_id), + location geometry(Point, 4326) NOT NULL, + street_segment_id BIGINT REFERENCES street_segment(segment_id), + data_image DATE, + image_path VARCHAR(255), + risk_score FLOAT, + comentario_v VARCHAR(255), + nota_v INTEGER, + comentario_a VARCHAR(255), + nota_a INTEGER, + comentario_t VARCHAR(255), + nota_t INTEGER, + comentario_m VARCHAR(255), + nota_m INTEGER, + comentario_al VARCHAR(255), + nota_al INTEGER, + comentario_s VARCHAR(255), + nota_s INTEGER, + user_rating INTEGER, + report_status report_status NOT NULL DEFAULT 'pending', + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + + +CREATE OR REPLACE FUNCTION atualizar_media_risk_score() +RETURNS TRIGGER AS $$ +BEGIN + INSERT INTO street_segment (segment_id, updated_at, avg_risk_score) + VALUES (NEW.street_segment_id, NOW(), + (SELECT AVG(risk_score) FROM reports WHERE street_segment_id = NEW.street_segment_id)) + ON CONFLICT (segment_id) DO UPDATE + SET avg_risk_score = EXCLUDED.avg_risk_score, + updated_at = NOW(); + RETURN NEW; +END; +$$ LANGUAGE plpgsql; + +CREATE TRIGGER atualizar_media_risk_score +AFTER INSERT OR UPDATE ON reports +FOR EACH ROW +EXECUTE FUNCTION atualizar_media_risk_score(); + + +CREATE TABLE bug_report ( + bug_report_id BIGSERIAL PRIMARY KEY, + user_id UUID REFERENCES users(user_id), + name VARCHAR(255) NOT NULL, + bug_type bug_type NOT NULL DEFAULT 'outro', + descricao VARCHAR(255), + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + + +CREATE TABLE bug_images_report ( + bug_report_image_id BIGSERIAL PRIMARY KEY, + bug_report_id BIGINT REFERENCES bug_report(bug_report_id), + imagem TEXT, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + + +CREATE TABLE route_rating ( + route_rating_id BIGSERIAL PRIMARY KEY, + user_id UUID REFERENCES users(user_id), + trip_shape TEXT, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); diff --git a/site/404.html b/site/404.html new file mode 100644 index 000000000..b5eb08cd2 --- /dev/null +++ b/site/404.html @@ -0,0 +1,579 @@ + + + +
+ + + + + + + + + + + + + + + + +A arquitetura do sistema foi projetada para separar claramente os processos assíncronos de construção de dados dos processos síncronos de consulta em tempo real.
+risk_scores) para gerar os artefatos de mapa enriquecidos que a plataforma online utiliza.A operação do sistema é dividida em dois fluxos principais e distintos: a alimentação periódica dos dados de risco e a requisição de rotas em tempo real pelo usuário.
+Este diagrama detalha o processo automatizado que roda periodicamente (ex: diariamente as 04:00 da manhã ou qualquer horário definido pela equipe) para recriar os mapas do Valhalla, incorporando os risk_scores mais recentes.

Este diagrama mostra a sequência de interações para os dois casos de uso principais do usuário: submeter um novo report (que irá alimentar o próximo ciclo de build) e solicitar uma rota segura.
+
O motor de roteamento open-source Valhalla é o núcleo do serviço de rotas. Seus componentes e o funcionamento dos dados são detalhados a seguir.
+++TRADUZIDO DE https://valhalla.github.io/valhalla/tiles/
+
Um tile (ou bloco) representa uma pequena seção retangular de uma área geográfica. O mapa inteiro é dividido em uma grade de tiles quadrados, que são arquivos em um formato binário específico contendo todas as informações necessárias para o roteamento.
+Os tiles são organizados em uma hierarquia de três níveis para otimizar buscas de longa distância:
+| Nível de Hierarquia | +Tamanho do Tile | +Conteúdo Principal | +
|---|---|---|
| 0 | +4° | +Vias expressas (ex: motorway, trunk) |
+
| 1 | +1° | +Vias arteriais (ex: primary, secondary) |
+
| 2 | +0.25° | +Vias locais (ex: residential, service) |
+
Em cada nível, o mundo é dividido usando a caixa delimitadora (-180, -90, 180, 90), com a ordenação começando do canto inferior esquerdo.
A imagem a seguir mostra a divisão do mundo nos tiles de nível 0.
+
Abaixo, exemplos de como regiões específicas são cobertas pelos diferentes níveis de tiles (Nível 0: azul, Nível 1: verde, Nível 2: vermelho).
+Alemanha
+
Pensilvânia
+
Nova Iorque
+
O Valhalla é composto por vários módulos, cada um com uma responsabilidade clara no processo de build e de roteamento.
+Responsabilidade: Converter dados brutos do formato .osm.pbf para os tiles roteáveis do Valhalla. Mjolnir é o "compilador" do mapa que faz o Extraction, Transformation and Loading (ETL).
Localização: src/mjolnir/

O processo, orquestrado pela ferramenta valhalla_build_tiles, segue várias etapas:
pbfgraphparser.cc): Leitura do arquivo .pbf do OpenStreetMap, iterando sobre nós, vias e relações.graphbuilder.cc): Transformação das entidades OSM em um grafo./lua/graph.lua). É aqui que o risk_score é incorporado como um peso de custohierarchybuilder.cc): Classificação das arestas nos níveis 0, 1 e 2 e geração de "atalhos" (shortcuts) para acelerar a busca.graphtilebuilder.cc): Divisão do grafo global na grade de tiles (.gph).valhalla_tiles (ou valhalla_tiles.tar), que é o "binário" de produção.Responsabilidade: Definir e fornecer acesso eficiente às estruturas de dados do grafo.
+Localização: src/baldr/
graphtile.h): Cada arquivo .gph é um bloco binário com um layout denso para acesso rápido aos dados.GraphId (graphid.h): Um uint64_t que identifica unicamente qualquer nó no grafo global, codificando o ID do tile, o nível da hierarquia e o índice do nó.graphreader.cc): Utiliza mmap para mapear o arquivo valhalla_tiles.tar no espaço de endereço virtual do processo. O sistema operacional gerencia o carregamento de dados do disco para a RAM sob demanda.
src/tyr/): Recebe a requisição HTTP e orquestra o fluxo interno.src/loki/): O serviço de "matching". Converte as coordenadas da requisição (lat, lon) para os nós/arestas correspondentes no grafo ("snap-to-road").src/thor/): A engine de busca de caminho. Recebe os nós de Loki e executa os algoritmos de roteamento.bidirectional_astar.cc): Utiliza o A* Bidirecional para performance.src/odin/): O serviço de "narrativa". Converte o caminho bruto (sequência de GraphIds) retornado pelo Thor em instruções de navegação turn-by-turn.++Pesquisa feita com
+Deep Searchdo Gemni 2.5 pro eInvestigardo ChatGPT 4.0/5.0
| Critério | +Replicação Monolítica | +Sharding Geográfico | +Lazy-Loading / Cache Remoto | +
|---|---|---|---|
| Tempo de Inicialização | +Médio-Alto (1-10 min) Depende do I/O do disco para o mmap inicial. |
+Baixo (<2 min) Dataset menor significa inicialização mais rápida. |
+Muito Baixo (<10 seg) O custo é transferido para a latência da primeira requisição. |
+
| Velocidade de Escalonamento | +Média Limitada pelo tempo de inicialização. Requer over-provisioning. |
+Rápida Pods mais leves permitem que o HPA responda mais agilmente. |
+Muito Rápida Escalonamento do compute é desacoplado do dado. |
+
| Eficiência de CPU/Memória | +Alta (se bem dimensionado) O mmap é extremamente otimizado. O "desperdício" é o custo de disco replicado. |
+Muito Alta Recursos alocados para a demanda específica de uma região. |
+Variável Degradada por I/O de rede; pode criar gargalos no cache remoto. |
+
| Complexidade Operacional | +Baixa Deploy padrão. Artefato único. Load balancing stateless. |
+Alta Requer um proxy de roteamento L7 e múltiplos artefatos. |
+Muito Alta Requer driver customizado e infra de cache robusta. |
+
| Isolamento de Falhas | +Médio Falha no pod afeta apenas aquele pod. |
+Alto Falha é contida no shard daquela região geográfica. |
+Baixo Dependência de um serviço de cache/storage centralizado. |
+
| Roteamento Inter-regional | +Nativo e Atômico Performance ótima dentro de um único processo. |
+Complexo e Lento Requer costura de resultados entre shards, adicionando latência. |
+Nativo (em teoria) Degradado por múltiplas buscas de tiles remotos. |
+
| Custo em Escala | +Médio-Alto Custo principal é o armazenamento em bloco (SSD) replicado. |
+Médio Economiza em armazenamento, mas adiciona custo do proxy e de engenharia. |
+Potencialmente Baixo (em teoria) Custo de engenharia e da infra de cache pode anular a economia. |
+
Para cobrir o Brasil e escalar para uma alta carga de requisições, a arquitetura de Replicação Monolítica é a escolha ideal. A complexidade introduzida pelas outras abordagens não justifica seus benefícios, exceto em escala verdadeiramente global.
+Justificativa Técnica:
+mmap de um arquivo local é uma das operações de I/O mais rápidas possíveis. A transição entre tiles tem latência na ordem de microssegundos a milissegundos, enquanto uma chamada de rede adiciona dezenas a centenas de milissegundos.risk_score) e um único tipo de serviço com um load balancer stateless é um benefício imenso em termos de confiabilidade, depuração e velocidade de desenvolvimento.