Skip to content

Commit 76723f9

Browse files
authored
add WMTS dimensions parsing (#904)
1 parent bdc4033 commit 76723f9

2 files changed

Lines changed: 81 additions & 0 deletions

File tree

owslib/wmts.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,14 @@
7878
_STYLE_TAG = _WMTS_NS + 'Style'
7979
_STYLE_LEGEND_URL = _WMTS_NS + 'LegendURL'
8080

81+
# Table 9, page 22-23, Parts of Dimensions data structure
82+
_DIMENSION_TAG = _WMTS_NS + 'Dimension'
83+
_UOM_TAG = _OWS_NS + 'UOM'
84+
_DIMENSION_UNIT_SYMBOL_TAG = _WMTS_NS + 'UnitSymbol'
85+
_DIMENSION_DEFAULT_TAG = _WMTS_NS + 'Default'
86+
_DIMENSION_CURRENT_TAG = _WMTS_NS + 'Current'
87+
_DIMENSION_VALUE_TAG = _WMTS_NS + 'Value'
88+
8189
_THEME_TAG = _WMTS_NS + 'Theme'
8290
_THEMES_TAG = _WMTS_NS + 'Themes'
8391
_TILE_HEIGHT_TAG = _WMTS_NS + 'TileHeight'
@@ -793,6 +801,65 @@ def __init__(self, elem, parent=None, index=0, parse_remote_metadata=False):
793801
_KEYWORDS_TAG + '/' + _KEYWORD_TAG)]
794802
self.infoformats = [f.text for f in elem.findall(_INFO_FORMAT_TAG)]
795803

804+
self.dimensions = {}
805+
for dim in elem.findall(_DIMENSION_TAG):
806+
dimension = {}
807+
808+
identifier = dim.find(_IDENTIFIER_TAG)
809+
if identifier is None:
810+
# mandatory parameter
811+
raise ValueError('%s missing identifier' % (dim,))
812+
if identifier.text in self.dimensions:
813+
# domain identifier SHALL be unique
814+
warnings.warn('%s identifier duplicated, taking first occurence' % (dim,))
815+
continue
816+
817+
values = [f.text for f in dim.findall(_DIMENSION_VALUE_TAG)]
818+
if len(values) == 0:
819+
raise ValueError(
820+
'%s list of values can not be empty' % (dim,)
821+
)
822+
dimension['values'] = values
823+
824+
title = dim.find(_TITLE_TAG)
825+
if title is not None:
826+
dimension['title'] = title.text
827+
828+
abstract = dim.find(_ABSTRACT_TAG)
829+
if abstract is not None:
830+
dimension['abstract'] = abstract.text
831+
832+
keywords = [
833+
f.text for f in dim.findall(_KEYWORDS_TAG + '/' + _KEYWORD_TAG)
834+
]
835+
if keywords:
836+
dimension['keywords'] = keywords
837+
838+
uom = dim.find(_UOM_TAG)
839+
if uom is not None:
840+
dimension['UOM'] = uom.text
841+
842+
unit_symbol = dim.find(_DIMENSION_UNIT_SYMBOL_TAG)
843+
if unit_symbol is not None:
844+
dimension['unit_symbol'] = unit_symbol.text
845+
846+
default_value = dim.find(_DIMENSION_DEFAULT_TAG)
847+
if default_value in ['default', 'current', '', None]:
848+
# mandatory parameter
849+
raise ValueError(
850+
'%s default value must not be empty or \'default\' or \'current\''
851+
% (dim,)
852+
)
853+
dimension['default'] = default_value.text
854+
855+
current = dim.find(_DIMENSION_CURRENT_TAG)
856+
if current and current.text == 'true':
857+
dimension['current'] = True
858+
else:
859+
dimension['current'] = False
860+
861+
self.dimensions[identifier.text] = dimension
862+
796863
self.layers = []
797864
for child in elem.findall(_LAYER_TAG):
798865
self.layers.append(ContentMetadata(child, self))

tests/test_wmts.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ def test_wmts():
2727
# Available Layers:
2828
assert len(wmts.contents.keys()) > 0
2929
assert sorted(list(wmts.contents))[0] == 'AIRS_CO_Total_Column_Day'
30+
# at least one of the layers have a time dimension parsed
31+
assert wmts_dimensions_time_domain_exists(wmts.contents), "No layer has time dimension parsed"
3032
# Fetch a tile (using some defaults):
3133
tile = wmts.gettile(layer='MODIS_Terra_CorrectedReflectance_TrueColor',
3234
tilematrixset='EPSG4326_250m', tilematrix='0',
@@ -115,3 +117,15 @@ def test_wmts_rest_only():
115117
wmts = WebMapTileService(SERVICE_URL_REST)
116118
tile = wmts.gettile(layer="bmaporthofoto30cm", tilematrix="10", row=357, column=547)
117119
assert tile.info()['Content-Type'] == 'image/jpeg'
120+
121+
def wmts_dimensions_time_domain_exists(input_dict):
122+
# returns True if there is a layer with a 'time' dimension
123+
# parsed and contains a non-empty default value
124+
return any(
125+
hasattr(value, 'dimensions') and
126+
isinstance(getattr(value, 'dimensions'), dict) and
127+
isinstance(value.dimensions['time'], dict) and
128+
'default' in value.dimensions['time'] and
129+
len(value.dimensions['time']['default']) > 0
130+
for value in input_dict.values()
131+
)

0 commit comments

Comments
 (0)