Skip to content

GeoParquet 2.0 CRS: PROJJSON in geo metadata, flexible native Parquet crs, srid:0 for unknown - #286

Merged
cholmes merged 2 commits into
mainfrom
crs-projjson-srid0-2.0
Jun 16, 2026
Merged

GeoParquet 2.0 CRS: PROJJSON in geo metadata, flexible native Parquet crs, srid:0 for unknown#286
cholmes merged 2 commits into
mainfrom
crs-projjson-srid0-2.0

Conversation

@cholmes

@cholmes cholmes commented Jun 15, 2026

Copy link
Copy Markdown
Member

Encodes the GeoParquet 2.0 CRS decisions reached on the June 1 community call. This supersedes the two exploratory PRs it grew out of:

This PR keeps the structure and explanations that #284 introduced (it's a nice approach), but reframes them around the decisions below. It is a docs-only change — schema.json and the schema tests are unchanged from main (crs stays object|null).

Decisions encoded

1. The GeoParquet geo metadata crs is PROJJSON; the native Parquet crs can be any form

The spec now clearly separates the two crs fields:

  • GeoParquet column-metadata crs field — MUST be inline PROJJSON (or null). Writing geo metadata is itself optional (a writer may emit only the native Parquet geospatial types), but any file that does carry GeoParquet metadata states its CRS as inline PROJJSON there. This is the key guarantee: a reader of the GeoParquet metadata can always obtain a complete CRS definition directly, without resolving an authority code against an external registry.
  • Native Parquet crs property (on the GEOMETRY/GEOGRAPHY logical type) — the source of truth, and not restricted by GeoParquet. It MAY use any Parquet-core form: inline PROJJSON, <authority>:<code>, srid:<identifier>, or projjson:<key_name>.
    • Writers SHOULD use inline PROJJSON or <authority>:<code>; <authority>:<code> is RECOMMENDED for writers that can't readily generate PROJJSON (pure-SQL pipelines, browser-side writers).
    • A writer that can't generate PROJJSON is encouraged to just write plain native Parquet geo with an <authority>:<code> crs and omit GeoParquet metadata. Such a file isn't conformant GeoParquet 2.0, but any GeoParquet reader should still read it.
  • Readers MUST interpret both inline PROJJSON and <authority>:<code> in the native Parquet crs property, and SHOULD additionally tolerate srid:<identifier> / projjson:<key_name>.

Spec framing: producing the native Parquet geospatial types is the foundation of GeoParquet 2.0 and what every writer should do; the GeoParquet geo metadata is the optional, more-explicit layer on top.

2. null (unknown / undefined CRS) is kept, and maps to srid:0

  • The GeoParquet column-metadata crs MAY still be null to mean "CRS undefined or unknown" (kept for 1.x compatibility — real use cases include local/engineering coordinates and legacy data).
  • When the GeoParquet crs is null, the native Parquet crs property SHOULD be set to srid:0. The Parquet core spec mentions the srid:<identifier> form but assigns no meaning to 0; GeoParquet 2.0 adopts srid:0 to mean undefined/unknown CRS, following the GeoPackage convention discussed on the call.

Mirroring table (from the new spec text)

Parquet logical-type crs GeoParquet column-metadata crs Meaning
absent (Parquet default) absent OGC:CRS84
inline PROJJSON object the same CRS as inline PROJJSON CRS fully described in metadata
<authority>:<code> string the resolved CRS as inline PROJJSON CRS identified by an authority code
srid:0 null CRS undefined or unknown

Changes

  • format-specs/geoparquet.md:
    • Column-metadata crs row clarified (object|null; PROJJSON or null; must describe the same CRS as the native Parquet property).
    • §crs rewritten: the GeoParquet field is the inline-PROJJSON restatement; native Parquet property is the source of truth and may use other forms; nullsrid:0.
    • §crs Parquet property rewritten: explicitly scoped to the native Parquet property; native types are primary/recommended; writer MAY use any Parquet form (<authority>:<code> recommended when not inlining PROJJSON); writers that can't do PROJJSON should write plain native Parquet and omit geo metadata; reader MUST/SHOULD rules; srid:0 for unknown; mirroring table.
    • OGC:CRS84 details: note that <authority>:<code> OGC:CRS84 and EPSG:4326 are equivalent to OGC:CRS84.
  • schema.json, scripts/test_json_schema.py: no change (already object|null on main).

Test results

47 passed  (test_json_schema.py)
62 passed  (full scripts/ test suite)

🤖 Generated with Claude Code

… crs, srid:0 for unknown

Reflects the June 1 community-call decisions on GeoParquet 2.0 CRS handling:

- The GeoParquet `geo` column-metadata crs field MUST be inline PROJJSON (or
  null). Writing geo metadata is optional, but when present its crs is the
  guaranteed-PROJJSON restatement of the CRS, so readers can always obtain a full
  definition without resolving an authority code.
- The native Parquet GEOMETRY/GEOGRAPHY crs property is the source of truth and
  is NOT restricted by GeoParquet: it MAY use any Parquet-core form (inline
  PROJJSON, <authority>:<code>, srid:<id>, projjson:<key>). authority:code is the
  recommended form for writers that cannot generate PROJJSON; such writers are
  encouraged to write plain native Parquet geo and omit geo metadata (not
  conformant GeoParquet 2.0, but readers should still read it).
- Readers MUST understand PROJJSON and <authority>:<code> in the native Parquet
  crs property, and SHOULD tolerate the srid/projjson:key forms.
- "null" (undefined/unknown CRS) is kept in GeoParquet metadata for 1.x
  compatibility, and maps to srid:0 in the native Parquet crs property.

Keeps the structure and explanations from #284 but encodes the chosen decisions,
superseding #284 (authority:code in metadata) and #285 (removing null).
schema.json and the schema tests are unchanged from main (crs is object|null).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@paleolimbot paleolimbot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Others should have a look as well, but this looks good to me. It preserves the ability of existing metadata parsers to parse a CRS, and also gives practical advice nudging people towards the subset of values allowed by the Parquet spec that they should actually be using.

Comment thread format-specs/geoparquet.md Outdated
Co-authored-by: Dewey Dunnington <dewey@wherobots.com>
@cholmes
cholmes merged commit f0470d9 into main Jun 16, 2026
2 checks passed
@m-mohr
m-mohr deleted the crs-projjson-srid0-2.0 branch June 16, 2026 09:51
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.

2 participants