Skip to content

RFC: single-source rule for spatial: properties (resolves #6, #8, #12, #23) #32

Description

@wietzesuijker

Resolves: #6, #8, #12, #23
Composes with: #19

The bug

spatial: lets you store the same fact in two slots. Array level today:

{
  "node_type": "array",
  "attributes": {
    "spatial:shape": [1024, 1024],
    "spatial:transform": [10.0, 0.0, 500000.0, 0.0, -10.0, 5000000.0],
    "spatial:bbox": [500000.0, 4990000.0, 510000.0, 5000000.0]
  }
}

For an affine transform, the bbox is fully determined by transform + shape (four-corner walk). Storing it again invites floating-point drift between the two copies. Each consumer picks its own tolerance and its own tiebreaker. Same store, different rectangles in different viewers.

The fix

One slot per fact:

  • Affine array: carry spatial:transform + spatial:shape. MUST NOT carry spatial:bbox (derivable).
  • Non-affine array (rpc, polynomial, lookup, custom): MUST carry spatial:bbox. No closed-form derivation exists.
  • Group: MAY carry spatial:bbox only. No per-array spatial: properties belong at the group level.

JSON Schema enforces all three rules directly. No tolerance arithmetic, no normative prose for validators to ignore.

The cost

Two example fixtures need a one-line edit. Both included in the draft PRs below. No deployed production producers identified so far; if you know one that emits the forbidden pattern, flag it.

The proof

Draft PRs, both ready to run:

Receipts

For prior art (STAC, OGC, GeoTIFF, CF), rejected alternatives, per-issue cross-references, and out-of-scope reasoning, see notes/single-source-rule-rationale.md in the spec PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions