108 lines
4.8 KiB
Markdown
108 lines
4.8 KiB
Markdown
# Simulador de Contaminació Marina
|
||
|
||
Visor web de trajectòries lagrangianes de **~10.000 partícules contaminants** al Mediterrani occidental. Les partícules surten de punts de la costa catalana i es dispersen amb els corrents marins durant 72 hores. Quan arriben a la costa, s’encallen i s’acumulen, mostrant zones d’impacte.
|
||
|
||
**Stack:** Python · FastAPI · Next.js · Deck.gl · MapLibre (sense claus d’API)
|
||
|
||
---
|
||
|
||
## Arquitectura
|
||
|
||
```
|
||
trajectories/
|
||
├── backend/ # API i dades
|
||
│ ├── main.py # FastAPI: metadata, blocs JSON/Arrow, CORS, gzip
|
||
│ ├── data/ # Dades servides per l’API
|
||
│ │ ├── metadata.json # (opcional) simulació "default" a la arrel
|
||
│ │ └── simulations/ # Una carpeta per simulació
|
||
│ │ └── <sim_id>/ # metadata.json, block_0.arrow, block_1.arrow, ...
|
||
│ ├── etl/ # Pipeline NetCDF → blocs Arrow + metadata
|
||
│ │ ├── nc_reader.py # Lectura NetCDF (lon, lat, u, v, beached, temps)
|
||
│ │ ├── pipeline.py # Orquestració: load_nc → subsample horari → write_blocks_arrow
|
||
│ │ └── to_blocks.py # Escriptura Arrow IPC + metadata.json
|
||
│ └── scripts/
|
||
│ └── run_etl.py # CLI: python -m scripts.run_etl fitxer.nc [--sim-id ...]
|
||
│
|
||
└── frontend/ # App Next.js (App Router)
|
||
├── src/
|
||
│ ├── app/page.tsx # Pàgina principal → TrajectoryMap
|
||
│ ├── components/ # MapView, MapHeader, TimePlayer, TrajectoryMap, IntroDialog, …
|
||
│ ├── hooks/ # useBlocks (càrrega Arrow/JSON), useSimulation, useMapLayers, useMetadata
|
||
│ ├── lib/ # constants, trajectoryData (buildTrails, buildTripsWithTime)
|
||
│ └── types/ # trajectory (Meta, Block, PointDatum, TripDatum, …)
|
||
```
|
||
|
||
- **Backend:** Servir `metadata.json` i blocs de frames (JSON o **Arrow IPC**). Les dades viuen a `backend/data/` o `backend/data/simulations/<sim_id>/`. L’API accepta `?sim=default` (o qualsevol `sim_id`) per triar simulació.
|
||
- **Frontend:** Demana metadata a `/api/metadata?sim=...`, després els blocs a `/api/block/{id}` o `/api/block/{id}/arrow`. Construeix trails i trips a memòria (TripsLayer amb timestamps, PathLayer per selecció). Deck.gl + MapLibre renderitzen el mapa; el reproductor temporal avança el `currentTime` i es visualitzen les trajectòries amb color per origen, bloom/glow i partícules actives/beached.
|
||
|
||
---
|
||
|
||
## Com arrencar el projecte
|
||
|
||
### Requisits
|
||
|
||
- **Backend:** Python 3.10+, Node 18+ (només si no tens les dependències del backend instal·lades)
|
||
- **Frontend:** Node 18+
|
||
|
||
### 1. Backend
|
||
|
||
```bash
|
||
cd backend
|
||
|
||
# Entorn virtual i dependències
|
||
python3 -m venv venv
|
||
source venv/bin/activate # Windows: venv\Scripts\activate
|
||
pip install -r requirements.txt
|
||
|
||
# Dades (una de les dues opcions)
|
||
# Opció A: Dades de prova (sense NetCDF)
|
||
python generate_dummy_data.py
|
||
|
||
# Opció B: ETL des d’un NetCDF (genera block_*.arrow + metadata a data/simulations/<sim_id>/)
|
||
python -m scripts.run_etl path/to/trajectories.nc
|
||
python -m scripts.run_etl path/to/file.nc --sim-id my_run --write-json # opcional JSON
|
||
|
||
# Servidor API (port 8000)
|
||
uvicorn main:app --reload
|
||
```
|
||
|
||
L’API queda disponible a **http://localhost:8000**.
|
||
|
||
### 2. Frontend
|
||
|
||
```bash
|
||
cd frontend
|
||
|
||
npm install
|
||
npm run dev
|
||
```
|
||
|
||
Obre **http://localhost:3000**. Per defecte el frontend crida l’API a `http://localhost:8000` (configurable amb `NEXT_PUBLIC_API_URL` si cal).
|
||
|
||
### 3. Ús bàsic
|
||
|
||
1. Backend en marxa (terminal 1), frontend en marxa (terminal 2).
|
||
2. Obrir http://localhost:3000.
|
||
3. Tancar/acceptar el popup d’introducció i esperar que carreguin els blocs (barra de progrés).
|
||
4. Play / slider / velocitat (×0.5 … ×8). Zoom a les partícules (botó crosshair), Filters (basemap, capes), Info.
|
||
|
||
---
|
||
|
||
## API (resum)
|
||
|
||
| Endpoint | Descripció |
|
||
|----------|------------|
|
||
| `GET /api/simulations` | Llista d’IDs de simulació disponibles |
|
||
| `GET /api/metadata?sim=default` | Metadata (num_particles, num_steps, num_blocks, seed_names, origins, time_start, time_end, …) |
|
||
| `GET /api/block/{id}?sim=default` | Bloc en JSON (frames + step_start, step_end, accumulation) |
|
||
| `GET /api/block/{id}/arrow?sim=default` | Bloc en Apache Arrow IPC (columnes: step, particle_id, lon, lat, u, v, beached) |
|
||
|
||
---
|
||
|
||
## Característiques
|
||
|
||
- **Partícules i temps:** milers de partícules, 72 h (1 pas/hora), blocs de 24 h per càrrega progressiva.
|
||
- **Trajectòries:** TripsLayer amb cap arrodonit, color per origen (paleta), bloom/glow; partícules actives vs beached (vermell).
|
||
- **Mapa:** MapLibre (basemaps Carto), zoom/fit a partícules, tooltip amb origen i velocitat.
|
||
- **Dades:** ETL des de NetCDF (subsample horari, beached persistent) o dades de prova amb `generate_dummy_data.py`.
|