diff --git a/docs/source/data-publishing/ogcapi-coverages.rst b/docs/source/data-publishing/ogcapi-coverages.rst index fbbe6dd..6d4f588 100644 --- a/docs/source/data-publishing/ogcapi-coverages.rst +++ b/docs/source/data-publishing/ogcapi-coverages.rst @@ -100,6 +100,10 @@ Data access examples * http://localhost:5000/collections/foo/coverage?properties=1,3 * coverage access with subsetting * http://localhost:5000/collections/foo/coverage?subset=lat(10,20)&subset=long(10,20) +* coverage with bbox + * http://localhost:5000/collections/foo/coverage?bbox=10,10,20,20 +* coverage with bbox and bbox CRS + * http://localhost:5000/collections/foo/coverage?bbox=-8794239.772668611,5311971.846945471,-8348961.809495518,5621521.486192066&bbox=crs=3857 .. note:: ``.../coverage`` queries which return an alternative representation to CoverageJSON (which prompt a download) diff --git a/pygeoapi/api.py b/pygeoapi/api.py index 00f1160..834ddf9 100644 --- a/pygeoapi/api.py +++ b/pygeoapi/api.py @@ -2171,6 +2171,10 @@ class API: query_args['bbox'] = bbox + LOGGER.debug('Processing bbox-crs parameter') + + query_args['bbox_crs'] = request.params.get('bbox-crs') + LOGGER.debug('Processing datetime parameter') datetime_ = request.params.get('datetime', None) diff --git a/pygeoapi/openapi.py b/pygeoapi/openapi.py index f9d4b3e..0f5c932 100644 --- a/pygeoapi/openapi.py +++ b/pygeoapi/openapi.py @@ -334,6 +334,18 @@ def get_oas_30(cfg): 'default': False } }, + 'bbox-crs': { + 'name': 'bbox-crs', + 'in': 'query', + 'description': 'Indicates the EPSG for the given bbox coordinates.', # noqa + 'required': False, + 'style': 'form', + 'explode': False, + 'schema': { + 'type': 'integer', + 'default': 4326 + } + }, 'offset': { 'name': 'offset', 'in': 'query', @@ -677,7 +689,9 @@ def get_oas_30(cfg): 'operationId': 'get{}Coverage'.format(name.capitalize()), 'parameters': [ items_f, - items_l + items_l, + {'$ref': '{}#/components/parameters/bbox'.format(OPENAPI_YAML['oapif'])}, # noqa + {'$ref': '#/components/parameters/bbox-crs'} ], 'responses': { '200': {'$ref': '{}#/components/responses/Features'.format(OPENAPI_YAML['oapif'])}, # noqa diff --git a/pygeoapi/provider/rasterio_.py b/pygeoapi/provider/rasterio_.py index f12b7cd..9c12b96 100644 --- a/pygeoapi/provider/rasterio_.py +++ b/pygeoapi/provider/rasterio_.py @@ -162,8 +162,8 @@ class RasterioProvider(BaseProvider): return rangetype - def query(self, properties=[], subsets={}, bbox=[], datetime_=None, - format_='json', **kwargs): + def query(self, properties=[], subsets={}, bbox=None, bbox_crs=4326, + datetime_=None, format_='json', **kwargs): """ Extract data from collection collection :param properties: list of bands @@ -183,6 +183,9 @@ class RasterioProvider(BaseProvider): } shapes = [] + if not bbox: + bbox = [] + if all([not bands, not subsets, not bbox, format_ != 'json']): LOGGER.debug('No parameters specified, returning native data') return read_data(self.data) @@ -197,7 +200,7 @@ class RasterioProvider(BaseProvider): if len(bbox) > 0: minx, miny, maxx, maxy = bbox - crs_src = CRS.from_epsg(4326) + crs_src = CRS.from_epsg(bbox_crs) if 'crs' in self.options: crs_dest = CRS.from_string(self.options['crs']) diff --git a/pygeoapi/provider/xarray_.py b/pygeoapi/provider/xarray_.py index e80a353..8c08d0e 100644 --- a/pygeoapi/provider/xarray_.py +++ b/pygeoapi/provider/xarray_.py @@ -183,14 +183,15 @@ class XarrayProvider(BaseProvider): return rangetype - def query(self, properties=[], subsets={}, bbox=[], datetime_=None, - format_='json', **kwargs): + def query(self, properties=[], subsets={}, bbox=[], bbox_crs=4326, + datetime_=None, format_='json', **kwargs): """ Extract data from collection collection :param properties: list of data variables to return (all if blank) :param subsets: dict of subset names with lists of ranges :param bbox: bounding box [minx,miny,maxx,maxy] + :param bbox_crs: CRS of bounding box :param datetime_: temporal (datestamp or extent) :param format_: data format of output @@ -238,6 +239,8 @@ class XarrayProvider(BaseProvider): query_params[self._coverage_properties['y_axis_label']] = \ slice(bbox[1], bbox[3]) + LOGGER.debug('bbox_crs is not currently handled') + if datetime_ is not None: if self._coverage_properties['time_axis_label'] in subsets: msg = 'datetime and temporal subsetting are exclusive'