Skip to content

Enforce single-source rule for spatial: properties#31

Draft
wietzesuijker wants to merge 1 commit into
zarr-conventions:mainfrom
wietzesuijker:rfc/single-source-spatial-properties
Draft

Enforce single-source rule for spatial: properties#31
wietzesuijker wants to merge 1 commit into
zarr-conventions:mainfrom
wietzesuijker:rfc/single-source-spatial-properties

Conversation

@wietzesuijker
Copy link
Copy Markdown

@wietzesuijker wietzesuijker commented May 20, 2026

Summary

One slot per spatial: fact, per level. Affine arrays drop spatial:bbox (derivable from transform + shape); non-affine arrays must declare it; groups carry only spatial:bbox, no per-array properties.

Companion to the RFC at #32.

What's in this PR

  • schema.json: four allOf if/then branches enforcing the rules at array, group, and multiscales.layout[] levels.
  • README.md: new ## Property placement section with the rules, four-corner derivation snippet, antimeridian carve-out (xmin > xmax allowed for geographic CRSes), and updated examples that no longer carry the forbidden array-level pair.
  • test-rules.js: 12-case test suite. 7 forbidden shapes return valid=false; 5 positive shapes (including the antimeridian and multiscales-layout cases) return valid=true.
  • examples/proj.json: drops array-level spatial:bbox (now derivable); adds spatial:shape so the example is self-describing.
  • notes/single-source-rule-rationale.md: prior art, rejected alternatives, per-issue cross-references, out-of-scope reasoning. For reviewers who want the receipts; not normative.

Test plan

  • npm test, existing example validator: 2/2 PASS (multiscales.json, patched proj.json).
  • npm test, new rule suite: 12/12 PASS.
  • npm run lint: clean.
  • npx prettier --check schema.json examples/proj.json test-rules.js: clean.
  • Reviewer to run npm install && npm test locally.

Migration footprint

  • Two example fixtures across the spec and toolkit repos need a one-line removal. This PR includes the spec-side fixture; the toolkit-side fix is at zarr-developers/geozarr-toolkit#.
  • No deployed production producers identified so far. Production write paths (EOPF, GDAL, xarray/rioxarray) were not exhaustively crawled; reviewer input welcome.

- schema.json: four new allOf branches that make the placement rules
  enforceable without tolerance arithmetic.
    A. affine arrays MUST NOT carry spatial:bbox (derivable from
       spatial:transform + spatial:shape via the four transformed corners).
    B. non-affine arrays (transform_type != 'affine') MUST carry spatial:bbox
       (no closed-form derivation).
    C. groups MUST NOT carry per-array spatial properties (spatial:transform,
       spatial:transform_type, spatial:shape, spatial:registration).
    D. multiscales.layout[] entries MUST NOT carry spatial:bbox (derivable
       per resolution level from spatial:transform + spatial:shape).
- test-rules.js: 12-case suite covering both directions of each branch,
  plus an antimeridian carve-out case (xmin > xmax) for geographic CRSes.
- package.json: npm test now runs both the example validator and the rule
  suite.
- README.md: new "Property placement" section documenting the rules,
  the four-corner derivation, and the antimeridian carve-out.
- examples/proj.json: remove the array-level spatial:bbox (it duplicates the
  extent already encoded by spatial:transform); add spatial:shape so the
  example is self-describing.
- notes/single-source-rule-rationale.md: prior art, rejected alternatives,
  per-issue cross-references, and out-of-scope reasoning. Non-normative
  companion to the README section.

Resolves zarr-conventions#6, zarr-conventions#8, zarr-conventions#12, zarr-conventions#23. Composes with zarr-conventions#19.
@wietzesuijker wietzesuijker force-pushed the rfc/single-source-spatial-properties branch from d889920 to af11820 Compare May 20, 2026 17:41
@wietzesuijker
Copy link
Copy Markdown
Author

(force-pushed af11820 to resolve merge conflicts from parallel work in #14)

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