~ubuntu-branches/ubuntu/wily/grass/wily

« back to all changes in this revision

Viewing changes to gui/wxpython/core/layerlist.py

Tags: 7.0.0~rc1+ds1-1~exp1
* New upstream release candidate.
* Repack upstream tarball, remove precompiled Python objects.
* Add upstream metadata.
* Update gbp.conf and Vcs-Git URL to use the experimental branch.
* Update watch file for GRASS 7.0.
* Drop build dependencies for Tcl/Tk, add build dependencies:
  python-numpy, libnetcdf-dev, netcdf-bin, libblas-dev, liblapack-dev
* Update Vcs-Browser URL to use cgit instead of gitweb.
* Update paths to use grass70.
* Add configure options: --with-netcdf, --with-blas, --with-lapack,
  remove --with-tcltk-includes.
* Update patches for GRASS 7.
* Update copyright file, changes:
  - Update copyright years
  - Group files by license
  - Remove unused license sections
* Add patches for various typos.
* Fix desktop file with patch instead of d/rules.
* Use minimal dh rules.
* Bump Standards-Version to 3.9.6, no changes.
* Use dpkg-maintscript-helper to replace directories with symlinks.
  (closes: #776349)
* Update my email to use @debian.org address.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- coding: utf-8 -*-
 
2
"""
 
3
@package core.layerlist
 
4
 
 
5
@brief Non GUI classes for layer management (so far used for class simplelmgr only)
 
6
 
 
7
Classes:
 
8
 - layerlist::LayerList
 
9
 - layerlist::Layer
 
10
 - layerlist::LayerListToRendererConverter
 
11
 
 
12
(C) 2013 by the GRASS Development Team
 
13
 
 
14
This program is free software under the GNU General Public License
 
15
(>=v2). Read the file COPYING that comes with GRASS for details.
 
16
 
 
17
@author Anna Petrasova (kratochanna gmail.com)
 
18
"""
 
19
 
 
20
from grass.script import core as gcore
 
21
 
 
22
 
 
23
class LayerList(object):
 
24
    """Non GUI class managing list of layers.
 
25
 
 
26
    It provides API for handling layers. In the future,
 
27
    a non GUI class (e.g. named LayerTree) which includes this API,
 
28
    should be used for Layer Manager.
 
29
    """
 
30
    def __init__(self):
 
31
        self._list = []
 
32
 
 
33
    def GetSelectedLayers(self, activeOnly=True):
 
34
        """Returns list of selected layers.
 
35
 
 
36
        :param bool activeOnly: return only active layers
 
37
        """
 
38
        layers = []
 
39
        for layer in self._list:
 
40
            if layer.IsSelected():
 
41
                if activeOnly and layer.IsActive():
 
42
                    layers.append(layer)
 
43
                else:
 
44
                    layers.append(layer)
 
45
        return layers
 
46
 
 
47
    def GetSelectedLayer(self, activeOnly=False):
 
48
        """Returns selected layer or None when there is no selected layer.
 
49
 
 
50
        :param bool activeOnly: return only active layers
 
51
        """
 
52
        layers = self.GetSelectedLayers(activeOnly)
 
53
        if layers:
 
54
            return layers[0]
 
55
        return None
 
56
 
 
57
    def GetActiveLayers(self):
 
58
        """Returns list of active layers."""
 
59
        return [layer for layer in self._list if layer.IsActive()]
 
60
 
 
61
    def GetLayersByTypes(self, mapTypes):
 
62
        """Returns layers by types.
 
63
 
 
64
        :param mapTypes: list of types
 
65
        """
 
66
        layers = []
 
67
        for layer in self._list:
 
68
            if layer.mapType in mapTypes:
 
69
                layers.append(layer)
 
70
        return layers
 
71
 
 
72
    def AddNewLayer(self, name, mapType, cmd, active=True, hidden=False,
 
73
                    opacity=1, label=None, pos=0):
 
74
        """Creates new layer and adds it to the list (insert to the first position).
 
75
 
 
76
        :param ltype: layer type (raster, vector, 3d-raster, ...)
 
77
        :param cmd: command (given as a list)
 
78
        :param active: if True layer is active
 
79
        :param hidden: if True layer is hidden
 
80
        :param opacity: layer opacity level (0 - 100)
 
81
        :param name: layer name (set automatically from cmd)
 
82
        :param label: layer label (set automatically from name)
 
83
        :param pos: add layer to position
 
84
        """
 
85
        layer = Layer()
 
86
        layer.hidden = hidden
 
87
        layer.mapType = mapType
 
88
        layer.cmd = cmd
 
89
        layer.active = active
 
90
        layer.opacity = opacity
 
91
        layer.name = name
 
92
        if label:
 
93
            layer.label = label
 
94
 
 
95
        self._list.insert(pos, layer)
 
96
        return layer
 
97
 
 
98
    def AddLayer(self, layer):
 
99
        """Adds a layer to the layer list.
 
100
        """
 
101
        self._list.insert(0, layer)
 
102
 
 
103
    def InsertLayer(self, index, layer):
 
104
        """Adds a layer to the layer list.
 
105
        """
 
106
        self._list.insert(index, layer)
 
107
 
 
108
    def RemoveLayer(self, layer):
 
109
        """Removes layer."""
 
110
        self._list.remove(layer)
 
111
 
 
112
    def GetLayerByData(self, key, value):
 
113
        """Returns layer with specified.
 
114
 
 
115
        .. note::
 
116
            Returns only one layer. This might change.
 
117
 
 
118
        .. warning::
 
119
            Avoid using this method, it might be removed in the future.
 
120
        """
 
121
        raise NotImplementedError()
 
122
 
 
123
    def GetLayerIndex(self, layer):
 
124
        """Get index of layer."""
 
125
        return self._list.index(layer)
 
126
 
 
127
    def MoveLayerUp(self, layer):
 
128
        """Moves layer up (1 step)."""
 
129
        idx = self._list.index(layer)
 
130
        if idx > 0:
 
131
            lr = self._list.pop(idx)
 
132
            self._list.insert(idx - 1, lr)
 
133
 
 
134
    def MoveLayerDown(self, layer):
 
135
        """Moves layer down (1 step)."""
 
136
        idx = self._list.index(layer)
 
137
        if idx < len(self._list) - 1:
 
138
            lr = self._list.pop(idx)
 
139
            self._list.insert(idx + 1, lr)
 
140
 
 
141
    def __iter__(self):
 
142
        for layer in self._list:
 
143
            yield layer
 
144
 
 
145
    def __getitem__(self, index):
 
146
        return self._list[index]
 
147
 
 
148
    def __len__(self):
 
149
        return len(self._list)
 
150
 
 
151
    def __str__(self):
 
152
        text = ''
 
153
        for layer in self._list:
 
154
            text += str(layer.name) + '\n'
 
155
        return text
 
156
 
 
157
 
 
158
class Layer(object):
 
159
    """Object representing layer.
 
160
 
 
161
    Properties of the object are checked during setting.
 
162
    Map types can be extended if needed.
 
163
 
 
164
        >>> layer = Layer()
 
165
        >>> layer.selected = True
 
166
        >>> layer.IsSelected()
 
167
        True
 
168
        >>> layer.opacity = 0.1
 
169
        Traceback (most recent call last):
 
170
        ...
 
171
        ValueError: Opacity must be an integer between 0 and 100, not 0.1.
 
172
        >>> layer.name = 'blablabla'
 
173
        Traceback (most recent call last):
 
174
        ...
 
175
        ValueError: To set layer name, the type of layer must be specified.
 
176
        >>> layer.mapType = 'raster'
 
177
        >>> layer.name = 'blablabla'
 
178
        Traceback (most recent call last):
 
179
        ...
 
180
        ValueError: Map <blablabla> not found.
 
181
    """
 
182
    def __init__(self):
 
183
        self._mapType = None
 
184
        self._name = None
 
185
        self._label = None
 
186
        self._cmd = None
 
187
        self._opacity = 1
 
188
 
 
189
        self._selected = False
 
190
        self._active = True
 
191
        self._hidden = False
 
192
        self._initialized = False
 
193
 
 
194
        self._mapTypes = ['raster', 'vector', 'raster_3d', 'rgb']
 
195
        self._internalTypes = {'raster': 'cell',
 
196
                               'vector': 'vector',
 
197
                               'raster_3d': 'grid3',
 
198
                               'rgb': 'rgb'}
 
199
 
 
200
    def GetName(self):
 
201
        return self._name
 
202
 
 
203
    def SetName(self, name):
 
204
        """Sets name of the layer.
 
205
 
 
206
        It checks the name of the layer by g.findfile
 
207
        (raises ValueError if map does not exist).
 
208
        Therefore map type has to be set first.
 
209
        """
 
210
        if not self.hidden:
 
211
            fullName = name.split('@')
 
212
            if len(fullName) == 1 and self._mapType != 'rgb':  # skip checking rgb maps for now
 
213
                if self._mapType is None:
 
214
                    raise ValueError("To set layer name, the type of layer must be specified.")
 
215
 
 
216
                res = gcore.find_file(name=fullName,
 
217
                                      element=self._internalTypes[self._mapType])
 
218
                if not res['mapset']:
 
219
                    raise ValueError("Map <{name}> not found.".format(name=name))
 
220
                self._name = name + '@' + res['mapset']
 
221
            else:
 
222
                self._name = name
 
223
        self.label = name
 
224
 
 
225
    name = property(fget=GetName, fset=SetName)
 
226
 
 
227
    def GetLabel(self):
 
228
        return self._label
 
229
 
 
230
    def SetLabel(self, label):
 
231
        self._label = label
 
232
 
 
233
    label = property(fget=GetLabel, fset=SetLabel)
 
234
 
 
235
    def GetCmd(self):
 
236
        return self._cmd
 
237
 
 
238
    def SetCmd(self, cmd):
 
239
        self._cmd = cmd
 
240
 
 
241
    cmd = property(fget=GetCmd, fset=SetCmd)
 
242
 
 
243
    def GetMapType(self):
 
244
        return self._mapType
 
245
 
 
246
    def SetMapType(self, mapType):
 
247
        """Sets map type of the layer.
 
248
 
 
249
        :param mapType: can be 'raster', 'vector', 'raster_3d'
 
250
        """
 
251
        if mapType not in self._mapTypes:
 
252
            raise ValueError("Wrong map type used: {mtype}".format(mtype=mapType))
 
253
 
 
254
        self._mapType = mapType
 
255
 
 
256
    mapType = property(fget=GetMapType, fset=SetMapType)
 
257
 
 
258
    def GetOpacity(self):
 
259
        """Returns opacity value.
 
260
 
 
261
        :return: opacity as float between 0 and 1
 
262
        """
 
263
        return self._opacity
 
264
 
 
265
    def SetOpacity(self, opacity):
 
266
        """Sets opacity of the layer.
 
267
 
 
268
        :param float opacity: value between 0 and 1
 
269
        """
 
270
        if not (0 <= opacity <= 1):
 
271
            raise ValueError("Opacity value must be between 0 and 1, not {op}.".format(op=opacity))
 
272
        self._opacity = opacity
 
273
 
 
274
    opacity = property(fget=GetOpacity, fset=SetOpacity)
 
275
 
 
276
    def Select(self, select=True):
 
277
        self._selected = select
 
278
 
 
279
    def IsSelected(self):
 
280
        return self._selected
 
281
 
 
282
    selected = property(fget=IsSelected, fset=Select)
 
283
 
 
284
    def IsActive(self):
 
285
        return self._active
 
286
 
 
287
    def Activate(self, active=True):
 
288
        """Sets if layer is active (checked)."""
 
289
        self._active = active
 
290
 
 
291
    active = property(fget=IsActive, fset=Activate)
 
292
 
 
293
    def IsHidden(self):
 
294
        return self._hidden
 
295
 
 
296
    def Hide(self, hide=True):
 
297
        """Sets if layer is hidden."""
 
298
        self._hidden = hide
 
299
 
 
300
    hidden = property(fget=IsHidden, fset=Hide)
 
301
 
 
302
 
 
303
class LayerListToRendererConverter:
 
304
    """Help class for converting LayerList layers into renderer list (Map)"""
 
305
    def __init__(self, renderer):
 
306
        """
 
307
 
 
308
        :param layerList: instance of LayerList
 
309
        :param renderer: instance of Map
 
310
        """
 
311
        self._renderer = renderer
 
312
 
 
313
    def _getRendererLayer(self, index):
 
314
        """Returns corresponding layer of renderer."""
 
315
        rLayers = self._renderer.GetListOfLayers()
 
316
        index = len(rLayers) - index - 1
 
317
        return rLayers[index]
 
318
 
 
319
    def ConvertAll(self, layerList):
 
320
        """Removes all layers in Map and adds new layers form layerList.
 
321
        It's not meant for continuous update because everything is rerendered.
 
322
        """
 
323
        self._renderer.DeleteAllLayers()
 
324
        for layer in reversed(layerList):
 
325
            self.AddLayer(index=-1, layer=layer)
 
326
 
 
327
    def ChangeLayerOpacity(self, index, layer):
 
328
        """Changes layer opacity in renderer."""
 
329
        rLayer = self._getRendererLayer(index)
 
330
        self._renderer.ChangeLayer(rLayer, opacity=layer.opacity)
 
331
 
 
332
    def ChangeLayerCmd(self, index, layer):
 
333
        """Changes layer cmd in renderer."""
 
334
        rLayer = self._getRendererLayer(index)
 
335
        self._renderer.ChangeLayer(rLayer, command=layer.cmd)
 
336
 
 
337
    def ChangeLayerActive(self, index, layer):
 
338
        """Changes layer active state in renderer."""
 
339
        rLayer = self._getRendererLayer(index)
 
340
        self._renderer.ChangeLayer(rLayer, active=layer.active)
 
341
 
 
342
    def MoveLayerUp(self, index):
 
343
        """Moves layer up in renderer."""
 
344
        rLayers = self._renderer.GetListOfLayers()
 
345
        index = len(rLayers) - index - 1
 
346
        rLayer = rLayers.pop(index)
 
347
        rLayers.insert(index + 1, rLayer)
 
348
        self._renderer.SetLayers(rLayers)
 
349
 
 
350
    def MoveLayerDown(self, index):
 
351
        """Moves layer down in renderer."""
 
352
        rLayers = self._renderer.GetListOfLayers()
 
353
        index = len(rLayers) - index - 1
 
354
        rLayer = rLayers.pop(index)
 
355
        rLayers.insert(index - 1, rLayer)
 
356
        self._renderer.SetLayers(rLayers)
 
357
 
 
358
    def AddLayer(self, index, layer):
 
359
        """Adds layer to renderer (prepends)."""
 
360
        mapType = None
 
361
        if layer.mapType == 'raster':
 
362
            mapType = 'raster'
 
363
        elif layer.mapType == 'vector':
 
364
            mapType = 'vector'
 
365
        elif layer.mapType == 'raster_3d':
 
366
            mapType = '3d-raster'
 
367
        elif layer.mapType == 'rgb':
 
368
            mapType = 'rgb'
 
369
        self._renderer.AddLayer(ltype=mapType, command=layer.cmd,
 
370
                                name=layer.name, active=layer.active,
 
371
                                hidden=False, opacity=layer.opacity,
 
372
                                render=True, pos=-1)
 
373
 
 
374
    def RemoveLayer(self, index):
 
375
        """Removes layer from renderer."""
 
376
        self._renderer.DeleteLayer(self._getRendererLayer(index))