# Nuvolari Precipitation radar for Piedmont, Italy. Android first, iOS later, one Flutter codebase. Radar imagery comes from the public **Radar-DPC** platform, forecasts from **MET Norway**, weather alerts from the **ARPA Piemonte** XML-CAP bulletin. The app is free and ad-supported, with GDPR consent through Google's UMP. Nuvolari is an independent app. It is not affiliated with, endorsed by, or operated by ARPA Piemonte or the Dipartimento della Protezione Civile. For civil-protection purposes the official channels always prevail. ## Layout ``` app/ Flutter application (Dart package "nuvolari") backend/ Python worker: fetches DPC rasters, crops, reprojects, renders PNG frames docs/ architecture, data sources, licenses, stack decisions, roadmap, privacy tool/ verification scripts ``` Start with [docs/architecture.md](docs/architecture.md), then [docs/roadmap.md](docs/roadmap.md) for what is built and what is next. ## Toolchain | Tool | Version | |---|---| | Flutter | 3.47.3 stable (Dart 3.13.3) | | Android SDK | platform 36, build-tools 36.0.0, platform-tools | | JDK | 21 | | Python | 3.12+ (3.14 works; rasterio ships wheels for it) | | Android NDK | 28.2.13676358 — pinned by `maplibre_gl`, not by this project | A full toolchain plus a warm Gradle cache needs roughly **14 GB** of disk: Flutter 3 GB, Android SDK 2.5 GB (2 GB of which is the NDK the map plugin pins), the Gradle cache 5 GB, and build output around 2 GB. `flutter clean` reclaims the last of those. ## Configuration Secrets never enter the repository. Copy the template and fill it in: ```bash cp env.example.json env.json # env.json is git-ignored ``` | Key | Purpose | |---|---| | `MAP_STYLE_URL` | MapLibre style URL. Empty falls back to a local offline style. | | `RADAR_MANIFEST_URL` | Base URL of the published `manifest.json`. | | `RADAR_SOURCE` | `mock` (offline demo), `dpc` (live), `arpa` (disabled stub). | | `METNO_USER_AGENT_CONTACT` | Contact address for the MET Norway User-Agent — **mandatory** for forecasts. | | `ADMOB_APP_ID`, `ADMOB_BANNER_UNIT_ID` | Empty means Google's test ad units are used. | ## Running ```bash cd app flutter run --dart-define-from-file=../env.json ``` With no `env.json` the app starts in demo mode: mock radar frames from assets, offline base map style, test ad units. No network and no credentials required. ## Debugging in VS Code Open the **`Nuvolari` folder** as the workspace root — the configurations in `.vscode/` are relative to it. Then pick one in Run and Debug and press **F5**: | Configuration | Use it for | |---|---| | **Nuvolari — debug (emulatore)** | Everyday work. Demo mode, no `env.json` needed, hot reload on save. | | **Nuvolari — profile** | Judging animation smoothness. Debug builds run the Dart VM unoptimised, so the radar timeline always looks worse than it is — never assess it in debug. | | **Nuvolari — debug con env.json** | Real endpoints and keys. | | **Nuvolari — debug su Windows** | Fast UI iteration with no emulator. The native map does not render here. | | **Test — tutti** / **Test — file corrente** | Debugging tests with breakpoints. | Every emulator configuration runs `tool/start_emulator.ps1` first, so F5 works from a cold machine. The script exits immediately when a device is already attached, so pressing F5 twice does not start two emulators. `Ctrl+Shift+B` runs the full verification. Other tasks live under **Terminal → Run Task**: quick verification, regenerating the demo radar frames, and shutting the emulator down. ## Verifying ```powershell .\tool\verify.ps1 # format, analyze, test, build, lint, pytest .\tool\verify.ps1 -SkipBuild # fast inner loop ``` Stages whose target does not exist yet are skipped, so this runs from day one. ## Attribution Radar-DPC (CC BY-SA) · MET Norway (CC BY 4.0) · Arpa Piemonte · © OpenStreetMap contributors (ODbL). See [docs/licenses.md](docs/licenses.md) for the obligations these carry — in particular, the rendered radar frames are a derived product of CC BY-SA data and inherit share-alike.