diff --git a/locale/en/LC_MESSAGES/messages.po b/locale/en/LC_MESSAGES/messages.po index 34ad8c485..fab76819a 100644 --- a/locale/en/LC_MESSAGES/messages.po +++ b/locale/en/LC_MESSAGES/messages.po @@ -485,6 +485,18 @@ msgstr "" msgid "Display Tiles of" msgstr "" +#: pygeoapi/templates/collections/collection.html:92 +msgid "Coverages" +msgstr "" + +#: pygeoapi/templates/collections/collection.html:96 +msgid "Display Coverage" +msgstr "" + +#: pygeoapi/templates/collections/collection.html:97 +msgid "Display Coverage of" +msgstr "" + #: pygeoapi/templates/collections/index.html:13 msgid "Type" msgstr "" diff --git a/pygeoapi/api/collection.py b/pygeoapi/api/collection.py index 3b1f24922..2cd8b3ea6 100644 --- a/pygeoapi/api/collection.py +++ b/pygeoapi/api/collection.py @@ -228,13 +228,7 @@ def gen_collection(api, request, dataset: str, 'rel': f'{OGC_RELTYPES_BASE}/schema', 'title': l10n.translate('Schema of collection in HTML', locale_), 'href': f'{api.get_collections_url()}/{dataset}/schema?f={F_HTML}' - }]) - - if is_vector_tile or collection_data_type in ['feature', 'record']: - # TODO: translate - data['itemType'] = collection_data_type - LOGGER.debug('Adding feature/record based links') - data['links'].extend([{ + }, { 'type': 'application/schema+json', 'rel': f'{OGC_RELTYPES_BASE}/queryables', 'title': l10n.translate('Queryables for this collection as JSON', locale_), # noqa @@ -244,7 +238,13 @@ def gen_collection(api, request, dataset: str, 'rel': f'{OGC_RELTYPES_BASE}/queryables', 'title': l10n.translate('Queryables for this collection as HTML', locale_), # noqa 'href': f'{api.get_collections_url()}/{dataset}/queryables?f={F_HTML}' # noqa - }, { + }]) + + if is_vector_tile or collection_data_type in ['feature', 'record']: + # TODO: translate + LOGGER.debug('Adding feature/record based links') + data['itemType'] = collection_data_type + data['links'].extend([{ 'type': 'application/geo+json', 'rel': 'items', 'title': l10n.translate('Items as GeoJSON', locale_), @@ -278,12 +278,17 @@ def gen_collection(api, request, dataset: str, elif collection_data_type == 'coverage': LOGGER.debug('Adding coverage based links') - data['links'].append({ + data['links'].extend([{ 'type': 'application/prs.coverage+json', 'rel': f'{OGC_RELTYPES_BASE}/coverage', 'title': l10n.translate('Coverage data', locale_), 'href': f'{api.get_collections_url()}/{dataset}/coverage?f={F_JSON}' # noqa - }) + }, { + 'type': 'text/html', + 'rel': f'{OGC_RELTYPES_BASE}/coverage', + 'title': l10n.translate('Coverage data', locale_), + 'href': f'{api.get_collections_url()}/{dataset}/coverage?f={F_HTML}' # noqa + }]) if collection_data_format is not None: title_ = l10n.translate('Coverage data as', locale_) title_ = f"{title_} {collection_data_format['name']}" diff --git a/pygeoapi/api/coverages.py b/pygeoapi/api/coverages.py index 67755407d..2564071e8 100644 --- a/pygeoapi/api/coverages.py +++ b/pygeoapi/api/coverages.py @@ -41,14 +41,15 @@ import logging from http import HTTPStatus from typing import Tuple +import urllib from pygeoapi import l10n -from pygeoapi.formats import F_JSON +from pygeoapi.formats import F_JSON, F_COVERAGEJSON, F_HTML from pygeoapi.openapi import get_oas_30_parameters from pygeoapi.plugin import load_plugin from pygeoapi.provider.base import ProviderGenericError, ProviderTypeError from pygeoapi.provider import get_provider_by_type -from pygeoapi.util import filter_dict_by_key_value, to_json +from pygeoapi.util import filter_dict_by_key_value, to_json, render_j2_template from . import ( APIRequest, API, SYSTEM_LOCALE, validate_bbox, validate_datetime, @@ -86,6 +87,8 @@ def get_collection_coverage( # Force response content type and language (en-US only) headers headers = request.get_response_headers(SYSTEM_LOCALE, **api.api_headers) + collections = filter_dict_by_key_value(api.config['resources'], + 'type', 'collection') LOGGER.debug('Loading provider') try: @@ -142,6 +145,10 @@ def get_collection_coverage( query_args['datetime_'] = datetime_ query_args['format_'] = format_ + if request.format == F_HTML: + # Request as JSON to render HTML + query_args['format_'] = F_COVERAGEJSON + properties = request.params.get('properties') if properties: LOGGER.debug('Processing properties parameter') @@ -191,6 +198,39 @@ def get_collection_coverage( headers['Content-Type'] = collection_def['format']['mimetype'] return headers, HTTPStatus.OK, data + elif format_ == F_HTML: # render + tpl_config = api.get_dataset_templates(dataset) + + uri = f'{api.get_collections_url()}/{dataset}/coverage' + serialized_query_params = '' + for k, v in request.params.items(): + if k != 'f': + serialized_query_params += '&' + serialized_query_params += urllib.parse.quote(k, safe='') + serialized_query_params += '=' + serialized_query_params += urllib.parse.quote(str(v), safe=',') + + data['query_path'] = uri + data['dataset_path'] = '/'.join(uri.split('/')[:-1]) + data['collections_path'] = api.get_collections_url() + + data['links'] = [{ + 'rel': 'collection', + 'title': collections[dataset]['title'], + 'href': data['dataset_path'] + }, { + 'type': 'application/vnd.cov+json', + 'rel': request.get_linkrel(F_COVERAGEJSON), + 'title': l10n.translate('This document as CoverageJSON', request.locale), # noqa + 'href': f'{uri}?f={F_COVERAGEJSON}{serialized_query_params}' + }] + + content = render_j2_template(api.tpl_config, tpl_config, + 'collections/coverage/index.html', + data, api.default_locale) + + return headers, HTTPStatus.OK, content + elif format_ == F_JSON: headers['Content-Type'] = 'application/prs.coverage+json' return headers, HTTPStatus.OK, to_json(data, api.pretty_print) diff --git a/pygeoapi/templates/collections/collection.html b/pygeoapi/templates/collections/collection.html index 2b3904dcc..4cfbfca0b 100644 --- a/pygeoapi/templates/collections/collection.html +++ b/pygeoapi/templates/collections/collection.html @@ -74,20 +74,40 @@