~ubuntu-branches/ubuntu/vivid/grass/vivid-proposed

« back to all changes in this revision

Viewing changes to gui/wxpython/web_services/cap_interface.py

  • Committer: Package Import Robot
  • Author(s): Bas Couwenberg
  • Date: 2015-02-20 23:12:08 UTC
  • mfrom: (8.2.6 experimental)
  • Revision ID: package-import@ubuntu.com-20150220231208-1u6qvqm84v430b10
Tags: 7.0.0-1~exp1
* New upstream release.
* Update python-ctypes-ternary.patch to use if/else instead of and/or.
* Drop check4dev patch, rely on upstream check.
* Add build dependency on libpq-dev to grass-dev for libpq-fe.h.
* Drop patches applied upstream, refresh remaining patches.
* Update symlinks for images switched from jpg to png.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
"""
 
2
@package web_services.cap_interface
 
3
 
 
4
@brief Provides common interface for GUI web_services.widgets to capabilities data of web services.
 
5
 
 
6
List of classes:
 
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
 
15
 
 
16
(C) 2012 by the GRASS Development Team
 
17
 
 
18
This program is free software under the GNU General Public License
 
19
(>=v2). Read the file COPYING that comes with GRASS for details.
 
20
 
 
21
@author Stepan Turek <stepan.turek seznam.cz> (Mentor: Martin Landa)
 
22
"""
 
23
 
 
24
import os
 
25
import sys
 
26
 
 
27
WMSLibPath = os.path.join(os.getenv("GISBASE"), "etc", "r.in.wms")
 
28
if WMSLibPath not in sys.path:
 
29
    sys.path.append(WMSLibPath)
 
30
 
 
31
from wms_cap_parsers import WMSCapabilitiesTree, \
 
32
                            WMTSCapabilitiesTree, \
 
33
                            OnEarthCapabilitiesTree
 
34
 
 
35
class CapabilitiesBase:
 
36
    def GetLayerByName(self, name):
 
37
        """Find layer by name
 
38
        """
 
39
        for l in self.layers_by_id:
 
40
            if name == l.GetLayerData('name'):
 
41
                return l
 
42
        return None
 
43
 
 
44
    def GetRootLayer(self):
 
45
        """Get children layers
 
46
        """
 
47
        if self.layers_by_id:
 
48
            return self.layers_by_id[0]
 
49
        else:
 
50
            return None
 
51
 
 
52
class LayerBase:
 
53
    def GetId(self):
 
54
        """Get layer id
 
55
        """
 
56
        return self.id
 
57
 
 
58
    def GetChildren(self):
 
59
        """Get children layers
 
60
        """
 
61
        return self.child_layers
 
62
 
 
63
    def GetLayerNode(self):
 
64
        """Get layer node
 
65
        """
 
66
        return self.layer_node
 
67
 
 
68
    def AddChildLayer(self, layer):
 
69
        """Add child layer
 
70
        """
 
71
        self.child_layers.append(layer)
 
72
 
 
73
class WMSCapabilities(CapabilitiesBase, WMSCapabilitiesTree):
 
74
    def __init__(self, cap_file, force_version = None):
 
75
        """Create common interface for web_services.widgets to WMS
 
76
        capabilities data
 
77
        """
 
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)
 
81
 
 
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"))
 
84
 
 
85
        self.layers_by_id = {}
 
86
        self._initializeLayerTree(self.root_layer)
 
87
 
 
88
    def _initializeLayerTree(self, parent_layer, id = 0):
 
89
        """Build tree, which represents layers
 
90
        """
 
91
        if id == 0:
 
92
            parent_layer = WMSLayer(parent_layer, id, self)
 
93
            self.layers_by_id[id] = parent_layer
 
94
            id += 1
 
95
        
 
96
        layer_nodes = parent_layer.GetLayerNode().findall((self.xml_ns.Ns("Layer")))
 
97
        
 
98
        for l in layer_nodes:
 
99
            layer = WMSLayer(l, id, self)
 
100
            parent_layer.AddChildLayer(layer)
 
101
            self.layers_by_id[id] = layer
 
102
            id += 1
 
103
            id = self._initializeLayerTree(layer, id)
 
104
        
 
105
        return id
 
106
 
 
107
    def GetFormats(self):
 
108
        """Get supported formats
 
109
        """      
 
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"))
 
113
 
 
114
        formats = []
 
115
        for node in format_nodes:
 
116
            formats.append(node.text)
 
117
 
 
118
        return formats
 
119
 
 
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
 
124
        """
 
125
        self.id = id
 
126
        self.cap = cap
 
127
        self.child_layers = []
 
128
        self.layer_node = layer_node
 
129
        self.xml_ns = self.cap.getxmlnshandler()
 
130
 
 
131
    def GetLayerData(self, param):
 
132
        """Get layer data"""
 
133
        title = self.xml_ns.Ns("Title")
 
134
        name = self.xml_ns.Ns("Name")
 
135
 
 
136
        if param == 'title':
 
137
            title_node = self.layer_node.find(title)
 
138
            if title_node is not None:
 
139
                return title_node.text 
 
140
            else:
 
141
                return None
 
142
 
 
143
        if param == 'name':
 
144
            name_node = self.layer_node.find(name)
 
145
            if name_node is not None:
 
146
                return name_node.text 
 
147
            else:
 
148
                return None
 
149
 
 
150
        if param == 'format':
 
151
            return self.cap.GetFormats()
 
152
 
 
153
        if param == 'styles':
 
154
            styles = []
 
155
            style = self.xml_ns.Ns("Style")
 
156
            for style_node in self.layer_node.findall(style):
 
157
                style_name = '' 
 
158
                style_title = ''
 
159
 
 
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
 
164
 
 
165
                styles.append({'title' : style_title, 
 
166
                               'name' : style_name,
 
167
                               'isDefault' : False})
 
168
            return styles
 
169
 
 
170
        if param == 'srs':
 
171
            projs_nodes = self.layer_node.findall(self.xml_ns.Ns(self.cap.getprojtag()))
 
172
 
 
173
            projs = []
 
174
            if projs_nodes is None:
 
175
                return projs
 
176
            for p in projs_nodes:
 
177
                projs.append(p.text.strip())
 
178
            return projs
 
179
 
 
180
    def IsRequestable(self):
 
181
        """Is it possible to use the layer for WMS GetMap request?
 
182
        """
 
183
        name = self.xml_ns.Ns("Name")
 
184
        name_node = self.layer_node.find(name)
 
185
 
 
186
        if name_node is not None:
 
187
            return True
 
188
        else:
 
189
            return False
 
190
 
 
191
class WMTSCapabilities(CapabilitiesBase, WMTSCapabilitiesTree):
 
192
    def __init__(self, cap_file):
 
193
        """Create common interface for web_services.widgets to WMTS
 
194
        capabilities data
 
195
        """
 
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)
 
199
 
 
200
        contents = self._find(self.getroot(), 'Contents', self.xml_ns.NsWmts)
 
201
        layers = self._findall(contents, 'Layer', self.xml_ns.NsWmts)
 
202
 
 
203
        self.layers_by_id = {}
 
204
        
 
205
        id = 0
 
206
        root_layer = WMTSLayer(None, id, self)
 
207
        self.layers_by_id[id] = root_layer
 
208
 
 
209
        for layer_node in layers:
 
210
            id += 1
 
211
            self.layers_by_id[id] = WMTSLayer(layer_node, id, self)
 
212
            root_layer.child_layers.append(self.layers_by_id[id])
 
213
    
 
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
 
218
        """
 
219
        self.id = id
 
220
        self.cap = cap
 
221
        self.child_layers = []
 
222
        self.layer_node = layer_node
 
223
        self.xml_ns = self.cap.getxmlnshandler()
 
224
        self.projs = self._getProjs()
 
225
 
 
226
    def GetLayerData(self, param):
 
227
        """Get layer data
 
228
        """
 
229
        title = self.xml_ns.NsOws("Title")
 
230
        name = self.xml_ns.NsOws("Identifier")
 
231
 
 
232
        if self.layer_node is None and param in ['title', 'name']:
 
233
            return None
 
234
        elif self.layer_node is None:
 
235
            return []
 
236
 
 
237
        if param == 'title':
 
238
            title_node = self.layer_node.find(title)
 
239
            if title_node is not None:
 
240
                return title_node.text 
 
241
            else:
 
242
                return None
 
243
 
 
244
        if param == 'name':
 
245
            name_node = self.layer_node.find(name)
 
246
            if name_node is not None:
 
247
                return name_node.text 
 
248
            else:
 
249
                return None
 
250
 
 
251
        if param == 'styles':
 
252
            styles = []
 
253
            for style_node in self.layer_node.findall(self.xml_ns.NsWmts("Style")):
 
254
 
 
255
                style_name = '' 
 
256
                style_title = ''
 
257
 
 
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
 
262
 
 
263
                is_def = False
 
264
                if 'isDefault' in style_node.attrib and\
 
265
                    style_node.attrib['isDefault'] == 'true':
 
266
                    is_def = True
 
267
 
 
268
                styles.append({'title' : style_title, 
 
269
                               'name' : style_name,
 
270
                               'isDefault' : is_def})
 
271
            
 
272
            return styles
 
273
 
 
274
        if param == 'format':
 
275
            formats = []
 
276
            for frmt in self.layer_node.findall(self.xml_ns.NsWmts('Format')):
 
277
                formats.append(frmt.text.strip())
 
278
            return formats
 
279
 
 
280
        if param == 'srs':
 
281
            return self.projs
 
282
 
 
283
    def _getProjs(self):
 
284
        """Get layer projections
 
285
        """
 
286
        layer_projs = []
 
287
        if self.layer_node is None:
 
288
            return layer_projs
 
289
 
 
290
        mat_set_links = self.layer_node.findall(self.xml_ns.NsWmts('TileMatrixSetLink'))
 
291
 
 
292
        contents = self.cap.getroot().find(self.xml_ns.NsWmts('Contents'))
 
293
        tileMatrixSets = contents.findall(self.xml_ns.NsWmts('TileMatrixSet'))
 
294
 
 
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:
 
298
                continue
 
299
 
 
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:
 
303
                    continue
 
304
                mat_set_srs = mat_set.find(self.xml_ns.NsOws('SupportedCRS')).text.strip()
 
305
                layer_projs.append(mat_set_srs)
 
306
        return layer_projs
 
307
 
 
308
    def IsRequestable(self):
 
309
        """Is it possible to use the layer for WMTS request?
 
310
        """
 
311
        if self.layer_node is None:
 
312
            return False
 
313
        else:
 
314
            return True
 
315
 
 
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
 
320
        capabilities data)
 
321
        """
 
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)
 
325
 
 
326
        self.layers_by_id = {}
 
327
        self._initializeLayerTree(self.getroot())
 
328
        
 
329
    def _initializeLayerTree(self, parent_layer, id = 0):
 
330
        """Build tree, which represents layers
 
331
        """
 
332
        if id == 0:
 
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
 
338
            id += 1
 
339
        else:
 
340
            layer_nodes = parent_layer.layer_node.findall('TiledGroup')
 
341
            layer_nodes += parent_layer.layer_node.findall('TiledGroups')
 
342
 
 
343
        for layer_node in layer_nodes:
 
344
            layer = OnEarthLayer(layer_node, parent_layer, id, self)
 
345
            self.layers_by_id[id] = layer
 
346
            id += 1
 
347
            parent_layer.child_layers.append(layer)
 
348
            if layer_node.tag == 'TiledGroups':
 
349
               id = self._initializeLayerTree(layer, id)
 
350
 
 
351
        return id
 
352
 
 
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)
 
358
        """
 
359
        self.id = id
 
360
        self.cap = cap
 
361
        self.layer_node = layer_node
 
362
        self.child_layers = []
 
363
        self.parent_layer = parent_layer
 
364
 
 
365
    def IsRequestable(self):
 
366
        """Is it possible to use the layer for NASA OnEarth GetMap request?
 
367
        """
 
368
        if self.layer_node is None or \
 
369
           self.layer_node.tag == 'TiledGroups':
 
370
           return False
 
371
        else:
 
372
            return True
 
373
 
 
374
    def GetLayerData(self, param):
 
375
        """Get layer data
 
376
        """
 
377
        if self.layer_node is None and param in ['title', 'name']:
 
378
            return None
 
379
        elif self.layer_node is None:
 
380
            return []
 
381
 
 
382
        if param == 'title':
 
383
            title_node = self.layer_node.find("Title")
 
384
            if title_node is not None:
 
385
                return title_node.text 
 
386
            else:
 
387
                return None
 
388
 
 
389
        if param == 'name':
 
390
            name_node = self.layer_node.find("Name")
 
391
            if name_node is not None:
 
392
                return name_node.text 
 
393
            else:
 
394
                return None
 
395
 
 
396
        if param == 'styles':
 
397
            return []
 
398
 
 
399
        if param == 'format':
 
400
            return []
 
401
 
 
402
        if param == 'srs':
 
403
            return []