Valid EDR cube queries for data with decreasing coordinates (#1402)

* resolving case when lat dimensions are decreasing

CF conventions state only that a "coordinate variable must have values that are strictly monotonic (increasing or decreasing)." In the case of PRISM, the lat coordinates are decreasing. pygeoapi failed due to the lat dimension being empty with existing implementation; this update addresses the issue.

* remove blank space

* resolving case when lat dimensions are decreasing

CF conventions state only that a "coordinate variable must have values that are strictly monotonic (increasing or decreasing)." In the case of PRISM, the lat coordinates are decreasing. pygeoapi failed due to the lat dimension being empty with existing implementation; this update addresses the issue.

* remove blank space

* test decreasing latitude

The new test will now uncover if you can successfully serve data stored on S3 AND test if you can perform a cube query on data with monotonically decreasing latitude coordinates at the same time.

* flake8 py3 fixes
This commit is contained in:
Sarah Jordan
2023-11-15 17:03:15 -06:00
committed by GitHub
parent de1a7d93ee
commit 08fa2b7286
3 changed files with 39 additions and 21 deletions
+18 -3
View File
@@ -33,7 +33,11 @@ import numpy as np
from pygeoapi.provider.base import ProviderNoDataError, ProviderQueryError from pygeoapi.provider.base import ProviderNoDataError, ProviderQueryError
from pygeoapi.provider.base_edr import BaseEDRProvider from pygeoapi.provider.base_edr import BaseEDRProvider
from pygeoapi.provider.xarray_ import _to_datetime_string, XarrayProvider from pygeoapi.provider.xarray_ import (
_to_datetime_string,
_convert_float32_to_float64,
XarrayProvider,
)
LOGGER = logging.getLogger(__name__) LOGGER = logging.getLogger(__name__)
@@ -180,9 +184,11 @@ class XarrayEDRProvider(BaseEDRProvider, XarrayProvider):
LOGGER.debug(f"Query type: {kwargs.get('query_type')}") LOGGER.debug(f"Query type: {kwargs.get('query_type')}")
bbox = kwargs.get('bbox') bbox = kwargs.get('bbox')
xmin, ymin, xmax, ymax = self._configure_bbox(bbox)
if len(bbox) == 4: if len(bbox) == 4:
query_params[self.x_field] = slice(bbox[0], bbox[2]) query_params[self.x_field] = slice(bbox[xmin], bbox[xmax])
query_params[self.y_field] = slice(bbox[1], bbox[3]) query_params[self.y_field] = slice(bbox[ymin], bbox[ymax])
else: else:
raise ProviderQueryError('z-axis not supported') raise ProviderQueryError('z-axis not supported')
@@ -206,6 +212,7 @@ class XarrayEDRProvider(BaseEDRProvider, XarrayProvider):
else: else:
data = self._data data = self._data
data = data.sel(query_params) data = data.sel(query_params)
data = _convert_float32_to_float64(data)
except KeyError: except KeyError:
raise ProviderNoDataError() raise ProviderNoDataError()
@@ -288,3 +295,11 @@ class XarrayEDRProvider(BaseEDRProvider, XarrayProvider):
except KeyError: except KeyError:
time_steps = kwargs.get('limit') time_steps = kwargs.get('limit')
return time, time_steps return time, time_steps
def _configure_bbox(self, bbox):
xmin, ymin, xmax, ymax = 0, 1, 2, 3
if self._data[self.x_field][0] > self._data[self.x_field][-1]:
xmin, xmax = xmax, xmin
if self._data[self.y_field][0] > self._data[self.y_field][-1]:
ymin, ymax = ymax, ymin
return xmin, ymin, xmax, ymax
+10 -9
View File
@@ -314,28 +314,27 @@ resources:
name: NetCDF name: NetCDF
mimetype: application/x-netcdf mimetype: application/x-netcdf
nasa-power: usgs-prism:
type: collection type: collection
title: NASA Prediction Of Worldwide Energy Resources (POWER) title: Parameter-elevation Regressions on Independent Slopes Model (PRISM)
description: NASA Prediction Of Worldwide Energy Resources (POWER) description: PRISM Monthly Climate Data for the Continental United States
keywords: keywords:
- nasa - temperature
- energy - precipitation
- power
extents: extents:
spatial: spatial:
bbox: [-180,-90,180,90] bbox: [-125.020836, 24.104166, -66.520836, 49.9375]
crs: http://www.opengis.net/def/crs/OGC/1.3/CRS84 crs: http://www.opengis.net/def/crs/OGC/1.3/CRS84
links: links:
- type: text/html - type: text/html
rel: canonical rel: canonical
title: information title: information
href: https://power.larc.nasa.gov/ href: https://cida.usgs.gov/thredds/catalog.html?dataset=cida.usgs.gov/prism_v2
hreflang: en-US hreflang: en-US
providers: providers:
- type: edr - type: edr
name: xarray-edr name: xarray-edr
data: s3://power-analysis-ready-datastore/power_901_annual_meteorology_utc.zarr data: s3://mdmf/gdp/PRISM_v2.zarr
format: format:
name: zarr name: zarr
mimetype: application/zip mimetype: application/zip
@@ -343,6 +342,8 @@ resources:
s3: s3:
anon: true anon: true
requester_pays: false requester_pays: false
client_kwargs:
endpoint_url: https://usgs.osn.mghpcc.org/
objects: objects:
type: collection type: collection
+11 -9
View File
@@ -2002,15 +2002,6 @@ def test_get_collection_edr_query(config, api_):
req, 'icoads-sst', None, 'position') req, 'icoads-sst', None, 'position')
assert code == HTTPStatus.NO_CONTENT assert code == HTTPStatus.NO_CONTENT
# S3 EDR
req = mock_request({
'coords': 'POINT(-100 40)',
'parameter-name': 'GWETROOT'
})
rsp_headers, code, response = api_.get_collection_edr_query(
req, 'nasa-power', None, 'position')
assert code == HTTPStatus.OK
# position no coords # position no coords
req = mock_request({ req = mock_request({
'datetime': '2000-01-17' 'datetime': '2000-01-17'
@@ -2041,6 +2032,17 @@ def test_get_collection_edr_query(config, api_):
req, 'icoads-sst', None, 'cube') req, 'icoads-sst', None, 'cube')
assert code == HTTPStatus.BAD_REQUEST assert code == HTTPStatus.BAD_REQUEST
# cube decreasing latitude coords and S3
req = mock_request({
'bbox': '-100,40,-99,45',
'parameter-name': 'tmn',
'datetime': '1994-01-01/1994-12-31',
})
rsp_headers, code, response = api_.get_collection_edr_query(
req, 'usgs-prism', None, 'cube')
assert code == HTTPStatus.OK
def test_validate_bbox(): def test_validate_bbox():
assert validate_bbox('1,2,3,4') == [1, 2, 3, 4] assert validate_bbox('1,2,3,4') == [1, 2, 3, 4]