Skip to content

Validate collection bboxes on create/edit and tolerate them on view#79

Open
alukach wants to merge 2 commits into
chore/react-19-upgradefrom
fix/bbox-validation
Open

Validate collection bboxes on create/edit and tolerate them on view#79
alukach wants to merge 2 commits into
chore/react-19-upgradefrom
fix/bbox-validation

Conversation

@alukach

@alukach alukach commented Jun 8, 2026

Copy link
Copy Markdown
Member

What & why

A collection or item whose spatial extent is invalid or degenerate could be saved through the form and then crash the map when viewed. The triggering example was a bbox of [-90, 90, -90, 90] — a zero-area point sitting at the Web Mercator singularity (latitude 90°), which made fitBounds produce NaN coordinates and request an out-of-range tile (.../22/1048576/0.png).

This PR adds validation on both sides: block bad bboxes when creating/editing, and tolerate + warn about them when viewing.

Stacked on chore/react-19-upgrade — base this against that branch, not main.

Changes

Viewing (defensive)

  • New shared sanitizeBbox / MERCATOR_MAX_LAT in components/Map/bounds.ts: drops non-finite corners and clamps lon/lat to ±180 / ±85.0511°.
  • CollectionMap and ItemMap run the bbox through it before fitBounds, cap at maxZoom, and guard the call in try/catch so a still-degenerate extent can't take down the app.

Creating / editing (blocking)

  • New $utils/bbox (inspectBbox / summarizeBboxIssues) encoding the geographic rules:
    • longitude ∈ [-180, 180], latitude ∈ [-90, 90]
    • south < north
    • non-zero area on both axes (catches the [-90, 90, -90, 90] case)
    • west < east is intentionally NOT required — antimeridian-crossing bboxes (minLon > maxLon) stay valid; only an exact min === max longitude is degenerate.
  • CollectionForm/EditForm.tsx folds per-corner bbox errors into Formik validation, keyed at spatial.<i>.<corner> so they render inline on the offending input and block submit.

Viewing (warning)

  • CollectionDetail shows a non-blocking banner listing the problems when a stored extent is invalid.

Tests

  • bbox.test.ts — 13 unit tests covering ranges, ordering, zero-area, antimeridian, 3D (6-value) bboxes, and string coercion. Full client suite green (19 tests).

Manual check

  • Open a collection with a bad bbox → warning banner renders, map doesn't crash.
  • Enter [-90, 90, -90, 90] in the new-collection form → inline errors block submit and the view scrolls to the invalid field.

🤖 Generated with Claude Code

alukach and others added 2 commits June 8, 2026 14:16
A collection or item whose bbox sits at the Web Mercator singularity
(latitude ±90°, e.g. [-90, 90, -90, 90]) made fitBounds produce NaN center
coordinates and an out-of-range tile request (.../22/1048576/0.png), crashing
the map. Add a shared sanitizeBbox helper that drops non-finite corners and
clamps lon/lat to ±180 / ±85.0511°, and call it from both CollectionMap and
ItemMap before fitBounds. Also cap fitBounds at maxZoom and guard it in
try/catch so a zero-area extent can't zoom absurdly or take down the app.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The schema-driven form validation only knew each bbox corner was a number, so
geographically invalid or degenerate extents (out-of-range coords, south>north,
zero-area boxes like [-90, 90, -90, 90]) could be saved and later crash the map.

Add a shared inspectBbox/summarizeBboxIssues util ($utils/bbox) encoding the
geographic rules: lon in [-180,180], lat in [-90,90], south<north, and non-zero
area on both axes (west<east is NOT required so antimeridian-crossing bboxes
stay valid). The collection EditForm now folds per-corner bbox errors into the
Formik validation (keyed at spatial.<i>.<corner> so they render inline and block
submit), and the collection detail page shows a non-blocking warning listing the
problems when a stored extent is invalid. Unit-tested in bbox.test.ts.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant