77# Colin Blackburn <colb@bgs.ac.uk>
88# Ricardo Garcia Silva <ricardo.garcia.silva@geobeyond.it>
99#
10- # Copyright (c) 2025 Tom Kralidis
10+ # Copyright (c) 2026 Tom Kralidis
1111# Copyright (c) 2025 Francesco Bartoli
1212# Copyright (c) 2022 John A Stevenson and Colin Blackburn
1313# Copyright (c) 2023 Ricardo Garcia Silva
@@ -588,6 +588,7 @@ def get_exception(self, status: int, headers: dict, format_: str | None,
588588 """
589589
590590 exception_info = sys .exc_info ()
591+
591592 LOGGER .error (
592593 description ,
593594 exc_info = exception_info if exception_info [0 ] is not None else None
@@ -709,22 +710,22 @@ def landing_page(api: API,
709710 'title' : l10n .translate ('Collections' , request .locale ),
710711 'href' : api .get_collections_url ()
711712 }, {
712- 'rel' : 'http://www.opengis.net/def/rel/ogc/1.0 /processes' ,
713+ 'rel' : f' { OGC_RELTYPES_BASE } /processes' ,
713714 'type' : FORMAT_TYPES [F_JSON ],
714715 'title' : l10n .translate ('Processes' , request .locale ),
715716 'href' : f"{ api .base_url } /processes"
716717 }, {
717- 'rel' : 'http://www.opengis.net/def/rel/ogc/1.0 /job-list' ,
718+ 'rel' : f' { OGC_RELTYPES_BASE } /job-list' ,
718719 'type' : FORMAT_TYPES [F_JSON ],
719720 'title' : l10n .translate ('Jobs' , request .locale ),
720721 'href' : f"{ api .base_url } /jobs"
721722 }, {
722- 'rel' : 'http://www.opengis.net/def/rel/ogc/1.0 /tiling-schemes' ,
723+ 'rel' : f' { OGC_RELTYPES_BASE } /tiling-schemes' ,
723724 'type' : FORMAT_TYPES [F_JSON ],
724725 'title' : l10n .translate ('The list of supported tiling schemes as JSON' , request .locale ), # noqa
725726 'href' : f"{ api .base_url } /TileMatrixSets?f=json"
726727 }, {
727- 'rel' : 'http://www.opengis.net/def/rel/ogc/1.0 /tiling-schemes' ,
728+ 'rel' : f' { OGC_RELTYPES_BASE } /tiling-schemes' ,
728729 'type' : FORMAT_TYPES [F_HTML ],
729730 'title' : l10n .translate ('The list of supported tiling schemes as HTML' , request .locale ), # noqa
730731 'href' : f"{ api .base_url } /TileMatrixSets?f=html"
@@ -897,7 +898,10 @@ def describe_collections(api: API, request: APIRequest,
897898 'links' : []
898899 }
899900
900- bbox = v ['extents' ]['spatial' ]['bbox' ]
901+ extents = deepcopy (v ['extents' ])
902+
903+ bbox = extents ['spatial' ]['bbox' ]
904+ LOGGER .debug ('Setting spatial extents from configuration' )
901905 # The output should be an array of bbox, so if the user only
902906 # provided a single bbox, wrap it in a array.
903907 if not isinstance (bbox [0 ], list ):
@@ -907,12 +911,13 @@ def describe_collections(api: API, request: APIRequest,
907911 'bbox' : bbox
908912 }
909913 }
910- if 'crs' in v [ ' extents' ] ['spatial' ]:
914+ if 'crs' in extents ['spatial' ]:
911915 collection ['extent' ]['spatial' ]['crs' ] = \
912- v [ ' extents' ] ['spatial' ]['crs' ]
916+ extents ['spatial' ]['crs' ]
913917
914- t_ext = v . get ( ' extents' , {}) .get ('temporal' , {})
918+ t_ext = extents .get ('temporal' , {})
915919 if t_ext :
920+ LOGGER .debug ('Setting temporal extents from configuration' )
916921 begins = dategetter ('begin' , t_ext )
917922 ends = dategetter ('end' , t_ext )
918923 collection ['extent' ]['temporal' ] = {
@@ -921,6 +926,24 @@ def describe_collections(api: API, request: APIRequest,
921926 if 'trs' in t_ext :
922927 collection ['extent' ]['temporal' ]['trs' ] = t_ext ['trs' ]
923928
929+ _ = extents .pop ('spatial' , None )
930+ _ = extents .pop ('temporal' , None )
931+
932+ for ek , ev in extents .items ():
933+ LOGGER .debug (f'Adding extent { ek } ' )
934+ collection ['extent' ][ek ] = {
935+ 'definition' : ev ['url' ],
936+ 'interval' : [ev ['range' ]]
937+ }
938+ if 'units' in ev :
939+ collection ['extent' ][ek ]['unit' ] = ev ['units' ]
940+
941+ if 'values' in ev :
942+ collection ['extent' ][ek ]['grid' ] = {
943+ 'cellsCount' : len (ev ['values' ]),
944+ 'coordinates' : ev ['values' ]
945+ }
946+
924947 LOGGER .debug ('Processing configured collection links' )
925948 for link in l10n .translate (v .get ('links' , []), request .locale ):
926949 lnk = {
@@ -990,13 +1013,13 @@ def describe_collections(api: API, request: APIRequest,
9901013 if collection_data_type == 'record' :
9911014 collection ['links' ].append ({
9921015 'type' : FORMAT_TYPES [F_JSON ],
993- 'rel' : 'http://www.opengis.net/def/rel/ogc/1.0 /ogc-catalog' ,
1016+ 'rel' : f' { OGC_RELTYPES_BASE } /ogc-catalog' ,
9941017 'title' : l10n .translate ('Record catalogue as JSON' , request .locale ), # noqa
9951018 'href' : f'{ api .get_collections_url ()} /{ k } ?f={ F_JSON } '
9961019 })
9971020 collection ['links' ].append ({
9981021 'type' : FORMAT_TYPES [F_HTML ],
999- 'rel' : 'http://www.opengis.net/def/rel/ogc/1.0 /ogc-catalog' ,
1022+ 'rel' : f' { OGC_RELTYPES_BASE } /ogc-catalog' ,
10001023 'title' : l10n .translate ('Record catalogue as HTML' , request .locale ), # noqa
10011024 'href' : f'{ api .get_collections_url ()} /{ k } ?f={ F_HTML } '
10021025 })
@@ -1021,13 +1044,13 @@ def describe_collections(api: API, request: APIRequest,
10211044 LOGGER .debug ('Adding feature/record based links' )
10221045 collection ['links' ].append ({
10231046 'type' : 'application/schema+json' ,
1024- 'rel' : 'http://www.opengis.net/def/rel/ogc/1.0 /queryables' ,
1047+ 'rel' : f' { OGC_RELTYPES_BASE } /queryables' ,
10251048 'title' : l10n .translate ('Queryables for this collection as JSON' , request .locale ), # noqa
10261049 'href' : f'{ api .get_collections_url ()} /{ k } /queryables?f={ F_JSON } ' # noqa
10271050 })
10281051 collection ['links' ].append ({
10291052 'type' : FORMAT_TYPES [F_HTML ],
1030- 'rel' : 'http://www.opengis.net/def/rel/ogc/1.0 /queryables' ,
1053+ 'rel' : f' { OGC_RELTYPES_BASE } /queryables' ,
10311054 'title' : l10n .translate ('Queryables for this collection as HTML' , request .locale ), # noqa
10321055 'href' : f'{ api .get_collections_url ()} /{ k } /queryables?f={ F_HTML } ' # noqa
10331056 })
@@ -1135,19 +1158,20 @@ def describe_collections(api: API, request: APIRequest,
11351158 LOGGER .debug ('Adding tile links' )
11361159 collection ['links' ].append ({
11371160 'type' : FORMAT_TYPES [F_JSON ],
1138- 'rel' : f'http://www.opengis.net/def/rel/ogc/1.0/ tilesets-{ p .tile_type } ' , # noqa
1161+ 'rel' : f'{ OGC_RELTYPES_BASE } / tilesets-{ p .tile_type } ' ,
11391162 'title' : l10n .translate ('Tiles as JSON' , request .locale ),
1140- 'href' : f'{ api .get_collections_url ()} /{ k } /tiles?f={ F_JSON } ' # noqa
1163+ 'href' : f'{ api .get_collections_url ()} /{ k } /tiles?f={ F_JSON } '
11411164 })
11421165 collection ['links' ].append ({
11431166 'type' : FORMAT_TYPES [F_HTML ],
1144- 'rel' : f'http://www.opengis.net/def/rel/ogc/1.0/ tilesets-{ p .tile_type } ' , # noqa
1167+ 'rel' : f'{ OGC_RELTYPES_BASE } / tilesets-{ p .tile_type } ' ,
11451168 'title' : l10n .translate ('Tiles as HTML' , request .locale ),
1146- 'href' : f'{ api .get_collections_url ()} /{ k } /tiles?f={ F_HTML } ' # noqa
1169+ 'href' : f'{ api .get_collections_url ()} /{ k } /tiles?f={ F_HTML } '
11471170 })
11481171
11491172 try :
11501173 map_ = get_provider_by_type (v ['providers' ], 'map' )
1174+ p = load_plugin ('provider' , map_ )
11511175 except ProviderTypeError :
11521176 map_ = None
11531177
@@ -1158,15 +1182,36 @@ def describe_collections(api: API, request: APIRequest,
11581182 map_format = map_ ['format' ]['name' ]
11591183
11601184 title_ = l10n .translate ('Map as' , request .locale )
1161- title_ = f" { title_ } { map_format } "
1185+ title_ = f' { title_ } { map_format } '
11621186
11631187 collection ['links' ].append ({
11641188 'type' : map_mimetype ,
1165- 'rel' : 'http://www.opengis.net/def/rel/ogc/1.0 /map' ,
1189+ 'rel' : f' { OGC_RELTYPES_BASE } /map' ,
11661190 'title' : title_ ,
1167- 'href' : f" { api .get_collections_url ()} /{ k } /map?f={ map_format } " # noqa
1191+ 'href' : f' { api .get_collections_url ()} /{ k } /map?f={ map_format } '
11681192 })
11691193
1194+ if p ._fields :
1195+ schema_reltype = f'{ OGC_RELTYPES_BASE } /schema' ,
1196+ schema_links = [s for s in collection ['links' ] if
1197+ schema_reltype in s ]
1198+
1199+ if not schema_links :
1200+ title_ = l10n .translate ('Schema of collection in JSON' , request .locale ) # noqa
1201+ collection ['links' ].append ({
1202+ 'type' : 'application/schema+json' ,
1203+ 'rel' : f'{ OGC_RELTYPES_BASE } /schema' ,
1204+ 'title' : title_ ,
1205+ 'href' : f'{ api .get_collections_url ()} /{ k } /schema?f=json' # noqa
1206+ })
1207+ title_ = l10n .translate ('Schema of collection in HTML' , request .locale ) # noqa
1208+ collection ['links' ].append ({
1209+ 'type' : 'text/html' ,
1210+ 'rel' : f'{ OGC_RELTYPES_BASE } /schema' ,
1211+ 'title' : title_ ,
1212+ 'href' : f'{ api .get_collections_url ()} /{ k } /schema?f=html' # noqa
1213+ })
1214+
11701215 try :
11711216 edr = get_provider_by_type (v ['providers' ], 'edr' )
11721217 p = load_plugin ('provider' , edr )
@@ -1217,6 +1262,10 @@ def describe_collections(api: API, request: APIRequest,
12171262 }
12181263 }
12191264 }
1265+
1266+ if request .format is not None and request .format == 'json' :
1267+ data_query ['link' ]['type' ] = 'application/vnd.cov+json'
1268+
12201269 collection ['data_queries' ][qt ] = data_query
12211270
12221271 title1 = l10n .translate ('query for this collection as JSON' , request .locale ) # noqa
@@ -1334,9 +1383,14 @@ def get_collection_schema(api: API, request: Union[APIRequest, Any],
13341383 p = load_plugin ('provider' , get_provider_by_type (
13351384 api .config ['resources' ][dataset ]['providers' ], 'coverage' )) # noqa
13361385 except ProviderTypeError :
1337- LOGGER .debug ('Loading record provider' )
1338- p = load_plugin ('provider' , get_provider_by_type (
1339- api .config ['resources' ][dataset ]['providers' ], 'record' ))
1386+ try :
1387+ LOGGER .debug ('Loading record provider' )
1388+ p = load_plugin ('provider' , get_provider_by_type (
1389+ api .config ['resources' ][dataset ]['providers' ], 'record' ))
1390+ except ProviderTypeError :
1391+ LOGGER .debug ('Loading edr provider' )
1392+ p = load_plugin ('provider' , get_provider_by_type (
1393+ api .config ['resources' ][dataset ]['providers' ], 'edr' ))
13401394 except ProviderGenericError as err :
13411395 LOGGER .error (err )
13421396 return api .get_exception (
0 commit comments