feat: Open Data Catalog explorer with server-side clip - #94
Conversation
Add an Open Data Catalog side panel to the Create Image Layer page so analysts can browse open disaster imagery (Vantor/Maxar + Planet Open Data), preview it, and build an image layer without hunting for COG URLs. Catalog UI (ui/src/Components/OpenDataCatalog/): - Dynamic discovery + merge of every event across the Vantor S3 STAC and Planet Source-Cooperative STAC catalogs; framework-free module with a discoverEvents()/fetchEventCatalog() contract (swap-to-backend seam). - Azure Maps footprints + TiTiler COG preview (works with no Azure Maps key); preview tile loading indicator. - Add a scene to pre/post in one click with source-type + capture-date auto-fill; buttons are phase-scoped (pre->Pre, post->Post). - Two-way map<->list selection: click a footprint to scroll/highlight/expand the list row; footprints stay clickable during preview. Server-side clip AOI: - Draw a box that sets a layer-level clipBbox ([w,s,e,n] EPSG:4326); imagery prep clips the pre/post mosaics via gdalwarp -te/-te_srs (GDAL reprojects the bounds). The catalog filters scenes overlapping the AOI and badges scenes that fully cover it, so pre/post share one AOI. - Model ImageLayer.clipBbox + validate_clip_bbox; PutLayer validates/carries it; threaded through the imagery-prep config -> ImageryWorkflow -> mosaic_imagery. Verified end-to-end (output bounds match the drawn box). Supporting fixes: - Allow data.source.coop on the imagery allowlist (UI + hastelib) and route non-S3/Blob allowlisted hosts through the generic HTTP downloader, so Planet imagery downloads at prep time. - Local dev proxy (docker/nginx.conf): TiTiler timeouts + client_max_body_size for chunk uploads. - QUICKSTART: DOCKER_GID must be 0 on macOS Docker Desktop. Azure Maps auth is unchanged (existing anonymous/AAD Client-ID flow). Spec: spec/features/open-data-catalog/. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds an in-app Open Data Catalog explorer on the Create Image Layer flow, letting analysts discover/preview open disaster imagery (Vantor/Maxar + Planet Source Cooperative) and build image layers faster, including an optional server-side clip AOI applied during imagery prep.
Changes:
- Adds new Open Data Catalog UI (panel + list + Azure Maps footprints + TiTiler preview) and wires it into the Create Image Layer form (including scene-to-pre/post “add” + auto-fill).
- Introduces
ImageLayer.clipBboxend-to-end (UI → PutLayer validation → imagery-prep config → GDAL mosaic clip). - Expands imagery URL allowlist to include
data.source.coopand routes non-S3/Blob allowlisted URLs through the generic HTTP downloader; updates local dev proxy settings/docs.
Reviewed changes
Copilot reviewed 26 out of 26 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| ui/src/util/validation.js | Allowlists data.source.coop imagery hosts in UI URL validation. |
| ui/src/Components/OpenDataCatalog/SceneListItem.jsx | New scene row UI with metadata, AOI badge, and phase-scoped add buttons. |
| ui/src/Components/OpenDataCatalog/OpenDataCatalogPanel.jsx | New catalog side panel: discovery, filtering, list↔map selection sync, clip toolbar. |
| ui/src/Components/OpenDataCatalog/OpenDataCatalogMap.jsx | New Azure Maps footprint rendering + TiTiler preview + rectangle clip drawing. |
| ui/src/Components/OpenDataCatalog/openDataCatalog.js | Framework-free STAC discovery/normalization + TiTiler URL helpers + bbox overlap helpers. |
| ui/src/Components/CreateEditImageLayerHelper.js | Adds clipBbox to form state + helper to add catalog scenes into imagery URL arrays. |
| ui/src/Components/CreateEditImageLayerForm.jsx | Adds “Browse Open Data Catalog” entry point; threads clipBbox into PutLayer payload. |
| spec/features/open-data-catalog/README.md | Feature spec overview and decision log for catalog + server-side clip. |
| spec/features/open-data-catalog/design.md | Detailed design: discovery/preview/clip flow and API contract changes. |
| spec/features/open-data-catalog/data-model.md | Documents clipBbox schema change and allowlist additions. |
| spec/features/open-data-catalog/user-stories.md | User stories and acceptance criteria for catalog and clip workflows. |
| spec/features/open-data-catalog/test-plan.md | Test strategy/coverage matrix for allowlist + clip + manual flows. |
| spec/features/open-data-catalog/plan.md | Implementation plan/status across core/API/UI phases. |
| spec/features/open-data-catalog/impact-analysis.md | Impact/risk analysis across UI/API/workflow/security considerations. |
| spec/features/open-data-catalog/rollout.md | Rollout plan, prerequisites, monitoring, rollback notes. |
| QUICKSTART.md | Documents macOS Docker Desktop DOCKER_GID behavior (set to 0). |
| hastelib/tests/core/utils/test_url_allowlist.py | Adds unit tests for data.source.coop allowlist + validate_clip_bbox. |
| hastelib/src/hastegeo/workflows/prepare_imagery.py | Threads clip_bbox into workflow and mosaic creation. |
| hastelib/src/hastegeo/core/utils/url_allowlist.py | Adds source.coop allowlist and validate_clip_bbox validator. |
| hastelib/src/hastegeo/core/utils/imagery.py | Clips mosaics during GDAL warp when clip_bbox is set. |
| hastelib/src/hastegeo/core/utils/downloader.py | Routes non-S3/Blob allowlisted imagery hosts to generic HTTP downloader. |
| hastelib/src/hastegeo/core/processors/imagery.py | Adds clip_bbox into imagery-prep config payload. |
| hastelib/src/hastegeo/core/models/projects.py | Adds ImageLayer.clipBbox field to model. |
| docker/nginx.conf | Increases body size and TiTiler proxy timeouts for local dev. |
| docker/docker-compose.yml | Adds CLEANUP_CONTAINERS env var to aid debugging spawned containers. |
| api/hastefuncapi/function_app.py | Validates clipBbox in PutLayer (400 on invalid bbox). |
- SceneListItem.formatGsd: guard non-finite input so a non-numeric gsd renders as absent instead of "NaN m GSD". - SceneListItem.formatSize: treat only null/undefined/"" as absent so a legitimate 0-byte asset formats as "0 B" (was hidden by a falsy check). - Imagery allowlist host description (ui/util/validation.js and hastelib url_allowlist.py): say Source Cooperative "*.source.coop" to match what the validator actually allows (endsWith ".source.coop"), avoiding misleading error messages. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
RC artifacts readyAll branch deployment references use the same RC tag:
|
The Open Data Catalog fetches the Vantor (S3) and Planet (Source
Cooperative) STAC catalogs + thumbnails directly from the browser. The
deployed Static Web Apps CSP only allowed atlas/openstreetmap/blob hosts,
so connect-src (and img-src) blocked those requests in production
("Refused to connect ... violates the document's Content Security Policy").
Add the two exact hosts to connect-src and img-src in
ui/public/staticwebapp.config.json (and document them in
docs/security-configuration.md):
- https://vantor-opendata.s3.amazonaws.com
- https://data.source.coop
(Longer term, moving discovery behind a same-origin backend proxy would
keep connect-src at 'self'.)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Meygha Machado (mgmachado)
left a comment
There was a problem hiding this comment.
LGTM
RC artifacts readyAll branch deployment references use the same RC tag:
|
The COG preview built tile URLs as /cog/tiles/{z}/{x}/{y}.png, a legacy
TiTiler alias that works on the local titiler but 404s through the deployed
TiTiler/APIM route. Switch to the canonical
/cog/tiles/WebMercatorQuad/{z}/{x}/{y}?scale=1 path that the rest of HASTE
already uses (labels.py, function_app.py) and that APIM serves in production.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
RC artifacts readyAll branch deployment references use the same RC tag:
|
… dump Pool ids were wired through GitHub Environment *variables*, but this repo is public and Actions logs are public with it. GitHub masks secret values in logs and does not mask variables, and `az functionapp config appsettings set` was printing the resulting settings JSON to stdout, so the values would have landed in a public log. Store them as environment secrets instead, matching how RESOURCE_PREFIX, LOCATION, RESOURCE_SUFFIX and STATIC_APP_DOMAIN are already handled, and add `--output none` so the app-settings dump is not emitted at all. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: dd98b384-7e26-47a9-8c03-6f9594eb611c
RC artifacts readyAll branch deployment references use the same RC tag:
|
Meygha Machado (@mgmachado) Anthony Cintron (@prbatero) -- nice touch!! |
Add an Open Data Catalog side panel to the Create Image Layer page so analysts can browse open disaster imagery (Vantor/Maxar + Planet Open Data), preview it, and build an image layer without hunting for COG URLs.
Catalog UI (ui/src/Components/OpenDataCatalog/):
Server-side clip AOI:
Supporting fixes:
Azure Maps auth is unchanged (existing anonymous/AAD Client-ID flow).
Spec: spec/features/open-data-catalog/.