diff --git a/pyproject.toml b/pyproject.toml index 471c791..df908ec 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ classifiers = [ "Topic :: Scientific/Engineering :: GIS", "Typing :: Typed", ] -version = "0.3.0" +version = "0.4.0" dependencies = ["pydantic>=2.3,<3"] [project.optional-dependencies] diff --git a/src/edr_pydantic/parameter.py b/src/edr_pydantic/parameter.py index d8da3cb..466dbde 100644 --- a/src/edr_pydantic/parameter.py +++ b/src/edr_pydantic/parameter.py @@ -11,6 +11,14 @@ from .unit import Unit +class MeasurementType(EdrBaseModel): + method: str + # TODO: Add validation of ISO 8601 duration (including leading minus sign) + # TODO: Confusion in spec on the field name, duration versus period. + # See https://github.com/opengeospatial/ogcapi-environmental-data-retrieval/issues/560 + period: str + + class Parameter(EdrBaseModel, extra="allow"): type: Literal["Parameter"] = "Parameter" id: Optional[str] = None @@ -18,6 +26,7 @@ class Parameter(EdrBaseModel, extra="allow"): description: Optional[str] = None unit: Optional[Unit] = None observedProperty: ObservedProperty # noqa: N815 + measurementType: Optional[MeasurementType] = None # noqa: N815 @model_validator(mode="after") def must_not_have_unit_if_observed_property_has_categories(self): diff --git a/tests/test_data/parameter-names.json b/tests/test_data/parameter-names.json new file mode 100644 index 0000000..1583484 --- /dev/null +++ b/tests/test_data/parameter-names.json @@ -0,0 +1,59 @@ +{ + "Temperature_altitude_above_msl": { + "type": "Parameter", + "description": "Temperature for Specific altitude above MSL", + "unit": { + "label": "K", + "symbol": { + "value": "K", + "type": "http://qudt.org/vocab/unit/K" + } + }, + "observedProperty": { + "id": "http://codes.wmo.int/grib2/codeflag/4.2/_0-0-0", + "label": "Temperature_altitude_above_msl" + }, + "measurementType": { + "method": "instantaneous", + "period": "PT0S" + } + }, + "u-component_of_wind_altitude_above_msl": { + "type": "Parameter", + "description": "u-component of wind for Specific altitude above MSL", + "unit": { + "label": "m/s", + "symbol": { + "value": "m%20s", + "type": "http://qudt.org/vocab/unit/M-PER-SEC.html" + } + }, + "observedProperty": { + "id": "http://codes.wmo.int/grib2/codeflag/4.2/_0-2-2", + "label": "u-component_of_wind_altitude_above_msl" + }, + "measurementType": { + "method": "instantaneous", + "period": "PT0S" + } + }, + "v-component_of_wind_altitude_above_msl": { + "type": "Parameter", + "description": "v-component of wind for Specific altitude above MSL", + "unit": { + "label": "m/s", + "symbol": { + "value": "m%20s", + "type": "http://qudt.org/vocab/unit/M-PER-SEC.html" + } + }, + "observedProperty": { + "id": "http://codes.wmo.int/grib2/codeflag/4.2/_0-2-3", + "label": "v-component_of_wind_altitude_above_msl" + }, + "measurementType": { + "method": "instantaneous", + "period": "PT0S" + } + } +} diff --git a/tests/test_edr.py b/tests/test_edr.py index c68e4ac..81c6da8 100644 --- a/tests/test_edr.py +++ b/tests/test_edr.py @@ -1,12 +1,15 @@ import json from pathlib import Path +from typing import Dict import pytest from edr_pydantic.capabilities import LandingPageModel from edr_pydantic.collections import Collections from edr_pydantic.collections import Instance from edr_pydantic.extent import Extent +from edr_pydantic.parameter import Parameter from edr_pydantic.unit import Unit +from pydantic import RootModel from pydantic import ValidationError happy_cases = [ @@ -15,6 +18,7 @@ ("simple-instance.json", Instance), ("landing-page.json", LandingPageModel), ("doc-example-extent.json", Extent), + ("parameter-names.json", RootModel[Dict[str, Parameter]]), ]