-
Notifications
You must be signed in to change notification settings - Fork 10
Proposal: Projection Attribute Extension for Zarr v3 #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
emmanuelmathot
wants to merge
39
commits into
zarr-developers:main
Choose a base branch
from
emmanuelmathot:proj-crs
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 1 commit
Commits
Show all changes
39 commits
Select commit
Hold shift + click to select a range
60fddbc
add: create specifications for Projection Attribute Extension and its…
emmanuelmathot f09f67a
fix: update attribute naming from `proj` to `geo` in Projection Attri…
emmanuelmathot 83a5f93
fix: remove `shape` field from Projection Attribute Extension schema …
emmanuelmathot 77bae32
fix: rename `spatial_dims` to `spatial_dimensions` in README and sche…
emmanuelmathot caee06b
fix: enhance spatial dimension identification section in README with …
emmanuelmathot 9daf0d3
fix: clarify inheritance model for `geo:proj` attribute in README
emmanuelmathot 7e77fa1
fix: clarify spatial dimension identification section in README with …
emmanuelmathot 01537ec
fix: add version field to geo:proj schema and update README for compa…
emmanuelmathot 17a0700
fix: update geo:proj schema to include version field and restructure …
emmanuelmathot 289f774
Update attributes/geo:proj/README.md
emmanuelmathot cd14f53
Update attributes/README.md
emmanuelmathot 0932243
Update attributes/README.md
emmanuelmathot cd58d28
Update attributes/geo:proj/README.md
emmanuelmathot c317a4a
Update attributes/geo:proj/README.md
emmanuelmathot 8a60696
Remove redundant examples for irregular grid and update WKT2 represen…
emmanuelmathot 96b5db1
Refine spatial dimension identification section to focus on regular g…
emmanuelmathot e9e754e
Refactor inheritance model section for clarity and remove redundant r…
emmanuelmathot 1893b7b
Update examples in geo:proj README.md to enhance clarity and provide …
emmanuelmathot a244d90
Clarify spatial dimension interpretation in geo:proj README.md to emp…
emmanuelmathot 1cffe00
Clarify terminology and improve consistency in geo:proj README.md reg…
emmanuelmathot d903aa7
Remove the Registered Extensions section from attributes README.md to…
emmanuelmathot f4364e4
Update attributes/geo:proj/README.md
emmanuelmathot cc9f913
Enhance README.md and schema.json for geo:proj extension by adding de…
emmanuelmathot 21b0d1c
Refine validation rules in geo:proj README.md to clarify shape infere…
emmanuelmathot 1bde1bc
Update attributes/README.md
emmanuelmathot 190ad60
Update versioning in geo:proj README.md and schema.json to 0.1.0
emmanuelmathot a4b2bef
Update attributes/geo:proj/README.md
emmanuelmathot 544687d
Update attributes/geo:proj/README.md
emmanuelmathot 4582d2a
Enhance README.md with projection authority examples and clarify CRS …
emmanuelmathot 1c0134f
Remove redundant emphasis on spatial dimensions interpretation in geo…
emmanuelmathot ac841d8
Add algorithm for resolving spatial dimensions in group-level geo:proj
emmanuelmathot 803f269
Clarify flexibility in spatial dimension ordering in geo:proj README.md
emmanuelmathot 27a1123
Refactor Geo Projection Attribute Extension
emmanuelmathot eeb64ae
Update attributes/geo/proj/README.md
emmanuelmathot 22b277d
Merge branch 'main' into proj-crs
emmanuelmathot c84a05e
Update README.md for Geo Projection Attribute Extension and remove sc…
emmanuelmathot 5132326
Remove link to Attributes section in README.md
emmanuelmathot b13da42
Update attributes/geo/proj/README.md
emmanuelmathot f9ffc2f
Update attributes/geo/proj/README.md
emmanuelmathot File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
# Attributes Extensions | ||
|
||
This directory contains specifications for Zarr v3 attribute extensions. | ||
|
||
## What are Attribute Extensions? | ||
|
||
Attribute extensions define standardized schemas and semantics for metadata stored in the `attributes` field of Zarr arrays and groups. These extensions enable interoperability by establishing common conventions for domain-specific metadata. | ||
|
||
## Registered Extensions | ||
|
||
| Extension | Version | Description | | ||
|-----------|---------|-------------| | ||
| [projection](./projection/) | 1.0.0 | Coordinate reference system metadata for geospatial data | | ||
emmanuelmathot marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
## Creating an Attribute Extension | ||
|
||
When creating an attribute extension, consider: | ||
|
||
1. **Namespace**: Use a unique prefix to avoid conflicts (e.g., `proj:` for projection) | ||
emmanuelmathot marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
2. **Schema**: Provide a JSON schema for validation | ||
3. **Inheritance**: Define behavior when attributes are set at group vs array level | ||
4. **Compatibility**: Consider interoperability with existing tools and standards | ||
|
||
emmanuelmathot marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
## Extension Requirements | ||
|
||
Each attribute extension MUST: | ||
- Define the attribute key(s) and structure | ||
- Provide a JSON schema for validation | ||
- Include examples of usage | ||
- Document any inheritance or precedence rules | ||
emmanuelmathot marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
# Projection Attribute Extension for Zarr | ||
|
||
- **Extension Name**: Projection Attribute Extension | ||
- **Version**: 1.0.0 | ||
- **Extension Type**: Attribute | ||
- **Status**: Proposed | ||
- **Owners**: @emmanuelmathot | ||
|
||
## Description | ||
|
||
This extension defines a standardized way to encode coordinate reference system (CRS) information for geospatial Zarr arrays and groups using the `proj:crs` attribute. | ||
emmanuelmathot marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
||
## Motivation | ||
|
||
- Provides simple, standardized CRS encoding without complex nested structures | ||
- Addresses issues identified in GeoZarr discussions regarding CF convention complexity | ||
- Compatible with existing geospatial tools (GDAL, rasterio, pyproj) | ||
- Based on the proven STAC Projection Extension model | ||
|
||
## Specification | ||
|
||
The `proj:crs` attribute can be added to Zarr arrays or groups to define projection information. | ||
|
||
### Required Fields | ||
|
||
At least one of the following MUST be provided: | ||
|
||
- `proj:code`: Authority and code identifier (e.g., "EPSG:4326") | ||
- `proj:wkt2`: WKT2 string representation of the CRS | ||
- `proj:projjson`: PROJJSON object representation of the CRS | ||
|
||
emmanuelmathot marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
### Optional Fields | ||
|
||
- `proj:bbox`: Bounding box in the CRS coordinates | ||
- `proj:transform`: Affine transformation coefficients (6 or 9 elements) | ||
- `proj:shape`: Shape of the spatial dimensions [y, x] | ||
- `proj:spatial_dims`: Names of spatial dimensions in the array | ||
|
||
### Spatial Dimension Identification | ||
|
||
The extension identifies spatial dimensions through: | ||
|
||
1. **Explicit Declaration** (recommended): Use `proj:spatial_dims` to specify dimension names | ||
2. **Convention-Based** (fallback): Automatically detect standard spatial dimension names | ||
|
||
#### Explicit Declaration | ||
|
||
```json | ||
{ | ||
"proj:crs": { | ||
"proj:shape": [2048, 2048], | ||
emmanuelmathot marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
"proj:spatial_dims": ["latitude", "longitude"] | ||
} | ||
} | ||
``` | ||
|
||
#### Convention-Based Detection | ||
|
||
If `proj:spatial_dims` is not provided, implementations should scan `dimension_names` for these patterns (in order): | ||
|
||
- ["y", "x"] or ["Y", "X"] | ||
- ["lat", "lon"] or ["latitude", "longitude"] | ||
- ["northing", "easting"] | ||
- ["row", "col"] or ["line", "sample"] | ||
|
||
The first matching pair determines the spatial dimensions. | ||
|
||
### Validation Rules | ||
|
||
- When `proj:shape` is provided, values MUST match the sizes of identified spatial dimensions | ||
- The order in `proj:shape` is always [y/lat/northing, x/lon/easting] | ||
- If spatial dimensions cannot be identified and `proj:shape` is provided, implementations MUST raise an error | ||
- When multiple CRS representations are provided, precedence is: `proj:projjson` > `proj:wkt2` > `proj:code` | ||
|
||
## Examples | ||
|
||
### Example 1: Simple EPSG Code | ||
|
||
```json | ||
{ | ||
"zarr_format": 3, | ||
"shape": [2048, 2048], | ||
"dimension_names": ["y", "x"], | ||
"attributes": { | ||
"proj:crs": { | ||
"proj:code": "EPSG:3857" | ||
} | ||
} | ||
} | ||
``` | ||
|
||
### Example 2: With Multiple Dimensions and Transform | ||
|
||
```json | ||
{ | ||
"zarr_format": 3, | ||
"shape": [365, 100, 2048, 2048, 4], | ||
"dimension_names": ["time", "height", "latitude", "longitude", "band"], | ||
"attributes": { | ||
"proj:crs": { | ||
"proj:code": "EPSG:4326", | ||
"proj:spatial_dims": ["latitude", "longitude"], | ||
"proj:shape": [2048, 2048], | ||
"proj:transform": [0.1, 0.0, -180.0, 0.0, -0.1, 90.0], | ||
"proj:bbox": [-180.0, -90.0, 180.0, 90.0] | ||
} | ||
} | ||
} | ||
``` | ||
|
||
### Example 3: WKT2 Representation | ||
|
||
```json | ||
{ | ||
"zarr_format": 3, | ||
"shape": [1000, 1000], | ||
"dimension_names": ["northing", "easting"], | ||
"attributes": { | ||
"proj:crs": { | ||
"proj:wkt2": "PROJCRS[\"WGS 84 / UTM zone 33N\",BASEGEOGCRS[\"WGS 84\",DATUM[\"World Geodetic System 1984\",ELLIPSOID[\"WGS 84\",6378137,298.257223563,LENGTHUNIT[\"metre\",1]]],PRIMEM[\"Greenwich\",0,ANGLEUNIT[\"degree\",0.0174532925199433]]],CONVERSION[\"UTM zone 33N\",METHOD[\"Transverse Mercator\",ID[\"EPSG\",9807]],PARAMETER[\"Latitude of natural origin\",0,ANGLEUNIT[\"degree\",0.0174532925199433]],PARAMETER[\"Longitude of natural origin\",15,ANGLEUNIT[\"degree\",0.0174532925199433]],PARAMETER[\"Scale factor at natural origin\",0.9996,SCALEUNIT[\"unity\",1]],PARAMETER[\"False easting\",500000,LENGTHUNIT[\"metre\",1]],PARAMETER[\"False northing\",0,LENGTHUNIT[\"metre\",1]]],CS[Cartesian,2],AXIS[\"easting\",east,ORDER[1],LENGTHUNIT[\"metre\",1]],AXIS[\"northing\",north,ORDER[2],LENGTHUNIT[\"metre\",1]]]", | ||
"proj:shape": [1000, 1000], | ||
"proj:transform": [30.0, 0.0, 500000.0, 0.0, -30.0, 5000000.0] | ||
} | ||
} | ||
} | ||
``` | ||
|
||
## Inheritance | ||
|
||
When `proj:crs` is defined at the group level, it applies to all arrays within that group unless overridden at the array level. | ||
|
||
## Compatibility Notes | ||
|
||
- The `proj:code` field follows the "authority:code" format used by PROJ library | ||
- The `proj:wkt2` field should conform to OGC WKT2 (ISO 19162) standard | ||
- The `proj:transform` field follows the same ordering as GDAL's GeoTransform and STAC's projection extension | ||
|
||
## References | ||
|
||
- [STAC Projection Extension v2.0.0](https://github.com/stac-extensions/projection) | ||
- [PROJJSON Specification](https://proj.org/specifications/projjson.html) | ||
- [OGC WKT2 Standard](https://www.ogc.org/standards/wkt-crs) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
{ | ||
"$schema": "http://json-schema.org/draft-07/schema#", | ||
"$id": "https://zarr-specs.readthedocs.io/en/latest/extensions/attributes/projection/v1.0.0/schema.json", | ||
"title": "Zarr Projection Attribute Extension", | ||
"description": "Projection attribute extension for Zarr arrays and groups", | ||
"type": "object", | ||
"definitions": { | ||
"projectionMetadata": { | ||
"type": "object", | ||
"properties": { | ||
"proj:code": { | ||
"type": ["string", "null"], | ||
"description": "Authority:code identifier (e.g., EPSG:4326)", | ||
"pattern": "^[A-Z]+:[0-9]+$" | ||
}, | ||
"proj:wkt2": { | ||
"type": ["string", "null"], | ||
"description": "WKT2 (ISO 19162) CRS representation" | ||
}, | ||
"proj:projjson": { | ||
"oneOf": [ | ||
{ | ||
"$ref": "https://proj.org/schemas/v0.7/projjson.schema.json" | ||
}, | ||
{ | ||
"type": "null" | ||
} | ||
], | ||
"description": "PROJJSON CRS representation" | ||
}, | ||
"proj:bbox": { | ||
"type": "array", | ||
"oneOf": [ | ||
{ | ||
"minItems": 4, | ||
"maxItems": 4 | ||
}, | ||
{ | ||
"minItems": 6, | ||
"maxItems": 6 | ||
} | ||
], | ||
"items": { | ||
"type": "number" | ||
}, | ||
"description": "Bounding box in CRS coordinates" | ||
}, | ||
"proj:transform": { | ||
"type": "array", | ||
"oneOf": [ | ||
{ | ||
"minItems": 6, | ||
"maxItems": 6 | ||
}, | ||
{ | ||
"minItems": 9, | ||
"maxItems": 9 | ||
} | ||
], | ||
"items": { | ||
"type": "number" | ||
}, | ||
"description": "Affine transformation coefficients" | ||
}, | ||
"proj:shape": { | ||
"type": "array", | ||
"minItems": 2, | ||
"maxItems": 2, | ||
"items": { | ||
"type": "integer", | ||
"minimum": 1 | ||
}, | ||
"description": "Shape of spatial dimensions [y, x]" | ||
}, | ||
"proj:spatial_dims": { | ||
"type": "array", | ||
"minItems": 2, | ||
"maxItems": 2, | ||
"items": { | ||
"type": "string" | ||
}, | ||
"description": "Names of spatial dimensions [y_name, x_name]" | ||
} | ||
}, | ||
"oneOf": [ | ||
{ | ||
"required": ["proj:code"] | ||
}, | ||
{ | ||
"required": ["proj:wkt2"] | ||
}, | ||
{ | ||
"required": ["proj:projjson"] | ||
} | ||
] | ||
} | ||
}, | ||
"properties": { | ||
"attributes": { | ||
"type": "object", | ||
"properties": { | ||
"proj:crs": { | ||
"$ref": "#/definitions/projectionMetadata" | ||
} | ||
} | ||
} | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.