Moved webapp to top level.

This commit is contained in:
Felix Delattre 2026-06-10 15:33:03 +02:00
parent 17f2d1d659
commit 5389776c8a
4 changed files with 7 additions and 7 deletions

View file

@ -14,7 +14,7 @@ Worldwide PhenoCam EFAST feasibility screening. Human summary: [`README.md`](REA
| `4-fusion.py` | Step 4: GCC computation + EFAST BtI/ItB fusion loop |
| `5-metrics.py` | Step 5: timeseries, covariates, `metrics.json`, webapp manifest |
| `data/` | Manifests, per-site caches, screening outputs (large; mostly generated) |
| `webapp/` | Static QA viewer (`make serve` from workspace root) |
| `index.html`, `common.js` | Static QA viewer (`make serve` from workspace root) |
Workspace orchestration: [`../AGENTS.md`](../AGENTS.md).
@ -29,7 +29,7 @@ Workspace orchestration: [`../AGENTS.md`](../AGENTS.md).
| S2/S3 download + EFAST prep | `3-sentinel-data.py` |
| GCC + fusion | `4-fusion.py` |
| Metrics + webapp index | `5-metrics.py` |
| Web QA | `../Makefile` target `serve``webapp/index.html` |
| Web QA | `../Makefile` target `serve``index.html` |
---

View file

@ -54,4 +54,4 @@ The 2025 manifest currently lists **739** cameras with archive overlap; most per
## Web viewer
From the workspace root, `make serve` serves `processing/` at [http://localhost:8000/webapp/index.html](http://localhost:8000/webapp/index.html). Requires step 5 (`data/metrics/manifest.json`).
From the workspace root, `make serve` serves `processing/` at [http://localhost:8000/index.html](http://localhost:8000/index.html). Requires step 5 (`data/metrics/manifest.json`).

View file

@ -358,7 +358,7 @@ async function fetchJson(url) {
}
async function loadMetrics(year, site) {
const base = `../data/metrics/${year}/${site}`;
const base = `data/metrics/${year}/${site}`;
const [tsEntries, rasterEntries, metricsData, covariatesData] = await Promise.all([
Promise.all(Object.entries(TS_FILES).map(async ([k, f]) => [k, await fetchJson(`${base}/${f}`)])),
Promise.all(Object.entries(RASTER_FILES).map(async ([k, f]) => [k, await fetchJson(`${base}/${f}`)])),
@ -443,7 +443,7 @@ function renderSitePanel(meta, cov) {
// ── init ──
async function init() {
try {
manifest = await fetch("../data/metrics/manifest.json").then(r => r.json());
manifest = await fetch("data/metrics/manifest.json").then(r => r.json());
} catch {
qs("#empty").textContent = "manifest.json not found — run 5-metrics.py first.";
return;
@ -534,7 +534,7 @@ async function selectSite(site) {
renderSitePanel(meta, loaded.covariates);
renderInspector(loaded.ts);
} else {
ts = await loadCsvTs(`../data/phenocam/${currentYear}/${site}_1day.csv`);
ts = await loadCsvTs(`data/phenocam/${currentYear}/${site}_1day.csv`);
qs("#metricsSection").style.display = "none";
renderInspector(null);
}
@ -743,7 +743,7 @@ async function loadOverlay(id, item, dateEl) {
if (!item || !maps3[id]) return;
dateEl.textContent = fmtDate8(item.date);
try {
const buf = await fetch(`../${item.path}`).then(r => r.arrayBuffer());
const buf = await fetch(item.path).then(r => r.arrayBuffer());
const { dataUrl, bbox, crsCode } = await geotiffToCanvasDataUrl(buf);
let bounds;
if (crsCode === "EPSG:4326") {