Skip to content

Location.bbox as a bare [minx, miny, maxx, maxy] array is schema-invalid and untranslatable (King County feed) #6298

Description

@cody-seibert-gsa

Code repo: GSA/datagov-harvester

Problem

Location.bbox as a bare [minx, miny, maxx, maxy] coordinate array — the well-known GeoJSON "bbox" member convention (RFC 7946 §5) — is neither schema-valid nor translatable, and real, currently-onboarding agency data uses exactly this shape.

King County's real DCAT-US 3.0 feed (https://gis-kingcounty.opendata.arcgis.com/api/feed/dcat-us/3.0.json, from the in-flight onboarding ticket #6248) sends:

"spatial": [
  {
    "@type": "Location",
    "bbox": [-123.9434, 47.0089, -120.2857, 48.407]
  }
]

508 of 531 datasets (95.7%) in that live feed use this shape.

This is worse than a lost translated_spatial

Two independent problems, confirmed against the live feed:

  1. Schema validation rejects the whole record. Location.bbox (definitions/Location.json) only allows null, a string, or {"type": "Polygon", "coordinates": [...]} — a bare array matches none of them:
    ['spatial'] [{'@type': 'Location', 'bbox': [-123.9434, 47.0089, -120.2857, 48.407]}] is not valid under any of the given schemas
    
    Record.validate() (harvester/harvest.py:1333) sets self.status = "error" on any schema error, and sync() (:1466) returns early on status == "error" before _dataset_payload() ever runs. So this isn't a warning-level "spatial dropped" case like 6197: Degenerate WKT polygons are dropped, losing spatial for 10% of the OpenTopography feed #6294/DCAT-US 3 warning rules never fire on prefixed @type CURIEs (dct:Location, dcat:Dataset) #6295/spatial arrays pick the first *truthy* Location, not the first *usable* one #6296 — the record itself never gets persisted at all.
  2. Independently, translate_spatial_to_geojson() also returns None for this shape (_unwrap_location returns the raw bbox value, which is a list — translate_spatial only handles dict/str, so a bare list falls through to return ""), so even if validation were relaxed, the geometry would still be silently lost.

Why this is plausibly spec-intended, not just bad data

Location.bbox's own schema description says: "Bounding box represented in GeoJSON format, either as a Polygon or in bbox array format" — but the actual JSON Schema constraint only encodes the Polygon-object case, never the array case the description promises. King County appears to be using the standard GeoJSON bbox member convention the description is referring to; the schema's machine-checkable constraint just doesn't match its own prose.

Suggested fix

Normalize a bare 4-element numeric bbox array into {"type": "Polygon", "coordinates": [[[minx, miny], [minx, maxy], [maxx, maxy], [maxx, miny], [minx, miny]]]} at ingestion, before schema validation runs — the same "tolerate the real-world shape, canonicalize early" approach munge_spatial already uses for messy v1.1 spatial strings. This fixes both the validation rejection and the translation gap in one place, without needing to fork or patch the vendored dcat-us schema.

Separately (optional), consider raising the description/schema mismatch upstream against GSA/dcat-us.

Acceptance criteria

  • A DCAT-US 3.0 record with Location.bbox as [minx, miny, maxx, maxy] passes schema validation
  • That record's translated_spatial resolves to the equivalent GeoJSON Polygon
  • Location.bbox as a GeoJSON Polygon object or WKT string is unchanged
  • Unit test covers the bare-array form — there is currently none
  • Ideally, an integration test harvests a fixture using this shape and asserts on the resulting Dataset row (real feeds get rejected wholesale today, not just warned)

Context

Found while investigating #6038 (SPIKE-3) and #6296, using the real King County feed from #6248 as a source of production DCAT-US 3.0 data (the same role OpenTopography's feed played for #6294/#6295). Related to #6294, #6295, #6296.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions