2026-05-04 09:44:56 +02:00
2026-05-04 09:44:56 +02:00
2026-05-04 09:44:56 +02:00
2026-05-04 09:44:56 +02:00
2026-05-04 09:44:56 +02:00
2026-05-04 09:44:56 +02:00

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, sencallen i sacumulen, mostrant zones dimpacte.

Stack: Python · FastAPI · Next.js · Deck.gl · MapLibre (sense claus dAPI)


Arquitectura

trajectories/
├── backend/                 # API i dades
│   ├── main.py              # FastAPI: metadata, blocs JSON/Arrow, CORS, gzip
│   ├── data/                # Dades servides per lAPI
│   │   ├── 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>/. LAPI 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

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 dun 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

LAPI queda disponible a http://localhost:8000.

2. Frontend

cd frontend

npm install
npm run dev

Obre http://localhost:3000. Per defecte el frontend crida lAPI 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 dintroducció 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 dIDs 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.
Description
No description provided
Readme 10 MiB
Languages
TypeScript 66.8%
Python 29.2%
CSS 3.6%
JavaScript 0.4%