-
Notifications
You must be signed in to change notification settings - Fork 3
Add Spatial Zarr Convention models and metadata #100
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
Merged
Merged
Changes from 11 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
4528bb6
feat: add Spatial Zarr Convention models and metadata
emmanuelmathot 4490403
fix: enhance multiscales metadata handling with fallback for bounds a…
emmanuelmathot 94ba321
Update eopf-geozarr version to 0.5.1.dev18+g4528bb6b0.d20251216 in uv…
emmanuelmathot 79cf61a
fix: improve formatting and consistency in geospatial metadata classes
emmanuelmathot 6e853cb
feat: add spatial properties to overview level metadata and update ty…
emmanuelmathot e88d4ea
feat: implement tests for Spatial Zarr Convention models and metadata
emmanuelmathot 7b52696
feat: enhance Proj and ProjConventionMetadata tests for serialization…
emmanuelmathot 4449dd8
feat: add validation for non-empty dimensions in Spatial model
emmanuelmathot 9f184a7
fix: remove redundant imports of ProjConventionMetadata and SpatialCo…
emmanuelmathot c436412
feat: add spatial properties and projection information to Zarr conve…
emmanuelmathot 44aaa2d
feat: update spatial metadata and derivation chains in Zarr examples …
emmanuelmathot 9a42275
fix: remove redundant version field from MultiscaleMeta and Multiscal…
emmanuelmathot 32a425b
refactor: streamline spatial metadata calculation and error handling …
emmanuelmathot a505939
fix: remove redundant version field from multiscales and optimized ge…
emmanuelmathot 40bd7bf
fix: improve transform calculation logging for multiscales metadata
emmanuelmathot 00630c8
fix: add validation for spatial transform data to prevent all-zero en…
emmanuelmathot 41a1665
fix: remove redundant spatial transform entries from optimized geozar…
emmanuelmathot 1b88c53
fix: allow spatial_transform to be None in OverviewLevelJSON type def…
emmanuelmathot 212108e
fix: refactor ScaleLevel initialization and remove redundant spatial_…
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
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
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 |
|---|---|---|
| @@ -1,54 +1,61 @@ | ||
| """ | ||
| Models for the GeoProj Zarr Convention | ||
| Models for the Proj Zarr Convention (v1.0) | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from typing import Literal, Self | ||
| from typing import Literal | ||
|
|
||
| from pydantic import BaseModel, Field, model_validator | ||
| from typing_extensions import TypedDict | ||
|
|
||
| from eopf_geozarr.data_api.geozarr.common import is_none | ||
| from eopf_geozarr.data_api.geozarr.common import ZarrConventionMetadata, is_none | ||
| from eopf_geozarr.data_api.geozarr.projjson import ProjJSON # noqa: TC001 | ||
|
|
||
| GEO_PROJ_UUID: Literal["f17cb550-5864-4468-aeb7-f3180cfb622f"] = ( | ||
| "f17cb550-5864-4468-aeb7-f3180cfb622f" | ||
| ) | ||
| PROJ_UUID: Literal["f17cb550-5864-4468-aeb7-f3180cfb622f"] = "f17cb550-5864-4468-aeb7-f3180cfb622f" | ||
|
|
||
|
|
||
| class GeoProjConvention(TypedDict): | ||
| version: Literal["0.1.0"] | ||
| schema: Literal[ | ||
| "https://raw.githubusercontent.com/zarr-experimental/geo-proj/refs/tags/v0.1.0/schema.json" | ||
| class ProjConvention(TypedDict): | ||
| uuid: Literal["f17cb550-5864-4468-aeb7-f3180cfb622f"] | ||
| name: Literal["proj:"] | ||
| schema_url: Literal[ | ||
| "https://raw.githubusercontent.com/zarr-experimental/geo-proj/refs/tags/v1/schema.json" | ||
| ] | ||
| name: Literal["geo-proj"] | ||
| spec_url: Literal["https://github.com/zarr-experimental/geo-proj/blob/v1/README.md"] | ||
| description: Literal["Coordinate reference system information for geospatial data"] | ||
| spec: Literal["https://github.com/zarr-experimental/geo-proj/blob/v0.1.0/README.md"] | ||
|
|
||
|
|
||
| GeoProjConventions = TypedDict( # type: ignore[misc] | ||
| "GeoProjConventions", {GEO_PROJ_UUID: GeoProjConvention}, closed=False | ||
| ) | ||
| class ProjConventionMetadata(ZarrConventionMetadata): | ||
| uuid: Literal["f17cb550-5864-4468-aeb7-f3180cfb622f"] = PROJ_UUID | ||
| name: Literal["proj:"] = "proj:" | ||
| schema_url: Literal[ | ||
| "https://raw.githubusercontent.com/zarr-experimental/geo-proj/refs/tags/v1/schema.json" | ||
| ] = "https://raw.githubusercontent.com/zarr-experimental/geo-proj/refs/tags/v1/schema.json" | ||
| spec_url: Literal["https://github.com/zarr-experimental/geo-proj/blob/v1/README.md"] = ( | ||
| "https://github.com/zarr-experimental/geo-proj/blob/v1/README.md" | ||
| ) | ||
| description: Literal["Coordinate reference system information for geospatial data"] = ( | ||
| "Coordinate reference system information for geospatial data" | ||
| ) | ||
|
|
||
|
|
||
| class GeoProj(BaseModel): | ||
| class Proj(BaseModel): | ||
| # At least one of code, wkt2, or projjson must be provided | ||
| code: str | None = Field(None, alias="proj:code", exclude_if=is_none) | ||
| wkt2: str | None = Field(None, alias="proj:wkt2", exclude_if=is_none) | ||
| projjson: ProjJSON | None = Field(None, alias="proj:projjson", exclude_if=is_none) | ||
| spatial_dimensions: tuple[str, str] = Field(alias="proj:spatial_dimensions") | ||
| transform: tuple[float, float, float, float, float, float] | None = Field( | ||
| None, alias="proj:transform", exclude_if=is_none | ||
| ) | ||
| bbox: tuple[float, float, float, float] | None = Field( | ||
| None, alias="proj:bbox", exclude_if=is_none | ||
| ) | ||
| shape: tuple[int, int] | None = Field(None, alias="proj:shape", exclude_if=is_none) | ||
|
|
||
| model_config = {"extra": "allow", "serialize_by_alias": True} | ||
|
|
||
| @model_validator(mode="after") | ||
| def ensure_required_conditional_attributes(self) -> Self: | ||
| if self.code is None and self.wkt2 is None and self.projjson is None: | ||
| raise ValueError("One of 'code', 'wkt2', or 'projjson' must be provided.") | ||
| def validate_at_least_one_crs(self) -> Proj: | ||
| """Validate that at least one CRS field is provided""" | ||
| if not any([self.code, self.wkt2, self.projjson]): | ||
| raise ValueError( | ||
| "At least one of proj:code, proj:wkt2, or proj:projjson must be provided" | ||
| ) | ||
| return self | ||
|
|
||
|
|
||
| # Backwards compatibility alias | ||
| GeoProj = Proj | ||
emmanuelmathot marked this conversation as resolved.
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
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,58 @@ | ||
| """ | ||
| Models for the Spatial Zarr Convention | ||
| """ | ||
|
|
||
| from __future__ import annotations | ||
|
|
||
| from typing import Literal | ||
|
|
||
| from pydantic import BaseModel, Field, model_validator | ||
| from typing_extensions import TypedDict | ||
|
|
||
| from eopf_geozarr.data_api.geozarr.common import ZarrConventionMetadata, is_none | ||
|
|
||
| SPATIAL_UUID: Literal["689b58e2-cf7b-45e0-9fff-9cfc0883d6b4"] = ( | ||
| "689b58e2-cf7b-45e0-9fff-9cfc0883d6b4" | ||
| ) | ||
|
|
||
|
|
||
| class SpatialConvention(TypedDict): | ||
| uuid: Literal["689b58e2-cf7b-45e0-9fff-9cfc0883d6b4"] | ||
| name: Literal["spatial:"] | ||
| schema_url: Literal[ | ||
| "https://raw.githubusercontent.com/zarr-conventions/spatial/refs/tags/v1/schema.json" | ||
| ] | ||
| spec_url: Literal["https://github.com/zarr-conventions/spatial/blob/v1/README.md"] | ||
| description: Literal["Spatial coordinate and transformation information"] | ||
|
|
||
|
|
||
| class SpatialConventionMetadata(ZarrConventionMetadata): | ||
| uuid: Literal["689b58e2-cf7b-45e0-9fff-9cfc0883d6b4"] = SPATIAL_UUID | ||
| name: Literal["spatial:"] = "spatial:" | ||
| schema_url: Literal[ | ||
| "https://raw.githubusercontent.com/zarr-conventions/spatial/refs/tags/v1/schema.json" | ||
| ] = "https://raw.githubusercontent.com/zarr-conventions/spatial/refs/tags/v1/schema.json" | ||
| spec_url: Literal["https://github.com/zarr-conventions/spatial/blob/v1/README.md"] = ( | ||
| "https://github.com/zarr-conventions/spatial/blob/v1/README.md" | ||
| ) | ||
| description: Literal["Spatial coordinate and transformation information"] = ( | ||
| "Spatial coordinate and transformation information" | ||
| ) | ||
|
|
||
|
|
||
| class Spatial(BaseModel): | ||
| dimensions: list[str] = Field(alias="spatial:dimensions") # Required field | ||
emmanuelmathot marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| bbox: list[float] | None = Field(None, alias="spatial:bbox", exclude_if=is_none) | ||
| transform_type: str = Field("affine", alias="spatial:transform_type") | ||
| transform: list[float] | None = Field(None, alias="spatial:transform", exclude_if=is_none) | ||
| shape: list[int] | None = Field(None, alias="spatial:shape", exclude_if=is_none) | ||
| registration: str = Field("pixel", alias="spatial:registration") | ||
|
|
||
| model_config = {"extra": "allow", "serialize_by_alias": True} | ||
|
|
||
| @model_validator(mode="after") | ||
| def validate_dimensions_not_empty(self) -> Spatial: | ||
| """Validate that dimensions list is not empty.""" | ||
| if not self.dimensions: | ||
| raise ValueError("spatial:dimensions must contain at least one dimension") | ||
| return self | ||
Oops, something went wrong.
Oops, something went wrong.
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.