diff --git a/covjsonkit/decoder/Position.py b/covjsonkit/decoder/Position.py index fa94749..1fc5a5f 100644 --- a/covjsonkit/decoder/Position.py +++ b/covjsonkit/decoder/Position.py @@ -75,9 +75,9 @@ def to_geotiff(self): def to_geojson(self): features = [] for coverage in self.covjson["coverages"]: - lat = coverage["domain"]["axes"]["latitude"]["values"][0] - lon = coverage["domain"]["axes"]["longitude"]["values"][0] - z = coverage["domain"]["axes"]["levelist"]["values"][0] + lat = coverage["domain"]["axes"][self.x_name]["values"][0] + lon = coverage["domain"]["axes"][self.y_name]["values"][0] + z = coverage["domain"]["axes"][self.z_name]["values"][0] datetimes = coverage["domain"]["axes"]["t"]["values"] if "mars:metadata" in coverage: mars_metadata = coverage["mars:metadata"] diff --git a/covjsonkit/decoder/TimeSeries.py b/covjsonkit/decoder/TimeSeries.py index 4b11bed..da4794e 100644 --- a/covjsonkit/decoder/TimeSeries.py +++ b/covjsonkit/decoder/TimeSeries.py @@ -75,9 +75,9 @@ def to_geotiff(self): def to_geojson(self): features = [] for coverage in self.covjson["coverages"]: - lat = coverage["domain"]["axes"]["latitude"]["values"][0] - lon = coverage["domain"]["axes"]["longitude"]["values"][0] - z = coverage["domain"]["axes"]["levelist"]["values"][0] + lat = coverage["domain"]["axes"][self.x_name]["values"][0] + lon = coverage["domain"]["axes"][self.y_name]["values"][0] + z = coverage["domain"]["axes"][self.z_name]["values"][0] datetimes = coverage["domain"]["axes"]["t"]["values"] if "mars:metadata" in coverage: mars_metadata = coverage["mars:metadata"] diff --git a/covjsonkit/decoder/VerticalProfile.py b/covjsonkit/decoder/VerticalProfile.py index 6bcb18b..77b161b 100644 --- a/covjsonkit/decoder/VerticalProfile.py +++ b/covjsonkit/decoder/VerticalProfile.py @@ -73,9 +73,9 @@ def to_geotiff(self): def to_geojson(self): features = [] for coverage in self.covjson["coverages"]: - lat = coverage["domain"]["axes"]["latitude"]["values"][0] - lon = coverage["domain"]["axes"]["longitude"]["values"][0] - levels = coverage["domain"]["axes"]["levelist"]["values"] + lat = coverage["domain"]["axes"][self.x_name]["values"][0] + lon = coverage["domain"]["axes"][self.y_name]["values"][0] + levels = coverage["domain"]["axes"][self.z_name]["values"] datetimes = coverage["domain"]["axes"]["t"]["values"] if "mars:metadata" in coverage: mars_metadata = coverage["mars:metadata"] diff --git a/covjsonkit/version.py b/covjsonkit/version.py index 6232f7a..5635676 100644 --- a/covjsonkit/version.py +++ b/covjsonkit/version.py @@ -1 +1 @@ -__version__ = "0.2.10" +__version__ = "0.2.11" diff --git a/tests/data/test_timeseries_xyz_coverage.json b/tests/data/test_timeseries_xyz_coverage.json new file mode 100644 index 0000000..3e0718d --- /dev/null +++ b/tests/data/test_timeseries_xyz_coverage.json @@ -0,0 +1,351 @@ +{ + "type": "CoverageCollection", + "domainType": "PointSeries", + "coverages": [ + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levtype": "sfc", + "number": 1, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + -0.035149384216 + ] + }, + "longitude": { + "values": [ + 0.981308411215 + ] + }, + "levelist": { + "values": [ + 0 + ] + }, + "t": { + "values": [ + "2025-06-23T00:00:00Z", + "2025-06-23T01:00:00Z", + "2025-06-23T02:00:00Z", + "2025-06-23T03:00:00Z" + ] + } + } + }, + "ranges": { + "tcc": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 4 + ], + "axisNames": [ + "tcc" + ], + "values": [ + 0.31280517578125, + 0.45086669921875, + 0.421661376953125, + 0.233123779296875 + ] + }, + "2t": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 4 + ], + "axisNames": [ + "2t" + ], + "values": [ + 299.13653564453125, + 299.2686462402344, + 298.88636779785156, + 298.9047088623047 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levtype": "sfc", + "number": 2, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + -0.035149384216 + ] + }, + "longitude": { + "values": [ + 0.981308411215 + ] + }, + "levelist": { + "values": [ + 0 + ] + }, + "t": { + "values": [ + "2025-06-23T00:00:00Z", + "2025-06-23T01:00:00Z", + "2025-06-23T02:00:00Z", + "2025-06-23T03:00:00Z" + ] + } + } + }, + "ranges": { + "tcc": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 4 + ], + "axisNames": [ + "tcc" + ], + "values": [ + 0.831947922706604, + 0.763214111328125, + 0.762786865234375, + 0.990081787109375 + ] + }, + "2t": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 4 + ], + "axisNames": [ + "2t" + ], + "values": [ + 298.76365661621094, + 298.6814422607422, + 298.86614990234375, + 298.78407287597656 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levtype": "sfc", + "number": 1, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + 38.769770651632 + ] + }, + "longitude": { + "values": [ + 350.914051841746 + ] + }, + "levelist": { + "values": [ + 0 + ] + }, + "t": { + "values": [ + "2025-06-23T00:00:00Z", + "2025-06-23T01:00:00Z", + "2025-06-23T02:00:00Z", + "2025-06-23T03:00:00Z" + ] + } + } + }, + "ranges": { + "tcc": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 4 + ], + "axisNames": [ + "tcc" + ], + "values": [ + 1.0, + 1.0, + 0.205352783203125, + 0.28228759765625 + ] + }, + "2t": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 4 + ], + "axisNames": [ + "2t" + ], + "values": [ + 292.08770751953125, + 292.0010681152344, + 292.27699279785156, + 292.2133026123047 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levtype": "sfc", + "number": 2, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + 38.769770651632 + ] + }, + "longitude": { + "values": [ + 350.914051841746 + ] + }, + "levelist": { + "values": [ + 0 + ] + }, + "t": { + "values": [ + "2025-06-23T00:00:00Z", + "2025-06-23T01:00:00Z", + "2025-06-23T02:00:00Z", + "2025-06-23T03:00:00Z" + ] + } + } + }, + "ranges": { + "tcc": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 4 + ], + "axisNames": [ + "tcc" + ], + "values": [ + 0.9999929666519165, + 1.0, + 0.590179443359375, + 0.099029541015625 + ] + }, + "2t": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 4 + ], + "axisNames": [ + "2t" + ], + "values": [ + 292.56053161621094, + 292.1736297607422, + 291.95794677734375, + 291.95594787597656 + ] + } + } + } + ], + "referencing": [ + { + "coordinates": [ + "x", + "y", + "z" + ], + "system": { + "type": "GeographicCRS", + "id": "http://www.opengis.net/def/crs/OGC/1.3/CRS84" + } + } + ], + "parameters": { + "tcc": { + "type": "Parameter", + "description": { + "en": "This parameter is the proportion of a grid box covered by cloud. Total cloud cover is a single level field calculated from the cloud occurring at different model levels through the atmosphere. Assumptions are made about the degree of overlap/randomness between clouds at different heights.

Cloud fractions vary from 0 to 1.\n
[NOTE: See 228164 for the equivalent parameter in \"%\"]" + }, + "unit": { + "symbol": "(0 - 1)" + }, + "observedProperty": { + "id": "tcc", + "label": { + "en": "Total cloud cover" + } + } + }, + "2t": { + "type": "Parameter", + "description": { + "en": "This parameter is the temperature of air at 2m above the surface of land, sea or in-land waters.

2m temperature is calculated by interpolating between the lowest model level and the Earth's surface, taking account of the atmospheric conditions. See further information .

This parameter has units of kelvin (K). Temperature measured in kelvin can be converted to degrees Celsius (\u00b0C) by subtracting 273.15.

Please note that the encodings listed here for s2s & uerra (which includes encodings for carra/cerra) include entries for Mean 2 metre temperature. The specific encoding for Mean 2 metre temperature can be found in 228004." + }, + "unit": { + "symbol": "K" + }, + "observedProperty": { + "id": "2t", + "label": { + "en": "2 metre temperature" + } + } + } + } +} \ No newline at end of file diff --git a/tests/data/test_verticalprofile_coverage.json b/tests/data/test_verticalprofile_coverage.json index c9d892c..ed71891 100644 --- a/tests/data/test_verticalprofile_coverage.json +++ b/tests/data/test_verticalprofile_coverage.json @@ -1 +1,572 @@ -{"type": "CoverageCollection", "domainType": "VerticalProfile", "coverages": [{"mars:metadata": {"class": "od", "Forecast date": "2025-06-23T00:00:00Z", "domain": "g", "expver": "0001", "levelist": 1, "levtype": "pl", "number": 1, "step": 0, "stream": "enfo", "type": "pf"}, "type": "Coverage", "domain": {"type": "Domain", "axes": {"latitude": {"values": [-0.035149384216]}, "longitude": {"values": [0.981308411215]}, "levelist": {"values": [1, 2, 3, 5, 7, 10, 20]}, "t": {"values": ["2025-06-23T00:00:00Z"]}}}, "ranges": {"q": {"type": "NdArray", "dataType": "float", "shape": [7], "axisNames": ["levelist"], "values": [4.482228177948855e-06, 4.444737896847073e-06, 4.3706095311790705e-06, 4.0073391573969275e-06, 3.6435558286029845e-06, 3.2262623790302314e-06, 3.0683795557706617e-06]}}}, {"mars:metadata": {"class": "od", "Forecast date": "2025-06-23T00:00:00Z", "domain": "g", "expver": "0001", "levelist": 1, "levtype": "pl", "number": 1, "step": 1, "stream": "enfo", "type": "pf"}, "type": "Coverage", "domain": {"type": "Domain", "axes": {"latitude": {"values": [-0.035149384216]}, "longitude": {"values": [0.981308411215]}, "levelist": {"values": [1, 2, 3, 5, 7, 10, 20]}, "t": {"values": ["2025-06-23T01:00:00Z"]}}}, "ranges": {"q": {"type": "NdArray", "dataType": "float", "shape": [7], "axisNames": ["levelist"], "values": [4.487486876314506e-06, 4.4314983824733645e-06, 4.3832060327986255e-06, 4.02079604100436e-06, 3.627267687988933e-06, 3.233985808037687e-06, 3.054315129702445e-06]}}}, {"mars:metadata": {"class": "od", "Forecast date": "2025-06-23T00:00:00Z", "domain": "g", "expver": "0001", "levelist": 1, "levtype": "pl", "number": 2, "step": 0, "stream": "enfo", "type": "pf"}, "type": "Coverage", "domain": {"type": "Domain", "axes": {"latitude": {"values": [-0.035149384216]}, "longitude": {"values": [0.981308411215]}, "levelist": {"values": [1, 2, 3, 5, 7, 10, 20]}, "t": {"values": ["2025-06-23T00:00:00Z"]}}}, "ranges": {"q": {"type": "NdArray", "dataType": "float", "shape": [7], "axisNames": ["levelist"], "values": [4.201782076052041e-06, 4.282088411855511e-06, 4.331615855335258e-06, 4.028772309538908e-06, 3.6359106161398813e-06, 3.2297457437380217e-06, 3.0871296985424124e-06]}}}, {"mars:metadata": {"class": "od", "Forecast date": "2025-06-23T00:00:00Z", "domain": "g", "expver": "0001", "levelist": 1, "levtype": "pl", "number": 2, "step": 1, "stream": "enfo", "type": "pf"}, "type": "Coverage", "domain": {"type": "Domain", "axes": {"latitude": {"values": [-0.035149384216]}, "longitude": {"values": [0.981308411215]}, "levelist": {"values": [1, 2, 3, 5, 7, 10, 20]}, "t": {"values": ["2025-06-23T01:00:00Z"]}}}, "ranges": {"q": {"type": "NdArray", "dataType": "float", "shape": [7], "axisNames": ["levelist"], "values": [4.185261843758781e-06, 4.284713213564828e-06, 4.3478394218254834e-06, 4.017736500827596e-06, 3.635374923760537e-06, 3.232900780858472e-06, 3.0775609047850594e-06]}}}, {"mars:metadata": {"class": "od", "Forecast date": "2025-06-23T00:00:00Z", "domain": "g", "expver": "0001", "levelist": 1, "levtype": "pl", "number": 1, "step": 0, "stream": "enfo", "type": "pf"}, "type": "Coverage", "domain": {"type": "Domain", "axes": {"latitude": {"values": [38.910368186756]}, "longitude": {"values": [350.889192886457]}, "levelist": {"values": [1, 2, 3, 5, 7, 10, 20]}, "t": {"values": ["2025-06-23T00:00:00Z"]}}}, "ranges": {"q": {"type": "NdArray", "dataType": "float", "shape": [7], "axisNames": ["levelist"], "values": [4.3810632632812485e-06, 4.301430635678116e-06, 4.141271347180009e-06, 3.946424840250984e-06, 3.849378117593005e-06, 3.714595550263766e-06, 3.350861334183719e-06]}}}, {"mars:metadata": {"class": "od", "Forecast date": "2025-06-23T00:00:00Z", "domain": "g", "expver": "0001", "levelist": 1, "levtype": "pl", "number": 1, "step": 1, "stream": "enfo", "type": "pf"}, "type": "Coverage", "domain": {"type": "Domain", "axes": {"latitude": {"values": [38.910368186756]}, "longitude": {"values": [350.889192886457]}, "levelist": {"values": [1, 2, 3, 5, 7, 10, 20]}, "t": {"values": ["2025-06-23T01:00:00Z"]}}}, "ranges": {"q": {"type": "NdArray", "dataType": "float", "shape": [7], "axisNames": ["levelist"], "values": [4.363620973890647e-06, 4.310193617129698e-06, 4.14641726820264e-06, 3.9454171201214194e-06, 3.844673301500734e-06, 3.720980203070212e-06, 3.3482638173154555e-06]}}}, {"mars:metadata": {"class": "od", "Forecast date": "2025-06-23T00:00:00Z", "domain": "g", "expver": "0001", "levelist": 1, "levtype": "pl", "number": 2, "step": 0, "stream": "enfo", "type": "pf"}, "type": "Coverage", "domain": {"type": "Domain", "axes": {"latitude": {"values": [38.910368186756]}, "longitude": {"values": [350.889192886457]}, "levelist": {"values": [1, 2, 3, 5, 7, 10, 20]}, "t": {"values": ["2025-06-23T00:00:00Z"]}}}, "ranges": {"q": {"type": "NdArray", "dataType": "float", "shape": [7], "axisNames": ["levelist"], "values": [4.255100293448777e-06, 4.277315383660607e-06, 4.128412911086343e-06, 3.9497263060184196e-06, 3.843391823465936e-06, 3.71234546037158e-06, 3.364314579812344e-06]}}}, {"mars:metadata": {"class": "od", "Forecast date": "2025-06-23T00:00:00Z", "domain": "g", "expver": "0001", "levelist": 1, "levtype": "pl", "number": 2, "step": 1, "stream": "enfo", "type": "pf"}, "type": "Coverage", "domain": {"type": "Domain", "axes": {"latitude": {"values": [38.910368186756]}, "longitude": {"values": [350.889192886457]}, "levelist": {"values": [1, 2, 3, 5, 7, 10, 20]}, "t": {"values": ["2025-06-23T01:00:00Z"]}}}, "ranges": {"q": {"type": "NdArray", "dataType": "float", "shape": [7], "axisNames": ["levelist"], "values": [4.274668810921867e-06, 4.271092620911077e-06, 4.144170816289261e-06, 3.943900082958862e-06, 3.83627866540337e-06, 3.7143654481042176e-06, 3.3630112739047036e-06]}}}], "referencing": [{"coordinates": ["latitude", "longitude", "levelist"], "system": {"type": "GeographicCRS", "id": "http://www.opengis.net/def/crs/OGC/1.3/CRS84"}}], "parameters": {"q": {"type": "Parameter", "description": {"en": "This parameter is the mass of water vapour per kilogram of moist air.

The total mass of moist air is the sum of the dry air, water vapour, cloud liquid, cloud ice, rain and falling snow."}, "unit": {"symbol": "kg kg**-1"}, "observedProperty": {"id": "q", "label": {"en": "Specific humidity"}}}}} +{ + "type": "CoverageCollection", + "domainType": "VerticalProfile", + "coverages": [ + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 1, + "step": 0, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + -0.035149384216 + ] + }, + "longitude": { + "values": [ + 0.981308411215 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T00:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.482228177948855e-06, + 4.444737896847073e-06, + 4.3706095311790705e-06, + 4.0073391573969275e-06, + 3.6435558286029845e-06, + 3.2262623790302314e-06, + 3.0683795557706617e-06 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 1, + "step": 1, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + -0.035149384216 + ] + }, + "longitude": { + "values": [ + 0.981308411215 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T01:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.487486876314506e-06, + 4.4314983824733645e-06, + 4.3832060327986255e-06, + 4.02079604100436e-06, + 3.627267687988933e-06, + 3.233985808037687e-06, + 3.054315129702445e-06 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 2, + "step": 0, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + -0.035149384216 + ] + }, + "longitude": { + "values": [ + 0.981308411215 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T00:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.201782076052041e-06, + 4.282088411855511e-06, + 4.331615855335258e-06, + 4.028772309538908e-06, + 3.6359106161398813e-06, + 3.2297457437380217e-06, + 3.0871296985424124e-06 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 2, + "step": 1, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + -0.035149384216 + ] + }, + "longitude": { + "values": [ + 0.981308411215 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T01:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.185261843758781e-06, + 4.284713213564828e-06, + 4.3478394218254834e-06, + 4.017736500827596e-06, + 3.635374923760537e-06, + 3.232900780858472e-06, + 3.0775609047850594e-06 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 1, + "step": 0, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + 38.910368186756 + ] + }, + "longitude": { + "values": [ + 350.889192886457 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T00:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.3810632632812485e-06, + 4.301430635678116e-06, + 4.141271347180009e-06, + 3.946424840250984e-06, + 3.849378117593005e-06, + 3.714595550263766e-06, + 3.350861334183719e-06 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 1, + "step": 1, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + 38.910368186756 + ] + }, + "longitude": { + "values": [ + 350.889192886457 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T01:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.363620973890647e-06, + 4.310193617129698e-06, + 4.14641726820264e-06, + 3.9454171201214194e-06, + 3.844673301500734e-06, + 3.720980203070212e-06, + 3.3482638173154555e-06 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 2, + "step": 0, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + 38.910368186756 + ] + }, + "longitude": { + "values": [ + 350.889192886457 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T00:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.255100293448777e-06, + 4.277315383660607e-06, + 4.128412911086343e-06, + 3.9497263060184196e-06, + 3.843391823465936e-06, + 3.71234546037158e-06, + 3.364314579812344e-06 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 2, + "step": 1, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + 38.910368186756 + ] + }, + "longitude": { + "values": [ + 350.889192886457 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T01:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.274668810921867e-06, + 4.271092620911077e-06, + 4.144170816289261e-06, + 3.943900082958862e-06, + 3.83627866540337e-06, + 3.7143654481042176e-06, + 3.3630112739047036e-06 + ] + } + } + } + ], + "referencing": [ + { + "coordinates": [ + "latitude", + "longitude", + "levelist" + ], + "system": { + "type": "GeographicCRS", + "id": "http://www.opengis.net/def/crs/OGC/1.3/CRS84" + } + } + ], + "parameters": { + "q": { + "type": "Parameter", + "description": { + "en": "This parameter is the mass of water vapour per kilogram of moist air.

The total mass of moist air is the sum of the dry air, water vapour, cloud liquid, cloud ice, rain and falling snow." + }, + "unit": { + "symbol": "kg kg**-1" + }, + "observedProperty": { + "id": "q", + "label": { + "en": "Specific humidity" + } + } + } + } +} \ No newline at end of file diff --git a/tests/data/test_verticalprofile_xyz_coverage.json b/tests/data/test_verticalprofile_xyz_coverage.json new file mode 100644 index 0000000..28b7f2f --- /dev/null +++ b/tests/data/test_verticalprofile_xyz_coverage.json @@ -0,0 +1,572 @@ +{ + "type": "CoverageCollection", + "domainType": "VerticalProfile", + "coverages": [ + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 1, + "step": 0, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + -0.035149384216 + ] + }, + "longitude": { + "values": [ + 0.981308411215 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T00:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.482228177948855e-06, + 4.444737896847073e-06, + 4.3706095311790705e-06, + 4.0073391573969275e-06, + 3.6435558286029845e-06, + 3.2262623790302314e-06, + 3.0683795557706617e-06 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 1, + "step": 1, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + -0.035149384216 + ] + }, + "longitude": { + "values": [ + 0.981308411215 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T01:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.487486876314506e-06, + 4.4314983824733645e-06, + 4.3832060327986255e-06, + 4.02079604100436e-06, + 3.627267687988933e-06, + 3.233985808037687e-06, + 3.054315129702445e-06 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 2, + "step": 0, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + -0.035149384216 + ] + }, + "longitude": { + "values": [ + 0.981308411215 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T00:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.201782076052041e-06, + 4.282088411855511e-06, + 4.331615855335258e-06, + 4.028772309538908e-06, + 3.6359106161398813e-06, + 3.2297457437380217e-06, + 3.0871296985424124e-06 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 2, + "step": 1, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + -0.035149384216 + ] + }, + "longitude": { + "values": [ + 0.981308411215 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T01:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.185261843758781e-06, + 4.284713213564828e-06, + 4.3478394218254834e-06, + 4.017736500827596e-06, + 3.635374923760537e-06, + 3.232900780858472e-06, + 3.0775609047850594e-06 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 1, + "step": 0, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + 38.910368186756 + ] + }, + "longitude": { + "values": [ + 350.889192886457 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T00:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.3810632632812485e-06, + 4.301430635678116e-06, + 4.141271347180009e-06, + 3.946424840250984e-06, + 3.849378117593005e-06, + 3.714595550263766e-06, + 3.350861334183719e-06 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 1, + "step": 1, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + 38.910368186756 + ] + }, + "longitude": { + "values": [ + 350.889192886457 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T01:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.363620973890647e-06, + 4.310193617129698e-06, + 4.14641726820264e-06, + 3.9454171201214194e-06, + 3.844673301500734e-06, + 3.720980203070212e-06, + 3.3482638173154555e-06 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 2, + "step": 0, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + 38.910368186756 + ] + }, + "longitude": { + "values": [ + 350.889192886457 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T00:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.255100293448777e-06, + 4.277315383660607e-06, + 4.128412911086343e-06, + 3.9497263060184196e-06, + 3.843391823465936e-06, + 3.71234546037158e-06, + 3.364314579812344e-06 + ] + } + } + }, + { + "mars:metadata": { + "class": "od", + "Forecast date": "2025-06-23T00:00:00Z", + "domain": "g", + "expver": "0001", + "levelist": 1, + "levtype": "pl", + "number": 2, + "step": 1, + "stream": "enfo", + "type": "pf" + }, + "type": "Coverage", + "domain": { + "type": "Domain", + "axes": { + "latitude": { + "values": [ + 38.910368186756 + ] + }, + "longitude": { + "values": [ + 350.889192886457 + ] + }, + "levelist": { + "values": [ + 1, + 2, + 3, + 5, + 7, + 10, + 20 + ] + }, + "t": { + "values": [ + "2025-06-23T01:00:00Z" + ] + } + } + }, + "ranges": { + "q": { + "type": "NdArray", + "dataType": "float", + "shape": [ + 7 + ], + "axisNames": [ + "levelist" + ], + "values": [ + 4.274668810921867e-06, + 4.271092620911077e-06, + 4.144170816289261e-06, + 3.943900082958862e-06, + 3.83627866540337e-06, + 3.7143654481042176e-06, + 3.3630112739047036e-06 + ] + } + } + } + ], + "referencing": [ + { + "coordinates": [ + "x", + "y", + "z" + ], + "system": { + "type": "GeographicCRS", + "id": "http://www.opengis.net/def/crs/OGC/1.3/CRS84" + } + } + ], + "parameters": { + "q": { + "type": "Parameter", + "description": { + "en": "This parameter is the mass of water vapour per kilogram of moist air.

The total mass of moist air is the sum of the dry air, water vapour, cloud liquid, cloud ice, rain and falling snow." + }, + "unit": { + "symbol": "kg kg**-1" + }, + "observedProperty": { + "id": "q", + "label": { + "en": "Specific humidity" + } + } + } + } +} \ No newline at end of file diff --git a/tests/test_geojson.py b/tests/test_geojson.py index 8df5dab..a684aef 100644 --- a/tests/test_geojson.py +++ b/tests/test_geojson.py @@ -11,10 +11,18 @@ def setup_method(self): with open(timeseries, "r") as f: self.timeseries = json.load(f) + timeseries_xyz = os.path.join(current_dir, "data/test_timeseries_xyz_coverage.json") + with open(timeseries_xyz, "r") as f: + self.timeseries_xyz = json.load(f) + verticalprofile = os.path.join(current_dir, "data/test_verticalprofile_coverage.json") with open(verticalprofile, "r") as f: self.verticalprofile = json.load(f) + verticalprofile_xyz = os.path.join(current_dir, "data/test_verticalprofile_xyz_coverage.json") + with open(verticalprofile_xyz, "r") as f: + self.verticalprofile_xyz = json.load(f) + path = os.path.join(current_dir, "data/test_path_coverage.json") with open(path, "r") as f: self.path = json.load(f) @@ -29,12 +37,25 @@ def test_geojson_timeseries(self): assert ts["type"] == "FeatureCollection" assert len(ts["features"]) == 16 + + def test_geojson_xyz_axes_timeseries(self): + cov = Covjsonkit().decode(self.timeseries_xyz) + ts = cov.to_geojson() + assert ts["type"] == "FeatureCollection" + assert len(ts["features"]) == 16 + def test_geojson_verticalprofile(self): cov = Covjsonkit().decode(self.verticalprofile) vp = cov.to_geojson() assert vp["type"] == "FeatureCollection" assert len(vp["features"]) == 56 + def test_geojson_xyz_axes_verticalprofile(self): + cov = Covjsonkit().decode(self.verticalprofile_xyz) + vp = cov.to_geojson() + assert vp["type"] == "FeatureCollection" + assert len(vp["features"]) == 56 + def test_geojson_path(self): cov = Covjsonkit().decode(self.path) path = cov.to_geojson()