2
@package web_services.cap_interface
4
@brief Provides common interface for GUI web_services.widgets to capabilities data of web services.
7
- cap_interface::CapabilitiesBase
8
- cap_interface::LayerBase
9
- cap_interface::WMSCapabilities
10
- cap_interface::WMSLayer
11
- cap_interface::WMTSCapabilities
12
- cap_interface::WMTSLayer
13
- cap_interface::OnEarthCapabilities
14
- cap_interface::OnEarthLayer
16
(C) 2012 by the GRASS Development Team
18
This program is free software under the GNU General Public License
19
(>=v2). Read the file COPYING that comes with GRASS for details.
21
@author Stepan Turek <stepan.turek seznam.cz> (Mentor: Martin Landa)
27
WMSLibPath = os.path.join(os.getenv("GISBASE"), "etc", "r.in.wms")
28
if WMSLibPath not in sys.path:
29
sys.path.append(WMSLibPath)
31
from wms_cap_parsers import WMSCapabilitiesTree, \
32
WMTSCapabilitiesTree, \
33
OnEarthCapabilitiesTree
35
class CapabilitiesBase:
36
def GetLayerByName(self, name):
39
for l in self.layers_by_id:
40
if name == l.GetLayerData('name'):
44
def GetRootLayer(self):
45
"""Get children layers
48
return self.layers_by_id[0]
58
def GetChildren(self):
59
"""Get children layers
61
return self.child_layers
63
def GetLayerNode(self):
66
return self.layer_node
68
def AddChildLayer(self, layer):
71
self.child_layers.append(layer)
73
class WMSCapabilities(CapabilitiesBase, WMSCapabilitiesTree):
74
def __init__(self, cap_file, force_version = None):
75
"""Create common interface for web_services.widgets to WMS
78
# checks all elements needed for creation of GetMap requests
79
# by r.in.wms/d.wms modules, invalid elements are removed
80
WMSCapabilitiesTree.__init__(self, cap_file, force_version)
82
self.cap_node = self.getroot().find(self.xml_ns.Ns("Capability"))
83
self.root_layer = self.cap_node.find(self.xml_ns.Ns("Layer"))
85
self.layers_by_id = {}
86
self._initializeLayerTree(self.root_layer)
88
def _initializeLayerTree(self, parent_layer, id = 0):
89
"""Build tree, which represents layers
92
parent_layer = WMSLayer(parent_layer, id, self)
93
self.layers_by_id[id] = parent_layer
96
layer_nodes = parent_layer.GetLayerNode().findall((self.xml_ns.Ns("Layer")))
99
layer = WMSLayer(l, id, self)
100
parent_layer.AddChildLayer(layer)
101
self.layers_by_id[id] = layer
103
id = self._initializeLayerTree(layer, id)
107
def GetFormats(self):
108
"""Get supported formats
110
request_node = self.cap_node.find(self.xml_ns.Ns("Request"))
111
get_map_node = request_node.find(self.xml_ns.Ns("GetMap"))
112
format_nodes = get_map_node.findall(self.xml_ns.Ns("Format"))
115
for node in format_nodes:
116
formats.append(node.text)
120
class WMSLayer(LayerBase):
121
def __init__(self, layer_node, id, cap):
122
"""Common interface for web_services.widgets to WMS
123
capabilities <Layer> element
127
self.child_layers = []
128
self.layer_node = layer_node
129
self.xml_ns = self.cap.getxmlnshandler()
131
def GetLayerData(self, param):
133
title = self.xml_ns.Ns("Title")
134
name = self.xml_ns.Ns("Name")
137
title_node = self.layer_node.find(title)
138
if title_node is not None:
139
return title_node.text
144
name_node = self.layer_node.find(name)
145
if name_node is not None:
146
return name_node.text
150
if param == 'format':
151
return self.cap.GetFormats()
153
if param == 'styles':
155
style = self.xml_ns.Ns("Style")
156
for style_node in self.layer_node.findall(style):
160
if style_node.find(title) is not None:
161
style_title = style_node.find(title).text
162
if style_node.find(name) is not None:
163
style_name = style_node.find(name).text
165
styles.append({'title' : style_title,
167
'isDefault' : False})
171
projs_nodes = self.layer_node.findall(self.xml_ns.Ns(self.cap.getprojtag()))
174
if projs_nodes is None:
176
for p in projs_nodes:
177
projs.append(p.text.strip())
180
def IsRequestable(self):
181
"""Is it possible to use the layer for WMS GetMap request?
183
name = self.xml_ns.Ns("Name")
184
name_node = self.layer_node.find(name)
186
if name_node is not None:
191
class WMTSCapabilities(CapabilitiesBase, WMTSCapabilitiesTree):
192
def __init__(self, cap_file):
193
"""Create common interface for web_services.widgets to WMTS
196
# checks all elements needed for creation of GetTile requests
197
# by r.in.wms/d.wms modules, invalid elements are removed
198
WMTSCapabilitiesTree.__init__(self, cap_file)
200
contents = self._find(self.getroot(), 'Contents', self.xml_ns.NsWmts)
201
layers = self._findall(contents, 'Layer', self.xml_ns.NsWmts)
203
self.layers_by_id = {}
206
root_layer = WMTSLayer(None, id, self)
207
self.layers_by_id[id] = root_layer
209
for layer_node in layers:
211
self.layers_by_id[id] = WMTSLayer(layer_node, id, self)
212
root_layer.child_layers.append(self.layers_by_id[id])
214
class WMTSLayer(LayerBase):
215
def __init__(self, layer_node, id, cap):
216
"""Common interface for web_services.widgets to WMTS
217
capabilities <Layer> element
221
self.child_layers = []
222
self.layer_node = layer_node
223
self.xml_ns = self.cap.getxmlnshandler()
224
self.projs = self._getProjs()
226
def GetLayerData(self, param):
229
title = self.xml_ns.NsOws("Title")
230
name = self.xml_ns.NsOws("Identifier")
232
if self.layer_node is None and param in ['title', 'name']:
234
elif self.layer_node is None:
238
title_node = self.layer_node.find(title)
239
if title_node is not None:
240
return title_node.text
245
name_node = self.layer_node.find(name)
246
if name_node is not None:
247
return name_node.text
251
if param == 'styles':
253
for style_node in self.layer_node.findall(self.xml_ns.NsWmts("Style")):
258
if style_node.find(title) is not None:
259
style_title = style_node.find(title).text
260
if style_node.find(name) is not None:
261
style_name = style_node.find(name).text
264
if 'isDefault' in style_node.attrib and\
265
style_node.attrib['isDefault'] == 'true':
268
styles.append({'title' : style_title,
270
'isDefault' : is_def})
274
if param == 'format':
276
for frmt in self.layer_node.findall(self.xml_ns.NsWmts('Format')):
277
formats.append(frmt.text.strip())
284
"""Get layer projections
287
if self.layer_node is None:
290
mat_set_links = self.layer_node.findall(self.xml_ns.NsWmts('TileMatrixSetLink'))
292
contents = self.cap.getroot().find(self.xml_ns.NsWmts('Contents'))
293
tileMatrixSets = contents.findall(self.xml_ns.NsWmts('TileMatrixSet'))
295
for link in mat_set_links:
296
mat_set_link_id = link.find(self.xml_ns.NsWmts('TileMatrixSet')).text
297
if not mat_set_link_id:
300
for mat_set in tileMatrixSets:
301
mat_set_id = mat_set.find(self.xml_ns.NsOws('Identifier')).text
302
if mat_set_id and mat_set_id != mat_set_link_id:
304
mat_set_srs = mat_set.find(self.xml_ns.NsOws('SupportedCRS')).text.strip()
305
layer_projs.append(mat_set_srs)
308
def IsRequestable(self):
309
"""Is it possible to use the layer for WMTS request?
311
if self.layer_node is None:
316
class OnEarthCapabilities(CapabilitiesBase, OnEarthCapabilitiesTree):
317
def __init__(self, cap_file):
318
"""Create Common interface for web_services.widgets to
319
NASA OnEarth tile service data (equivalent to WMS, WMTS
322
# checks all elements needed for creation of GetMap requests
323
# by r.in.wms/d.wms modules, invalid elements are removed
324
OnEarthCapabilitiesTree.__init__(self, cap_file)
326
self.layers_by_id = {}
327
self._initializeLayerTree(self.getroot())
329
def _initializeLayerTree(self, parent_layer, id = 0):
330
"""Build tree, which represents layers
333
tiled_patterns = parent_layer.find('TiledPatterns')
334
layer_nodes = tiled_patterns.findall('TiledGroup')
335
layer_nodes += tiled_patterns.findall('TiledGroups')
336
parent_layer = OnEarthLayer(None, None, id, self)
337
self.layers_by_id[id] = parent_layer
340
layer_nodes = parent_layer.layer_node.findall('TiledGroup')
341
layer_nodes += parent_layer.layer_node.findall('TiledGroups')
343
for layer_node in layer_nodes:
344
layer = OnEarthLayer(layer_node, parent_layer, id, self)
345
self.layers_by_id[id] = layer
347
parent_layer.child_layers.append(layer)
348
if layer_node.tag == 'TiledGroups':
349
id = self._initializeLayerTree(layer, id)
353
class OnEarthLayer(LayerBase):
354
def __init__(self, layer_node, parent_layer, id, cap):
355
"""Common interface for web_services.widgets to NASA Earth
356
capabilities <TiledGroup>\<TiledGroups> element
357
(equivalent to WMS, WMTS <Layer> element)
361
self.layer_node = layer_node
362
self.child_layers = []
363
self.parent_layer = parent_layer
365
def IsRequestable(self):
366
"""Is it possible to use the layer for NASA OnEarth GetMap request?
368
if self.layer_node is None or \
369
self.layer_node.tag == 'TiledGroups':
374
def GetLayerData(self, param):
377
if self.layer_node is None and param in ['title', 'name']:
379
elif self.layer_node is None:
383
title_node = self.layer_node.find("Title")
384
if title_node is not None:
385
return title_node.text
390
name_node = self.layer_node.find("Name")
391
if name_node is not None:
392
return name_node.text
396
if param == 'styles':
399
if param == 'format':