Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add WMTS dimensions parsing #904

Merged
merged 1 commit into from
Feb 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 67 additions & 0 deletions owslib/wmts.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@
_STYLE_TAG = _WMTS_NS + 'Style'
_STYLE_LEGEND_URL = _WMTS_NS + 'LegendURL'

# Table 9, page 22-23, Parts of Dimensions data structure
_DIMENSION_TAG = _WMTS_NS + 'Dimension'
_UOM_TAG = _OWS_NS + 'UOM'
_DIMENSION_UNIT_SYMBOL_TAG = _WMTS_NS + 'UnitSymbol'
_DIMENSION_DEFAULT_TAG = _WMTS_NS + 'Default'
_DIMENSION_CURRENT_TAG = _WMTS_NS + 'Current'
_DIMENSION_VALUE_TAG = _WMTS_NS + 'Value'

_THEME_TAG = _WMTS_NS + 'Theme'
_THEMES_TAG = _WMTS_NS + 'Themes'
_TILE_HEIGHT_TAG = _WMTS_NS + 'TileHeight'
Expand Down Expand Up @@ -793,6 +801,65 @@ def __init__(self, elem, parent=None, index=0, parse_remote_metadata=False):
_KEYWORDS_TAG + '/' + _KEYWORD_TAG)]
self.infoformats = [f.text for f in elem.findall(_INFO_FORMAT_TAG)]

self.dimensions = {}
for dim in elem.findall(_DIMENSION_TAG):
dimension = {}

identifier = dim.find(_IDENTIFIER_TAG)
if identifier is None:
# mandatory parameter
raise ValueError('%s missing identifier' % (dim,))
if identifier.text in self.dimensions:
# domain identifier SHALL be unique
warnings.warn('%s identifier duplicated, taking first occurence' % (dim,))
continue

values = [f.text for f in dim.findall(_DIMENSION_VALUE_TAG)]
if len(values) == 0:
raise ValueError(
'%s list of values can not be empty' % (dim,)
)
dimension['values'] = values

title = dim.find(_TITLE_TAG)
if title is not None:
dimension['title'] = title.text

abstract = dim.find(_ABSTRACT_TAG)
if abstract is not None:
dimension['abstract'] = abstract.text

keywords = [
f.text for f in dim.findall(_KEYWORDS_TAG + '/' + _KEYWORD_TAG)
]
if keywords:
dimension['keywords'] = keywords

uom = dim.find(_UOM_TAG)
if uom is not None:
dimension['UOM'] = uom.text

unit_symbol = dim.find(_DIMENSION_UNIT_SYMBOL_TAG)
if unit_symbol is not None:
dimension['unit_symbol'] = unit_symbol.text

default_value = dim.find(_DIMENSION_DEFAULT_TAG)
if default_value in ['default', 'current', '', None]:
# mandatory parameter
raise ValueError(
'%s default value must not be empty or \'default\' or \'current\''
% (dim,)
)
dimension['default'] = default_value.text

current = dim.find(_DIMENSION_CURRENT_TAG)
if current and current.text == 'true':
dimension['current'] = True
else:
dimension['current'] = False

self.dimensions[identifier.text] = dimension

self.layers = []
for child in elem.findall(_LAYER_TAG):
self.layers.append(ContentMetadata(child, self))
Expand Down
14 changes: 14 additions & 0 deletions tests/test_wmts.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ def test_wmts():
# Available Layers:
assert len(wmts.contents.keys()) > 0
assert sorted(list(wmts.contents))[0] == 'AIRS_CO_Total_Column_Day'
# at least one of the layers have a time dimension parsed
assert wmts_dimensions_time_domain_exists(wmts.contents), "No layer has time dimension parsed"
# Fetch a tile (using some defaults):
tile = wmts.gettile(layer='MODIS_Terra_CorrectedReflectance_TrueColor',
tilematrixset='EPSG4326_250m', tilematrix='0',
Expand Down Expand Up @@ -115,3 +117,15 @@ def test_wmts_rest_only():
wmts = WebMapTileService(SERVICE_URL_REST)
tile = wmts.gettile(layer="bmaporthofoto30cm", tilematrix="10", row=357, column=547)
assert tile.info()['Content-Type'] == 'image/jpeg'

def wmts_dimensions_time_domain_exists(input_dict):
# returns True if there is a layer with a 'time' dimension
# parsed and contains a non-empty default value
return any(
hasattr(value, 'dimensions') and
isinstance(getattr(value, 'dimensions'), dict) and
isinstance(value.dimensions['time'], dict) and
'default' in value.dimensions['time'] and
len(value.dimensions['time']['default']) > 0
for value in input_dict.values()
)
Loading