GRASS Programmer's Manual  6.4.4(2014)-r
layertree.py
Go to the documentation of this file.
1 """!
2 @package lmgr.layertree
3 
4 @brief Utility classes for map layer management.
5 
6 Classes:
7  - layertree::LayerTree
8 
9 (C) 2007-2013 by the GRASS Development Team
10 
11 This program is free software under the GNU General Public License
12 (>=v2). Read the file COPYING that comes with GRASS for details.
13 
14 @author Michael Barton (Arizona State University)
15 @author Jachym Cepicky (Mendel University of Agriculture)
16 @author Martin Landa <landa.martin gmail.com>
17 """
18 
19 import sys
20 import wx
21 try:
22  import wx.lib.agw.customtreectrl as CT
23 except ImportError:
24  import wx.lib.customtreectrl as CT
25 import wx.lib.buttons as buttons
26 try:
27  import treemixin
28 except ImportError:
29  from wx.lib.mixins import treemixin
30 
31 from grass.script import core as grass
32 from grass.script import vector as gvector
33 
34 from core import globalvar
35 from gui_core.dialogs import SetOpacityDialog, EVT_APPLY_OPACITY
36 from gui_core.forms import GUI
37 from mapdisp.frame import MapFrame
38 from core.render import Map
39 from modules.histogram import HistogramFrame
40 from core.utils import GetLayerNameFromCmd
41 from wxplot.profile import ProfileFrame
42 from core.debug import Debug
43 from core.settings import UserSettings
44 from core.gcmd import GWarning
45 from gui_core.toolbars import BaseIcons
46 from icons.icon import MetaIcon
47 
48 TREE_ITEM_HEIGHT = 25
49 
50 LMIcons = {
51  'rastImport' : MetaIcon(img = 'layer-import',
52  label = _('Import raster data')),
53  'rastLink' : MetaIcon(img = 'layer-import',
54  label = _('Link external raster data')),
55  'rastOut' : MetaIcon(img = 'layer-export',
56  label = _('Set raster output format')),
57  'vectImport' : MetaIcon(img = 'layer-import',
58  label = _('Import vector data')),
59  'vectLink' : MetaIcon(img = 'layer-import',
60  label = _('Link external vector data')),
61  'vectOut' : MetaIcon(img = 'layer-export',
62  label = _('Set vector output format')),
63  'addCmd' : MetaIcon(img = 'layer-command-add',
64  label = _('Add command layer')),
65  'quit' : MetaIcon(img = 'quit',
66  label = _('Quit')),
67  'addRgb' : MetaIcon(img = 'layer-rgb-add',
68  label = _('Add RGB map layer')),
69  'addHis' : MetaIcon(img = 'layer-his-add',
70  label = _('Add HIS map layer')),
71  'addShaded' : MetaIcon(img = 'layer-shaded-relief-add',
72  label = _('Add shaded relief map layer')),
73  'addRArrow' : MetaIcon(img = 'layer-aspect-arrow-add',
74  label = _('Add raster flow arrows')),
75  'addRNum' : MetaIcon(img = 'layer-cell-cats-add',
76  label = _('Add raster cell numbers')),
77  'addThematic': MetaIcon(img = 'layer-vector-thematic-add',
78  label = _('Add thematic area (choropleth) map layer')),
79  'addChart' : MetaIcon(img = 'layer-vector-chart-add',
80  label = _('Add thematic chart layer')),
81  'addGrid' : MetaIcon(img = 'layer-grid-add',
82  label = _('Add grid layer')),
83  'addGeodesic': MetaIcon(img = 'shortest-distance',
84  label = _('Add geodesic line layer')),
85  'addRhumb' : MetaIcon(img = 'shortest-distance',
86  label = _('Add rhumbline layer')),
87  'addLabels' : MetaIcon(img = 'layer-label-add',
88  label = _('Add labels')),
89  'addRast3d' : MetaIcon(img = 'layer-raster3d-add',
90  label = _('Add 3D raster map layer'),
91  desc = _('Note that 3D raster data are rendered only in 3D view mode')),
92  'layerOptions' : MetaIcon(img = 'options',
93  label = _('Set options')),
94  }
95 
96 class LayerTree(treemixin.DragAndDrop, CT.CustomTreeCtrl):
97  """!Creates layer tree structure
98  """
99  def __init__(self, parent,
100  id = wx.ID_ANY, style = wx.SUNKEN_BORDER,
101  ctstyle = CT.TR_HAS_BUTTONS | CT.TR_HAS_VARIABLE_ROW_HEIGHT |
102  CT.TR_HIDE_ROOT | CT.TR_ROW_LINES | CT.TR_FULL_ROW_HIGHLIGHT |
103  CT.TR_MULTIPLE, **kwargs):
104 
105  if 'style' in kwargs:
106  ctstyle |= kwargs['style']
107  del kwargs['style']
108  self.disp_idx = kwargs['idx']
109  del kwargs['idx']
110  self.lmgr = kwargs['lmgr']
111  del kwargs['lmgr']
112  self.notebook = kwargs['notebook'] # GIS Manager notebook for layer tree
113  del kwargs['notebook']
114  self.auimgr = kwargs['auimgr'] # aui manager
115  del kwargs['auimgr']
116  showMapDisplay = kwargs['showMapDisplay']
117  del kwargs['showMapDisplay']
118  self.treepg = parent # notebook page holding layer tree
119  self.Map = Map() # instance of render.Map to be associated with display
120  self.root = None # ID of layer tree root node
121  self.groupnode = 0 # index value for layers
122  self.optpage = {} # dictionary of notebook option pages for each map layer
123  self.layer_selected = None # ID of currently selected layer
124  self.saveitem = {} # dictionary to preserve layer attributes for drag and drop
125  self.first = True # indicates if a layer is just added or not
126  self.flag = '' # flag for drag and drop hittest
127  self.rerender = False # layer change requires a rerendering if auto render
128  self.reorder = False # layer change requires a reordering
129  self.hitCheckbox = False # if cursor points at layer checkbox (to cancel selection changes)
130  self.forceCheck = False # force check layer if CheckItem is called
131 
132  try:
133  ctstyle |= CT.TR_ALIGN_WINDOWS
134  except AttributeError:
135  pass
136 
137  if globalvar.hasAgw:
138  super(LayerTree, self).__init__(parent, id, agwStyle = ctstyle, **kwargs)
139  else:
140  super(LayerTree, self).__init__(parent, id, style = ctstyle, **kwargs)
141  self.SetName("LayerTree")
142 
143  ### SetAutoLayout() causes that no vertical scrollbar is displayed
144  ### when some layers are not visible in layer tree
145  # self.SetAutoLayout(True)
146  self.SetGradientStyle(1)
147  self.EnableSelectionGradient(True)
148  self._setGradient()
149 
150  # init associated map display
151  pos = wx.Point((self.disp_idx + 1) * 25, (self.disp_idx + 1) * 25)
152  self.mapdisplay = MapFrame(self,
153  id = wx.ID_ANY, pos = pos,
154  size = globalvar.MAP_WINDOW_SIZE,
155  style = wx.DEFAULT_FRAME_STYLE,
156  tree = self, notebook = self.notebook,
157  lmgr = self.lmgr, page = self.treepg,
158  Map = self.Map, auimgr = self.auimgr)
159 
160  # title
161  self.mapdisplay.SetTitle(_("GRASS GIS %(version)s Map Display: %(id)d - Location: %(loc)s") % \
162  { 'version' : grass.version()['version'],
163  'id' : self.disp_idx + 1,
164  'loc' : grass.gisenv()["LOCATION_NAME"] })
165 
166  # show new display
167  if showMapDisplay is True:
168  self.mapdisplay.Show()
169  self.mapdisplay.Refresh()
170  self.mapdisplay.Update()
171 
172  self.root = self.AddRoot(_("Map Layers"))
173  self.SetPyData(self.root, (None, None))
174 
175  # create image list to use with layer tree
176  il = wx.ImageList(16, 16, mask = False)
177 
178  trart = wx.ArtProvider.GetBitmap(wx.ART_FOLDER_OPEN, wx.ART_OTHER, (16, 16))
179  self.folder_open = il.Add(trart)
180  trart = wx.ArtProvider.GetBitmap(wx.ART_FOLDER, wx.ART_OTHER, (16, 16))
181  self.folder = il.Add(trart)
182 
183  bmpsize = (16, 16)
184  trgif = BaseIcons["addRast"].GetBitmap(bmpsize)
185  self.rast_icon = il.Add(trgif)
186 
187  trgif = LMIcons["addRast3d"].GetBitmap(bmpsize)
188  self.rast3d_icon = il.Add(trgif)
189 
190  trgif = LMIcons["addRgb"].GetBitmap(bmpsize)
191  self.rgb_icon = il.Add(trgif)
192 
193  trgif = LMIcons["addHis"].GetBitmap(bmpsize)
194  self.his_icon = il.Add(trgif)
195 
196  trgif = LMIcons["addShaded"].GetBitmap(bmpsize)
197  self.shaded_icon = il.Add(trgif)
198 
199  trgif = LMIcons["addRArrow"].GetBitmap(bmpsize)
200  self.rarrow_icon = il.Add(trgif)
201 
202  trgif = LMIcons["addRNum"].GetBitmap(bmpsize)
203  self.rnum_icon = il.Add(trgif)
204 
205  trgif = BaseIcons["addVect"].GetBitmap(bmpsize)
206  self.vect_icon = il.Add(trgif)
207 
208  trgif = LMIcons["addThematic"].GetBitmap(bmpsize)
209  self.theme_icon = il.Add(trgif)
210 
211  trgif = LMIcons["addChart"].GetBitmap(bmpsize)
212  self.chart_icon = il.Add(trgif)
213 
214  trgif = LMIcons["addGrid"].GetBitmap(bmpsize)
215  self.grid_icon = il.Add(trgif)
216 
217  trgif = LMIcons["addGeodesic"].GetBitmap(bmpsize)
218  self.geodesic_icon = il.Add(trgif)
219 
220  trgif = LMIcons["addRhumb"].GetBitmap(bmpsize)
221  self.rhumb_icon = il.Add(trgif)
222 
223  trgif = LMIcons["addLabels"].GetBitmap(bmpsize)
224  self.labels_icon = il.Add(trgif)
225 
226  trgif = LMIcons["addCmd"].GetBitmap(bmpsize)
227  self.cmd_icon = il.Add(trgif)
228 
229  self.AssignImageList(il)
230 
231  self.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.OnExpandNode)
232  self.Bind(wx.EVT_TREE_ITEM_COLLAPSED, self.OnCollapseNode)
233  self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnActivateLayer)
234  self.Bind(wx.EVT_TREE_SEL_CHANGED, self.OnChangeSel)
235  self.Bind(wx.EVT_TREE_SEL_CHANGING, self.OnChangingSel)
236  self.Bind(CT.EVT_TREE_ITEM_CHECKED, self.OnLayerChecked)
237  self.Bind(CT.EVT_TREE_ITEM_CHECKING, self.OnLayerChecking)
238  self.Bind(wx.EVT_TREE_DELETE_ITEM, self.OnDeleteLayer)
239  self.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnLayerContextMenu)
240  self.Bind(wx.EVT_TREE_END_DRAG, self.OnEndDrag)
241  self.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnRenamed)
242  self.Bind(wx.EVT_KEY_UP, self.OnKeyUp)
243  self.Bind(wx.EVT_IDLE, self.OnIdle)
244  self.Bind(wx.EVT_MOTION, self.OnMotion)
245 
246  def _setGradient(self, iType = None):
247  """!Set gradient for items
248 
249  @param iType bgmap, vdigit or None
250  """
251  if iType == 'bgmap':
252  self.SetFirstGradientColour(wx.Colour(0, 100, 0))
253  self.SetSecondGradientColour(wx.Colour(0, 150, 0))
254  elif iType == 'vdigit':
255  self.SetFirstGradientColour(wx.Colour(100, 0, 0))
256  self.SetSecondGradientColour(wx.Colour(150, 0, 0))
257  else:
258  self.SetFirstGradientColour(wx.Colour(100, 100, 100))
259  self.SetSecondGradientColour(wx.Colour(150, 150, 150))
260 
261  def GetSelections(self):
262  """Returns a list of selected items.
263 
264  This method is copied from customtreecontrol and overriden because
265  with some version wx (?) multiple selection doesn't work.
266  Probably it is caused by another GetSelections method in treemixin.DragAndDrop?
267  """
268  array = []
269  idRoot = self.GetRootItem()
270  if idRoot:
271  array = self.FillArray(idRoot, array)
272 
273  #else: the tree is empty, so no selections
274 
275  return array
276 
277  def GetMap(self):
278  """!Get map instace"""
279  return self.Map
280 
281  def GetMapDisplay(self):
282  """!Get associated MapFrame"""
283  return self.mapdisplay
284 
285  def OnIdle(self, event):
286  """!Only re-order and re-render a composite map image from GRASS during
287  idle time instead of multiple times during layer changing.
288  """
289  if self.rerender:
290  if self.mapdisplay.GetToolbar('vdigit'):
291  vector = True
292  else:
293  vector = False
294  if self.mapdisplay.IsAutoRendered():
295  self.mapdisplay.MapWindow2D.UpdateMap(render = True, renderVector = vector)
296  if self.lmgr.IsPaneShown('toolbarNviz'): # nviz
297  self.mapdisplay.MapWindow3D.UpdateMap(render = True)
298 
299  self.rerender = False
300 
301  event.Skip()
302 
303  def OnKeyUp(self, event):
304  """!Key pressed"""
305  key = event.GetKeyCode()
306 
307  if key == wx.WXK_DELETE and self.lmgr and \
308  not self.GetEditControl():
309  self.lmgr.OnDeleteLayer(None)
310 
311  event.Skip()
312 
313  def OnLayerContextMenu (self, event):
314  """!Contextual menu for item/layer"""
315  if not self.layer_selected:
316  event.Skip()
317  return
318 
319  ltype = self.GetPyData(self.layer_selected)[0]['type']
320  mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
321 
322  Debug.msg (4, "LayerTree.OnContextMenu: layertype=%s" % \
323  ltype)
324 
325  if not hasattr (self, "popupID"):
326  self.popupID = dict()
327  for key in ('remove', 'rename', 'opacity', 'nviz', 'zoom',
328  'region', 'export', 'attr', 'edit0', 'edit1',
329  'bgmap', 'topo', 'meta', 'null', 'zoom1', 'region1',
330  'color', 'hist', 'univar', 'prof', 'properties'):
331  self.popupID[key] = wx.NewId()
332 
333  self.popupMenu = wx.Menu()
334 
335  numSelected = len(self.GetSelections())
336 
337  self.popupMenu.Append(self.popupID['remove'], text = _("Remove"))
338  self.Bind(wx.EVT_MENU, self.lmgr.OnDeleteLayer, id = self.popupID['remove'])
339 
340  if ltype != "command":
341  self.popupMenu.Append(self.popupID['rename'], text = _("Rename"))
342  self.Bind(wx.EVT_MENU, self.OnRenameLayer, id = self.popupID['rename'])
343  if numSelected > 1:
344  self.popupMenu.Enable(self.popupID['rename'], False)
345 
346  # map layer items
347  if ltype not in ("group", "command"):
348  self.popupMenu.AppendSeparator()
349  self.popupMenu.Append(self.popupID['opacity'], text = _("Change opacity level"))
350  self.Bind(wx.EVT_MENU, self.OnPopupOpacityLevel, id = self.popupID['opacity'])
351  self.popupMenu.Append(self.popupID['properties'], text = _("Properties"))
352  self.Bind(wx.EVT_MENU, self.OnPopupProperties, id = self.popupID['properties'])
353 
354  if numSelected > 1:
355  self.popupMenu.Enable(self.popupID['opacity'], False)
356  self.popupMenu.Enable(self.popupID['properties'], False)
357 
358  if ltype in ('raster', 'vector', '3d-raster') and self.lmgr.IsPaneShown('toolbarNviz'):
359  self.popupMenu.Append(self.popupID['nviz'], _("3D view properties"))
360  self.Bind (wx.EVT_MENU, self.OnNvizProperties, id = self.popupID['nviz'])
361 
362  if ltype in ('raster', 'vector', 'rgb'):
363  self.popupMenu.Append(self.popupID['zoom'], text = _("Zoom to selected map(s)"))
364  self.Bind(wx.EVT_MENU, self.mapdisplay.OnZoomToMap, id = self.popupID['zoom'])
365  self.popupMenu.Append(self.popupID['region'], text = _("Set computational region from selected map(s)"))
366  self.Bind(wx.EVT_MENU, self.OnSetCompRegFromMap, id = self.popupID['region'])
367 
368  # specific items
369  try:
370  mltype = self.GetPyData(self.layer_selected)[0]['type']
371  except:
372  mltype = None
373 
374  # vector layers (specific items)
375  if mltype and mltype == "vector":
376  self.popupMenu.AppendSeparator()
377  self.popupMenu.Append(self.popupID['export'], text = _("Export"))
378  self.Bind(wx.EVT_MENU, lambda x: self.lmgr.OnMenuCmd(cmd = ['v.out.ogr',
379  'input=%s' % mapLayer.GetName()]),
380  id = self.popupID['export'])
381 
382  self.popupMenu.AppendSeparator()
383 
384  self.popupMenu.Append(self.popupID['color'], _("Set color table"))
385  self.Bind (wx.EVT_MENU, self.OnVectorColorTable, id = self.popupID['color'])
386 
387  self.popupMenu.Append(self.popupID['attr'], text = _("Show attribute data"))
388  self.Bind(wx.EVT_MENU, self.lmgr.OnShowAttributeTable, id = self.popupID['attr'])
389 
390  self.popupMenu.Append(self.popupID['edit0'], text = _("Start editing"))
391  self.popupMenu.Append(self.popupID['edit1'], text = _("Stop editing"))
392  self.popupMenu.Enable(self.popupID['edit1'], False)
393  self.Bind (wx.EVT_MENU, self.OnStartEditing, id = self.popupID['edit0'])
394  self.Bind (wx.EVT_MENU, self.OnStopEditing, id = self.popupID['edit1'])
395 
396  layer = self.GetPyData(self.layer_selected)[0]['maplayer']
397  # enable editing only for vector map layers available in the current mapset
398  digitToolbar = self.mapdisplay.GetToolbar('vdigit')
399  if digitToolbar:
400  # background vector map
401  self.popupMenu.Append(self.popupID['bgmap'],
402  text = _("Use as background vector map for digitizer"),
403  kind = wx.ITEM_CHECK)
404  self.Bind(wx.EVT_MENU, self.OnSetBgMap, id = self.popupID['bgmap'])
405  if UserSettings.Get(group = 'vdigit', key = 'bgmap', subkey = 'value',
406  internal = True) == layer.GetName():
407  self.popupMenu.Check(self.popupID['bgmap'], True)
408 
409  self.popupMenu.Append(self.popupID['topo'], text = _("Rebuild topology"))
410  self.Bind(wx.EVT_MENU, self.OnTopology, id = self.popupID['topo'])
411 
412  if layer.GetMapset() != grass.gisenv()['MAPSET']:
413  # only vector map in current mapset can be edited
414  self.popupMenu.Enable (self.popupID['edit0'], False)
415  self.popupMenu.Enable (self.popupID['edit1'], False)
416  self.popupMenu.Enable (self.popupID['topo'], False)
417  elif digitToolbar and digitToolbar.GetLayer():
418  # vector map already edited
419  vdigitLayer = digitToolbar.GetLayer()
420  if vdigitLayer is layer:
421  self.popupMenu.Enable(self.popupID['edit0'], False)
422  self.popupMenu.Enable(self.popupID['edit1'], True)
423  self.popupMenu.Enable(self.popupID['remove'], False)
424  self.popupMenu.Enable(self.popupID['bgmap'], False)
425  self.popupMenu.Enable(self.popupID['topo'], False)
426  else:
427  self.popupMenu.Enable(self.popupID['edit0'], False)
428  self.popupMenu.Enable(self.popupID['edit1'], False)
429  self.popupMenu.Enable(self.popupID['bgmap'], True)
430 
431  self.popupMenu.Append(self.popupID['meta'], _("Metadata"))
432  self.Bind (wx.EVT_MENU, self.OnMetadata, id = self.popupID['meta'])
433  if numSelected > 1:
434  self.popupMenu.Enable(self.popupID['attr'], False)
435  self.popupMenu.Enable(self.popupID['edit0'], False)
436  self.popupMenu.Enable(self.popupID['edit1'], False)
437  self.popupMenu.Enable(self.popupID['meta'], False)
438  self.popupMenu.Enable(self.popupID['bgmap'], False)
439  self.popupMenu.Enable(self.popupID['topo'], False)
440  self.popupMenu.Enable(self.popupID['export'], False)
441 
442  # raster layers (specific items)
443  elif mltype and mltype == "raster":
444  self.popupMenu.Append(self.popupID['zoom1'], text = _("Zoom to selected map(s) (ignore NULLs)"))
445  self.Bind(wx.EVT_MENU, self.mapdisplay.OnZoomToRaster, id = self.popupID['zoom1'])
446  self.popupMenu.Append(self.popupID['region1'], text = _("Set computational region from selected map(s) (ignore NULLs)"))
447  self.Bind(wx.EVT_MENU, self.OnSetCompRegFromRaster, id = self.popupID['region1'])
448 
449  self.popupMenu.AppendSeparator()
450  self.popupMenu.Append(self.popupID['export'], text = _("Export"))
451  self.Bind(wx.EVT_MENU, lambda x: self.lmgr.OnMenuCmd(cmd = ['r.out.gdal',
452  'input=%s' % mapLayer.GetName()]),
453  id = self.popupID['export'])
454 
455  self.popupMenu.AppendSeparator()
456  self.popupMenu.Append(self.popupID['color'], _("Set color table"))
457  self.Bind (wx.EVT_MENU, self.OnRasterColorTable, id = self.popupID['color'])
458  self.popupMenu.Append(self.popupID['hist'], _("Histogram"))
459  self.Bind (wx.EVT_MENU, self.OnHistogram, id = self.popupID['hist'])
460  self.popupMenu.Append(self.popupID['univar'], _("Univariate raster statistics"))
461  self.Bind (wx.EVT_MENU, self.OnUnivariateStats, id = self.popupID['univar'])
462  self.popupMenu.Append(self.popupID['prof'], _("Profile"))
463  self.Bind (wx.EVT_MENU, self.OnProfile, id = self.popupID['prof'])
464  self.popupMenu.Append(self.popupID['meta'], _("Metadata"))
465  self.Bind (wx.EVT_MENU, self.OnMetadata, id = self.popupID['meta'])
466 
467  if numSelected > 1:
468  self.popupMenu.Enable(self.popupID['zoom1'], False)
469  self.popupMenu.Enable(self.popupID['region1'], False)
470  self.popupMenu.Enable(self.popupID['color'], False)
471  self.popupMenu.Enable(self.popupID['hist'], False)
472  self.popupMenu.Enable(self.popupID['univar'], False)
473  self.popupMenu.Enable(self.popupID['prof'], False)
474  self.popupMenu.Enable(self.popupID['meta'], False)
475  self.popupMenu.Enable(self.popupID['export'], False)
476  if self.lmgr.IsPaneShown('toolbarNviz'):
477  self.popupMenu.Enable(self.popupID['nviz'], False)
478 
479  self.PopupMenu(self.popupMenu)
480  self.popupMenu.Destroy()
481 
482  def OnTopology(self, event):
483  """!Rebuild topology of selected vector map"""
484  mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
485  cmd = ['v.build',
486  'map=%s' % mapLayer.GetName()]
487  self.lmgr.goutput.RunCmd(cmd, switchPage = True)
488 
489  def OnMetadata(self, event):
490  """!Print metadata of raster/vector map layer
491  TODO: Dialog to modify metadata
492  """
493  mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
494  mltype = self.GetPyData(self.layer_selected)[0]['type']
495 
496  if mltype == 'raster':
497  cmd = ['r.info']
498  elif mltype == 'vector':
499  cmd = ['v.info']
500  cmd.append('map=%s' % mapLayer.GetName())
501 
502  # print output to command log area
503  self.lmgr.goutput.RunCmd(cmd, switchPage = True)
504 
505  def OnSetCompRegFromRaster(self, event):
506  """!Set computational region from selected raster map (ignore NULLs)"""
507  mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
508 
509  cmd = ['g.region',
510  '-p',
511  'zoom=%s' % mapLayer.GetName()]
512 
513  # print output to command log area
514  self.lmgr.goutput.RunCmd(cmd)
515 
516  def OnSetCompRegFromMap(self, event):
517  """!Set computational region from selected raster/vector map
518  """
519  rast = []
520  vect = []
521  rast3d = []
522  for layer in self.GetSelections():
523  mapLayer = self.GetPyData(layer)[0]['maplayer']
524  mltype = self.GetPyData(layer)[0]['type']
525 
526  if mltype == 'raster':
527  rast.append(mapLayer.GetName())
528  elif mltype == 'vector':
529  vect.append(mapLayer.GetName())
530  elif mltype == '3d-raster':
531  rast3d.append(mapLayer.GetName())
532  elif mltype == 'rgb':
533  for rname in mapLayer.GetName().splitlines():
534  rast.append(rname)
535 
536  cmd = ['g.region']
537  if rast:
538  cmd.append('rast=%s' % ','.join(rast))
539  if vect:
540  cmd.append('vect=%s' % ','.join(vect))
541  if rast3d:
542  cmd.append('rast3d=%s' % ','.join(rast3d))
543 
544  # print output to command log area
545  if len(cmd) > 1:
546  cmd.append('-p')
547  self.lmgr.goutput.RunCmd(cmd, compReg = False)
548 
549  def OnProfile(self, event):
550  """!Plot profile of given raster map layer"""
551  mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
552  if not mapLayer.GetName():
553  wx.MessageBox(parent = self,
554  message = _("Unable to create profile of "
555  "raster map."),
556  caption = _("Error"), style = wx.OK | wx.ICON_ERROR | wx.CENTRE)
557  return False
558 
559  if not hasattr (self, "profileFrame"):
560  self.profileFrame = None
561 
562  if hasattr (self.mapdisplay, "profile") and self.mapdisplay.profile:
563  self.profileFrame = self.mapdisplay.profile
564 
565  if not self.profileFrame:
566  self.profileFrame = ProfileFrame(self.mapdisplay,
567  id = wx.ID_ANY, pos = wx.DefaultPosition, size = (700,300),
568  style = wx.DEFAULT_FRAME_STYLE, rasterList = [mapLayer.GetName()])
569  # show new display
570  self.profileFrame.Show()
571 
572  def OnRasterColorTable(self, event):
573  """!Set color table for raster map"""
574  name = self.GetPyData(self.layer_selected)[0]['maplayer'].GetName()
575  GUI(parent = self).ParseCommand(['r.colors',
576  'map=%s' % name])
577 
578  def OnVectorColorTable(self, event):
579  """!Set color table for vector map"""
580  name = self.GetPyData(self.layer_selected)[0]['maplayer'].GetName()
581  GUI(parent = self, centreOnParent = False).ParseCommand(['v.colors',
582  'map=%s' % name])
583 
584  def OnHistogram(self, event):
585  """!Plot histogram for given raster map layer
586  """
587  mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
588  if not mapLayer.GetName():
589  GError(parent = self,
590  message = _("Unable to display histogram of "
591  "raster map. No map name defined."))
592  return
593 
594  win = HistogramFrame(parent = self)
595 
596  win.CentreOnScreen()
597  win.Show()
598  win.SetHistLayer(mapLayer.GetName())
599  win.HistWindow.UpdateHist()
600  win.Refresh()
601  win.Update()
602 
603  def OnUnivariateStats(self, event):
604  """!Univariate raster statistics"""
605  name = self.GetPyData(self.layer_selected)[0]['maplayer'].GetName()
606  self.lmgr.goutput.RunCmd(['r.univar', 'map=%s' % name], switchPage = True)
607 
608  def OnStartEditing(self, event):
609  """!Start editing vector map layer requested by the user
610  """
611  try:
612  maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
613  except:
614  event.Skip()
615  return
616 
617  if not self.mapdisplay.GetToolbar('vdigit'): # enable tool
618  self.mapdisplay.AddToolbar('vdigit')
619 
620  if not self.mapdisplay.toolbars['vdigit']:
621  return
622 
623  self.mapdisplay.toolbars['vdigit'].StartEditing(maplayer)
624 
625  self._setGradient('vdigit')
626  self.RefreshLine(self.layer_selected)
627 
628  def OnStopEditing(self, event):
629  """!Stop editing the current vector map layer
630  """
631  maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
632 
633  self.mapdisplay.toolbars['vdigit'].OnExit()
634  if self.lmgr:
635  self.lmgr.toolbars['tools'].Enable('vdigit', enable = True)
636 
637  self._setGradient()
638  self.RefreshLine(self.layer_selected)
639 
640  def OnSetBgMap(self, event):
641  """!Set background vector map for editing sesstion"""
642  digit = self.mapdisplay.GetWindow().digit
643  if event.IsChecked():
644  mapName = self.GetPyData(self.layer_selected)[0]['maplayer'].GetName()
645  UserSettings.Set(group = 'vdigit', key = 'bgmap', subkey = 'value',
646  value = str(mapName), internal = True)
647  digit.OpenBackgroundMap(mapName)
648  self._setGradient('bgmap')
649  else:
650  UserSettings.Set(group = 'vdigit', key = 'bgmap', subkey = 'value',
651  value = '', internal = True)
652  digit.CloseBackgroundMap()
653  self._setGradient()
654 
655  self.RefreshLine(self.layer_selected)
656 
657  def OnPopupProperties (self, event):
658  """!Popup properties dialog"""
660 
661  def OnPopupOpacityLevel(self, event):
662  """!Popup opacity level indicator"""
663  if not self.GetPyData(self.layer_selected)[0]['ctrl']:
664  return
665 
666  maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
667  current_opacity = maplayer.GetOpacity()
668 
669  dlg = SetOpacityDialog(self, opacity = current_opacity,
670  title = _("Set opacity of <%s>") % maplayer.GetName())
671  dlg.CentreOnParent()
672  dlg.Bind(EVT_APPLY_OPACITY, self.OnApplyLayerOpacity)
673 
674  if dlg.ShowModal() == wx.ID_OK:
675  self.ChangeLayerOpacity(layer = self.layer_selected, value = dlg.GetOpacity())
676  dlg.Destroy()
677 
678  def OnApplyLayerOpacity(self, event):
679  """!Handles EVT_APPLY_OPACITY event."""
680  self.ChangeLayerOpacity(layer = self.layer_selected, value = event.value)
681 
682  def ChangeLayerOpacity(self, layer, value):
683  """!Change opacity value of layer
684  @param layer layer for which to change (item in layertree)
685  @param value opacity value (float between 0 and 1)
686  """
687  maplayer = self.GetPyData(layer)[0]['maplayer']
688  self.Map.ChangeOpacity(maplayer, value)
689  maplayer.SetOpacity(value)
690  self.SetItemText(layer,
691  self._getLayerName(layer))
692 
693  # vector layer currently edited
694  if self.GetMapDisplay().GetToolbar('vdigit') and \
695  self.GetMapDisplay().GetToolbar('vdigit').GetLayer() == maplayer:
696  alpha = int(value * 255)
697  self.GetMapDisplay().GetWindow().digit.GetDisplay().UpdateSettings(alpha = alpha)
698 
699  # redraw map if auto-rendering is enabled
700  renderVector = False
701  if self.GetMapDisplay().GetToolbar('vdigit'):
702  renderVector = True
703  self.GetMapDisplay().GetWindow().UpdateMap(render = False, renderVector = renderVector)
704 
705  def OnNvizProperties(self, event):
706  """!Nviz-related properties (raster/vector/volume)
707 
708  @todo vector/volume
709  """
710  self.lmgr.notebook.SetSelectionByName('nviz')
711  ltype = self.GetPyData(self.layer_selected)[0]['type']
712  if ltype == 'raster':
713  self.lmgr.nviz.SetPage('surface')
714  elif ltype == 'vector':
715  self.lmgr.nviz.SetPage('vector')
716  elif ltype == '3d-raster':
717  self.lmgr.nviz.SetPage('volume')
718 
719  def OnRenameLayer (self, event):
720  """!Rename layer"""
721  self.EditLabel(self.layer_selected)
722  self.GetEditControl().SetSelection(-1, -1)
723 
724  def OnRenamed(self, event):
725  """!Layer renamed"""
726  item = self.layer_selected
727  self.GetPyData(item)[0]['label'] = event.GetLabel()
728  self.SetItemText(item, self._getLayerName(item)) # not working, why?
729 
730  event.Skip()
731 
732  def AddLayer(self, ltype, lname = None, lchecked = None,
733  lopacity = 1.0, lcmd = None, lgroup = None, lvdigit = None, lnviz = None, multiple = True):
734  """!Add new item to the layer tree, create corresponding MapLayer instance.
735  Launch property dialog if needed (raster, vector, etc.)
736 
737  @param ltype layer type (raster, vector, 3d-raster, ...)
738  @param lname layer name
739  @param lchecked if True layer is checked
740  @param lopacity layer opacity level
741  @param lcmd command (given as a list)
742  @param lgroup index of group item (-1 for root) or None
743  @param lvdigit vector digitizer settings (eg. geometry attributes)
744  @param lnviz layer Nviz properties
745  @param multiple True to allow multiple map layers in layer tree
746  """
747  if lname and not multiple:
748  # check for duplicates
749  item = self.GetFirstVisibleItem()
750  while item and item.IsOk():
751  if self.GetPyData(item)[0]['type'] == 'vector':
752  name = self.GetPyData(item)[0]['maplayer'].GetName()
753  if name == lname:
754  return
755  item = self.GetNextVisible(item)
756 
757  self.first = True
758  params = {} # no initial options parameters
759 
760  # deselect active item
761  if self.layer_selected:
762  self.SelectItem(self.layer_selected, select = False)
763 
764  Debug.msg (3, "LayerTree().AddLayer(): ltype=%s" % (ltype))
765 
766  if ltype == 'command':
767  # generic command item
768  ctrl = self._createCommandCtrl()
769  ctrl.Bind(wx.EVT_TEXT_ENTER, self.OnCmdChanged)
770 
771  elif ltype == 'group':
772  # group item
773  ctrl = None
774  grouptext = _('Layer group:') + str(self.groupnode)
775  self.groupnode += 1
776  else:
777  btnbmp = LMIcons["layerOptions"].GetBitmap((16,16))
778  ctrl = buttons.GenBitmapButton(self, id = wx.ID_ANY, bitmap = btnbmp, size = (24,24))
779  ctrl.SetToolTipString(_("Click to edit layer settings"))
780  self.Bind(wx.EVT_BUTTON, self.OnLayerContextMenu, ctrl)
781  # add layer to the layer tree
782  if self.layer_selected and self.layer_selected != self.GetRootItem():
783  if self.GetPyData(self.layer_selected)[0]['type'] == 'group' \
784  and self.IsExpanded(self.layer_selected):
785  # add to group (first child of self.layer_selected) if group expanded
786  layer = self.PrependItem(parent = self.layer_selected,
787  text = '', ct_type = 1, wnd = ctrl)
788  else:
789  # prepend to individual layer or non-expanded group
790  if lgroup == -1:
791  # -> last child of root (loading from workspace)
792  layer = self.AppendItem(parentId = self.root,
793  text = '', ct_type = 1, wnd = ctrl)
794  elif lgroup > -1:
795  # -> last child of group (loading from workspace)
796  parent = self.FindItemByIndex(index = lgroup)
797  if not parent:
798  parent = self.root
799  layer = self.AppendItem(parentId = parent,
800  text = '', ct_type = 1, wnd = ctrl)
801  elif lgroup is None:
802  # -> previous sibling of selected layer
803  parent = self.GetItemParent(self.layer_selected)
804  layer = self.InsertItem(parentId = parent,
805  input = self.GetPrevSibling(self.layer_selected),
806  text = '', ct_type = 1, wnd = ctrl)
807  else: # add first layer to the layer tree (first child of root)
808  layer = self.PrependItem(parent = self.root, text = '', ct_type = 1, wnd = ctrl)
809 
810  # layer is initially unchecked as inactive (beside 'command')
811  # use predefined value if given
812  if lchecked is not None:
813  checked = lchecked
814  else:
815  checked = True
816 
817  self.forceCheck = True
818  self.CheckItem(layer, checked = checked)
819 
820  # add text and icons for each layer ltype
821  label = _('(double click to set properties)') + ' ' * 15
822  if ltype == 'raster':
823  self.SetItemImage(layer, self.rast_icon)
824  self.SetItemText(layer, '%s %s' % (_('raster'), label))
825  elif ltype == '3d-raster':
826  self.SetItemImage(layer, self.rast3d_icon)
827  self.SetItemText(layer, '%s %s' % (_('3D raster'), label))
828  elif ltype == 'rgb':
829  self.SetItemImage(layer, self.rgb_icon)
830  self.SetItemText(layer, '%s %s' % (_('RGB'), label))
831  elif ltype == 'his':
832  self.SetItemImage(layer, self.his_icon)
833  self.SetItemText(layer, '%s %s' % (_('HIS'), label))
834  elif ltype == 'shaded':
835  self.SetItemImage(layer, self.shaded_icon)
836  self.SetItemText(layer, '%s %s' % (_('shaded relief'), label))
837  elif ltype == 'rastnum':
838  self.SetItemImage(layer, self.rnum_icon)
839  self.SetItemText(layer, '%s %s' % (_('raster cell numbers'), label))
840  elif ltype == 'rastarrow':
841  self.SetItemImage(layer, self.rarrow_icon)
842  self.SetItemText(layer, '%s %s' % (_('raster flow arrows'), label))
843  elif ltype == 'vector':
844  self.SetItemImage(layer, self.vect_icon)
845  self.SetItemText(layer, '%s %s' % (_('vector'), label))
846  elif ltype == 'thememap':
847  self.SetItemImage(layer, self.theme_icon)
848  self.SetItemText(layer, '%s %s' % (_('thematic map'), label))
849  elif ltype == 'themechart':
850  self.SetItemImage(layer, self.chart_icon)
851  self.SetItemText(layer, '%s %s' % (_('thematic charts'), label))
852  elif ltype == 'grid':
853  self.SetItemImage(layer, self.grid_icon)
854  self.SetItemText(layer, '%s %s' % (_('grid'), label))
855  elif ltype == 'geodesic':
856  self.SetItemImage(layer, self.geodesic_icon)
857  self.SetItemText(layer, '%s %s' % (_('geodesic line'), label))
858  elif ltype == 'rhumb':
859  self.SetItemImage(layer, self.rhumb_icon)
860  self.SetItemText(layer, '%s %s' % (_('rhumbline'), label))
861  elif ltype == 'labels':
862  self.SetItemImage(layer, self.labels_icon)
863  self.SetItemText(layer, '%s %s' % (_('vector labels'), label))
864  elif ltype == 'command':
865  self.SetItemImage(layer, self.cmd_icon)
866  elif ltype == 'group':
867  self.SetItemImage(layer, self.folder)
868  self.SetItemText(layer, grouptext)
869 
870  self.first = False
871 
872  if ltype != 'group':
873  if lcmd and len(lcmd) > 1:
874  cmd = lcmd
875  render = False
876  name, found = GetLayerNameFromCmd(lcmd)
877  else:
878  cmd = []
879  if ltype == 'command' and lname:
880  for c in lname.split(';'):
881  cmd.append(c.split(' '))
882 
883  render = False
884  name = None
885 
886  if ctrl:
887  ctrlId = ctrl.GetId()
888  else:
889  ctrlId = None
890 
891  # add a data object to hold the layer's command (does not apply to generic command layers)
892  self.SetPyData(layer, ({'cmd' : cmd,
893  'type' : ltype,
894  'ctrl' : ctrlId,
895  'label' : None,
896  'maplayer' : None,
897  'vdigit' : lvdigit,
898  'nviz' : lnviz,
899  'propwin' : None},
900  None))
901 
902  # find previous map layer instance
903  prevItem = self.GetFirstChild(self.root)[0]
904  prevMapLayer = None
905  pos = -1
906  while prevItem and prevItem.IsOk() and prevItem != layer:
907  if self.GetPyData(prevItem)[0]['maplayer']:
908  prevMapLayer = self.GetPyData(prevItem)[0]['maplayer']
909 
910  prevItem = self.GetNextSibling(prevItem)
911 
912  if prevMapLayer:
913  pos = self.Map.GetLayerIndex(prevMapLayer)
914  else:
915  pos = -1
916 
917  maplayer = self.Map.AddLayer(pos = pos,
918  type = ltype, command = self.GetPyData(layer)[0]['cmd'], name = name,
919  l_active = checked, l_hidden = False,
920  l_opacity = lopacity, l_render = render)
921  self.GetPyData(layer)[0]['maplayer'] = maplayer
922 
923  # run properties dialog if no properties given
924  if len(cmd) == 0:
925  self.PropertiesDialog(layer, show = True)
926 
927  else: # group
928  self.SetPyData(layer, ({'cmd' : None,
929  'type' : ltype,
930  'ctrl' : None,
931  'label' : None,
932  'maplayer' : None,
933  'propwin' : None},
934  None))
935 
936  # select new item
937  self.SelectItem(layer, select = True)
938  self.layer_selected = layer
939 
940  # use predefined layer name if given
941  if lname:
942  if ltype == 'group':
943  self.SetItemText(layer, lname)
944  elif ltype == 'command':
945  ctrl.SetValue(lname)
946  else:
947  self.SetItemText(layer, self._getLayerName(layer, lname))
948 
949  # updated progress bar range (mapwindow statusbar)
950  if checked is True:
951  self.mapdisplay.GetProgressBar().SetRange(len(self.Map.GetListOfLayers(l_active = True)))
952 
953  return layer
954 
955  def PropertiesDialog(self, layer, show = True):
956  """!Launch the properties dialog"""
957  if 'propwin' in self.GetPyData(layer)[0] and \
958  self.GetPyData(layer)[0]['propwin'] is not None:
959  # recycle GUI dialogs
960  win = self.GetPyData(layer)[0]['propwin']
961  if win.IsShown():
962  win.SetFocus()
963  else:
964  win.Show()
965 
966  return
967 
968  completed = ''
969  params = self.GetPyData(layer)[1]
970  ltype = self.GetPyData(layer)[0]['type']
971 
972  Debug.msg (3, "LayerTree.PropertiesDialog(): ltype=%s" % \
973  ltype)
974 
975  cmd = None
976  if self.GetPyData(layer)[0]['cmd']:
977  module = GUI(parent = self, show = show, centreOnParent = False)
978  module.ParseCommand(self.GetPyData(layer)[0]['cmd'],
979  completed = (self.GetOptData,layer,params))
980 
981  self.GetPyData(layer)[0]['cmd'] = module.GetCmd()
982  elif ltype == 'raster':
983  cmd = ['d.rast']
984  if UserSettings.Get(group='cmd', key='rasterOverlay', subkey='enabled'):
985  cmd.append('-o')
986 
987  elif ltype == '3d-raster':
988  cmd = ['d.rast3d.py']
989 
990  elif ltype == 'rgb':
991  cmd = ['d.rgb']
992  if UserSettings.Get(group='cmd', key='rasterOverlay', subkey='enabled'):
993  cmd.append('-o')
994 
995  elif ltype == 'his':
996  cmd = ['d.his']
997 
998  elif ltype == 'shaded':
999  cmd = ['d.shadedmap']
1000 
1001  elif ltype == 'rastarrow':
1002  cmd = ['d.rast.arrow']
1003 
1004  elif ltype == 'rastnum':
1005  cmd = ['d.rast.num']
1006 
1007  elif ltype == 'vector':
1008  types = list()
1009  for ftype in ['point', 'line', 'boundary', 'centroid', 'area', 'face']:
1010  if UserSettings.Get(group = 'cmd', key = 'showType', subkey = [ftype, 'enabled']):
1011  types.append(ftype)
1012 
1013  cmd = ['d.vect', 'type=%s' % ','.join(types)]
1014 
1015  elif ltype == 'thememap':
1016  # -s flag requested, otherwise only first thematic category is displayed
1017  # should be fixed by C-based d.thematic.* modules
1018  cmd = ['d.vect.thematic', '-s']
1019 
1020  elif ltype == 'themechart':
1021  cmd = ['d.vect.chart']
1022 
1023  elif ltype == 'grid':
1024  cmd = ['d.grid']
1025 
1026  elif ltype == 'geodesic':
1027  cmd = ['d.geodesic']
1028 
1029  elif ltype == 'rhumb':
1030  cmd = ['d.rhumbline']
1031 
1032  elif ltype == 'labels':
1033  cmd = ['d.labels']
1034 
1035  if cmd:
1036  GUI(parent = self, centreOnParent = False).ParseCommand(cmd,
1037  completed = (self.GetOptData,layer,params))
1038 
1039  def OnActivateLayer(self, event):
1040  """!Double click on the layer item.
1041  Launch property dialog, or expand/collapse group of items, etc.
1042  """
1043  self.lmgr.WorkspaceChanged()
1044  layer = event.GetItem()
1045  self.layer_selected = layer
1046 
1047  self.PropertiesDialog (layer)
1048 
1049  if self.GetPyData(layer)[0]['type'] == 'group':
1050  if self.IsExpanded(layer):
1051  self.Collapse(layer)
1052  else:
1053  self.Expand(layer)
1054 
1055  def OnDeleteLayer(self, event):
1056  """!Remove selected layer item from the layer tree"""
1057  self.lmgr.WorkspaceChanged()
1058  item = event.GetItem()
1059 
1060  try:
1061  item.properties.Close(True)
1062  except:
1063  pass
1064 
1065  if item != self.root:
1066  Debug.msg (3, "LayerTree.OnDeleteLayer(): name=%s" % \
1067  (self.GetItemText(item)))
1068  else:
1069  self.root = None
1070 
1071  # unselect item
1072  self.Unselect()
1073  self.layer_selected = None
1074 
1075  try:
1076  if self.GetPyData(item)[0]['type'] != 'group':
1077  self.Map.DeleteLayer( self.GetPyData(item)[0]['maplayer'])
1078  except:
1079  pass
1080 
1081  # redraw map if auto-rendering is enabled
1082  self.rerender = True
1083  self.reorder = True
1084 
1085  if self.mapdisplay.GetToolbar('vdigit'):
1086  self.mapdisplay.toolbars['vdigit'].UpdateListOfLayers (updateTool = True)
1087 
1088  # update progress bar range (mapwindow statusbar)
1089  self.mapdisplay.GetProgressBar().SetRange(len(self.Map.GetListOfLayers(l_active = True)))
1090 
1091  #
1092  # nviz
1093  #
1094  if self.lmgr.IsPaneShown('toolbarNviz') and \
1095  self.GetPyData(item) is not None:
1096  # nviz - load/unload data layer
1097  mapLayer = self.GetPyData(item)[0]['maplayer']
1098  self.mapdisplay.SetStatusText(_("Please wait, updating data..."), 0)
1099  if mapLayer.type == 'raster':
1100  self.mapdisplay.MapWindow.UnloadRaster(item)
1101  elif mapLayer.type == '3d-raster':
1102  self.mapdisplay.MapWindow.UnloadRaster3d(item)
1103  elif mapLayer.type == 'vector':
1104  self.mapdisplay.MapWindow.UnloadVector(item)
1105  self.mapdisplay.SetStatusText("", 0)
1106 
1107  event.Skip()
1108 
1109  def OnLayerChecking(self, event):
1110  """!Layer checkbox is being checked.
1111 
1112  Continue only if mouse is above checkbox or layer was checked programatically.
1113  """
1114  if self.hitCheckbox or self.forceCheck:
1115  self.forceCheck = False
1116  event.Skip()
1117  else:
1118  event.Veto()
1119 
1120  def OnLayerChecked(self, event):
1121  """!Enable/disable data layer"""
1122  self.lmgr.WorkspaceChanged()
1123 
1124  item = event.GetItem()
1125  checked = item.IsChecked()
1126 
1127  digitToolbar = self.mapdisplay.GetToolbar('vdigit')
1128  if not self.first:
1129  # change active parameter for item in layers list in render.Map
1130  if self.GetPyData(item)[0]['type'] == 'group':
1131  child, cookie = self.GetFirstChild(item)
1132  while child:
1133  self.forceCheck = True
1134  self.CheckItem(child, checked)
1135  mapLayer = self.GetPyData(child)[0]['maplayer']
1136  if not digitToolbar or \
1137  (digitToolbar and digitToolbar.GetLayer() != mapLayer):
1138  # ignore when map layer is edited
1139  self.Map.ChangeLayerActive(mapLayer, checked)
1140  child = self.GetNextSibling(child)
1141  else:
1142  mapLayer = self.GetPyData(item)[0]['maplayer']
1143  if not digitToolbar or \
1144  (digitToolbar and digitToolbar.GetLayer() != mapLayer):
1145  # ignore when map layer is edited
1146  self.Map.ChangeLayerActive(mapLayer, checked)
1147 
1148  # update progress bar range (mapwindow statusbar)
1149  self.mapdisplay.GetProgressBar().SetRange(len(self.Map.GetListOfLayers(l_active = True)))
1150 
1151  # nviz
1152  if self.lmgr.IsPaneShown('toolbarNviz') and \
1153  self.GetPyData(item) is not None:
1154  # nviz - load/unload data layer
1155  mapLayer = self.GetPyData(item)[0]['maplayer']
1156 
1157  self.mapdisplay.SetStatusText(_("Please wait, updating data..."), 0)
1158 
1159  if checked: # enable
1160  if mapLayer.type == 'raster':
1161  self.mapdisplay.MapWindow.LoadRaster(item)
1162  elif mapLayer.type == '3d-raster':
1163  self.mapdisplay.MapWindow.LoadRaster3d(item)
1164  elif mapLayer.type == 'vector':
1165  vInfo = gvector.vector_info_topo(mapLayer.GetName())
1166  if (vInfo['points'] + vInfo['centroids']) > 0:
1167  self.mapdisplay.MapWindow.LoadVector(item, points = True)
1168  if (vInfo['lines'] + vInfo['boundaries']) > 0:
1169  self.mapdisplay.MapWindow.LoadVector(item, points = False)
1170 
1171  else: # disable
1172  if mapLayer.type == 'raster':
1173  self.mapdisplay.MapWindow.UnloadRaster(item)
1174  elif mapLayer.type == '3d-raster':
1175  self.mapdisplay.MapWindow.UnloadRaster3d(item)
1176  elif mapLayer.type == 'vector':
1177  self.mapdisplay.MapWindow.UnloadVector(item)
1178 
1179  self.mapdisplay.SetStatusText("", 0)
1180 
1181  # redraw map if auto-rendering is enabled
1182  self.rerender = True
1183  self.reorder = True
1184 
1185  def OnCmdChanged(self, event):
1186  """!Change command string"""
1187  ctrl = event.GetEventObject().GetId()
1188  cmd = event.GetString()
1189 
1190  # find layer tree item by ctrl
1191  layer = self.GetFirstVisibleItem()
1192  while layer and layer.IsOk():
1193  if self.GetPyData(layer)[0]['ctrl'] == ctrl:
1194  break
1195  layer = self.GetNextVisible(layer)
1196 
1197  # change parameters for item in layers list in render.Map
1198  self.ChangeLayer(layer)
1199 
1200  event.Skip()
1201 
1202  def OnMotion(self, event):
1203  """!Mouse is moving.
1204 
1205  Detects if mouse points at checkbox.
1206  """
1207  thisItem, flags = self.HitTest(event.GetPosition())
1208  # workaround: in order not to check checkox when clicking outside
1209  # we need flag TREE_HITTEST_ONITEMCHECKICON but not TREE_HITTEST_ONITEMLABEL
1210  # this applies only for TR_FULL_ROW_HIGHLIGHT style
1211  if (flags & CT.TREE_HITTEST_ONITEMCHECKICON) and not (flags & CT.TREE_HITTEST_ONITEMLABEL):
1212  self.hitCheckbox = True
1213  else:
1214  self.hitCheckbox = False
1215  event.Skip()
1216 
1217  def OnChangingSel(self, event):
1218  """!Selection is changing.
1219 
1220  If the user is clicking on checkbox, selection change is vetoed.
1221  """
1222  if self.hitCheckbox:
1223  event.Veto()
1224 
1225  def OnChangeSel(self, event):
1226  """!Selection changed"""
1227  layer = event.GetItem()
1228  digitToolbar = self.mapdisplay.GetToolbar('vdigit')
1229  if digitToolbar:
1230  mapLayer = self.GetPyData(layer)[0]['maplayer']
1231  bgmap = UserSettings.Get(group = 'vdigit', key = 'bgmap', subkey = 'value',
1232  internal = True)
1233 
1234  if digitToolbar.GetLayer() == mapLayer:
1235  self._setGradient('vdigit')
1236  elif bgmap == mapLayer.GetName():
1237  self._setGradient('bgmap')
1238  else:
1239  self._setGradient()
1240  else:
1241  self._setGradient()
1242 
1243  self.layer_selected = layer
1244 
1245  try:
1246  if self.IsSelected(oldlayer):
1247  self.SetItemWindowEnabled(oldlayer, True)
1248  else:
1249  self.SetItemWindowEnabled(oldlayer, False)
1250 
1251  if self.IsSelected(layer):
1252  self.SetItemWindowEnabled(layer, True)
1253  else:
1254  self.SetItemWindowEnabled(layer, False)
1255  except:
1256  pass
1257 
1258  try:
1259  self.RefreshLine(oldlayer)
1260  self.RefreshLine(layer)
1261  except:
1262  pass
1263 
1264  # update statusbar -> show command string
1265  if self.GetPyData(layer) and self.GetPyData(layer)[0]['maplayer']:
1266  cmd = self.GetPyData(layer)[0]['maplayer'].GetCmd(string = True)
1267  if len(cmd) > 0:
1268  self.lmgr.SetStatusText(cmd)
1269 
1270  # set region if auto-zooming is enabled
1271  if self.GetPyData(layer) and self.GetPyData(layer)[0]['cmd'] and \
1272  UserSettings.Get(group = 'display', key = 'autoZooming', subkey = 'enabled'):
1273  mapLayer = self.GetPyData(layer)[0]['maplayer']
1274  if mapLayer.GetType() in ('raster', 'vector'):
1275  render = self.mapdisplay.IsAutoRendered()
1276  self.mapdisplay.MapWindow.ZoomToMap(layers = [mapLayer,],
1277  render = render)
1278 
1279  # update nviz tools
1280  if self.lmgr.IsPaneShown('toolbarNviz') and \
1281  self.GetPyData(self.layer_selected) is not None:
1282  if self.layer_selected.IsChecked():
1283  # update Nviz tool window
1284  type = self.GetPyData(self.layer_selected)[0]['maplayer'].type
1285 
1286  if type == 'raster':
1287  self.lmgr.nviz.UpdatePage('surface')
1288  self.lmgr.nviz.SetPage('surface')
1289  elif type == 'vector':
1290  self.lmgr.nviz.UpdatePage('vector')
1291  self.lmgr.nviz.SetPage('vector')
1292  elif type == '3d-raster':
1293  self.lmgr.nviz.UpdatePage('volume')
1294  self.lmgr.nviz.SetPage('volume')
1295 
1296  def OnCollapseNode(self, event):
1297  """!Collapse node
1298  """
1299  if self.GetPyData(self.layer_selected)[0]['type'] == 'group':
1300  self.SetItemImage(self.layer_selected, self.folder)
1301 
1302  def OnExpandNode(self, event):
1303  """!Expand node
1304  """
1305  self.layer_selected = event.GetItem()
1306  if self.GetPyData(self.layer_selected)[0]['type'] == 'group':
1307  self.SetItemImage(self.layer_selected, self.folder_open)
1308 
1309  def OnEndDrag(self, event):
1310  self.StopDragging()
1311  dropTarget = event.GetItem()
1312  self.flag = self.HitTest(event.GetPoint())[1]
1313  if self.IsValidDropTarget(dropTarget):
1314  self.UnselectAll()
1315  if dropTarget != None:
1316  self.SelectItem(dropTarget)
1317  self.OnDrop(dropTarget, self._dragItem)
1318  elif dropTarget == None:
1319  self.OnDrop(dropTarget, self._dragItem)
1320 
1321  def OnDrop(self, dropTarget, dragItem):
1322  # save everthing associated with item to drag
1323  try:
1324  old = dragItem # make sure this member exists
1325  except:
1326  return
1327 
1328  Debug.msg (4, "LayerTree.OnDrop(): layer=%s" % \
1329  (self.GetItemText(dragItem)))
1330 
1331  # recreate data layer, insert copy of layer in new position, and delete original at old position
1332  newItem = self.RecreateItem (dragItem, dropTarget)
1333 
1334  # if recreated layer is a group, also recreate its children
1335  if self.GetPyData(newItem)[0]['type'] == 'group':
1336  (child, cookie) = self.GetFirstChild(dragItem)
1337  if child:
1338  while child:
1339  self.RecreateItem(child, dropTarget, parent = newItem)
1340  self.Delete(child)
1341  child = self.GetNextChild(old, cookie)[0]
1342 
1343  # delete layer at original position
1344  try:
1345  self.Delete(old) # entry in render.Map layers list automatically deleted by OnDeleteLayer handler
1346  except AttributeError:
1347  pass
1348 
1349  # redraw map if auto-rendering is enabled
1350  self.rerender = True
1351  self.reorder = True
1352 
1353  # select new item
1354  self.SelectItem(newItem)
1355 
1356  def RecreateItem (self, dragItem, dropTarget, parent = None):
1357  """!Recreate item (needed for OnEndDrag())
1358  """
1359  Debug.msg (4, "LayerTree.RecreateItem(): layer=%s" % \
1360  self.GetItemText(dragItem))
1361 
1362  # fetch data (dragItem)
1363  checked = self.IsItemChecked(dragItem)
1364  image = self.GetItemImage(dragItem, 0)
1365  text = self.GetItemText(dragItem)
1366 
1367  if self.GetPyData(dragItem)[0]['type'] == 'command':
1368  # recreate command layer
1369  newctrl = self._createCommandCtrl()
1370  try:
1371  newctrl.SetValue(self.GetPyData(dragItem)[0]['maplayer'].GetCmd(string = True))
1372  except:
1373  pass
1374  newctrl.Bind(wx.EVT_TEXT_ENTER, self.OnCmdChanged)
1375  data = self.GetPyData(dragItem)
1376 
1377  elif self.GetPyData(dragItem)[0]['ctrl']:
1378  # recreate data layer
1379  btnbmp = LMIcons["layerOptions"].GetBitmap((16,16))
1380  newctrl = buttons.GenBitmapButton(self, id = wx.ID_ANY, bitmap = btnbmp, size = (24, 24))
1381  newctrl.SetToolTipString(_("Click to edit layer settings"))
1382  self.Bind(wx.EVT_BUTTON, self.OnLayerContextMenu, newctrl)
1383  data = self.GetPyData(dragItem)
1384 
1385  elif self.GetPyData(dragItem)[0]['type'] == 'group':
1386  # recreate group
1387  newctrl = None
1388  data = None
1389 
1390  # decide where to put recreated item
1391  if dropTarget != None and dropTarget != self.GetRootItem():
1392  if parent:
1393  # new item is a group
1394  afteritem = parent
1395  else:
1396  # new item is a single layer
1397  afteritem = dropTarget
1398 
1399  # dragItem dropped on group
1400  if self.GetPyData(afteritem)[0]['type'] == 'group':
1401  newItem = self.PrependItem(afteritem, text = text, \
1402  ct_type = 1, wnd = newctrl, image = image, \
1403  data = data)
1404  self.Expand(afteritem)
1405  else:
1406  #dragItem dropped on single layer
1407  newparent = self.GetItemParent(afteritem)
1408  newItem = self.InsertItem(newparent, self.GetPrevSibling(afteritem), \
1409  text = text, ct_type = 1, wnd = newctrl, \
1410  image = image, data = data)
1411  else:
1412  # if dragItem not dropped on a layer or group, append or prepend it to the layer tree
1413  if self.flag & wx.TREE_HITTEST_ABOVE:
1414  newItem = self.PrependItem(self.root, text = text, \
1415  ct_type = 1, wnd = newctrl, image = image, \
1416  data = data)
1417  elif (self.flag & wx.TREE_HITTEST_BELOW) or (self.flag & wx.TREE_HITTEST_NOWHERE) \
1418  or (self.flag & wx.TREE_HITTEST_TOLEFT) or (self.flag & wx.TREE_HITTEST_TORIGHT):
1419  newItem = self.AppendItem(self.root, text = text, \
1420  ct_type = 1, wnd = newctrl, image = image, \
1421  data = data)
1422 
1423  #update new layer
1424  self.SetPyData(newItem, self.GetPyData(dragItem))
1425  if newctrl:
1426  self.GetPyData(newItem)[0]['ctrl'] = newctrl.GetId()
1427  else:
1428  self.GetPyData(newItem)[0]['ctrl'] = None
1429 
1430  self.forceCheck = True
1431  self.CheckItem(newItem, checked = checked) # causes a new render
1432 
1433  return newItem
1434 
1435  def _getLayerName(self, item, lname = ''):
1436  """!Get layer name string
1437 
1438  @param lname optional layer name
1439  """
1440  mapLayer = self.GetPyData(item)[0]['maplayer']
1441  if not lname:
1442  lname = self.GetPyData(item)[0]['label']
1443  opacity = int(mapLayer.GetOpacity(float = True) * 100)
1444  if not lname:
1445  dcmd = self.GetPyData(item)[0]['cmd']
1446  lname, found = GetLayerNameFromCmd(dcmd, layerType = mapLayer.GetType(),
1447  fullyQualified = True)
1448  if not found:
1449  return None
1450 
1451  if opacity < 100:
1452  return lname + ' (%s %d' % (_('opacity:'), opacity) + '%)'
1453 
1454  return lname
1455 
1456  def GetOptData(self, dcmd, layer, params, propwin):
1457  """!Process layer data (when changes in propertiesdialog are applied)"""
1458  # set layer text to map name
1459  if dcmd:
1460  self.GetPyData(layer)[0]['cmd'] = dcmd
1461  mapText = self._getLayerName(layer)
1462  mapName, found = GetLayerNameFromCmd(dcmd)
1463  mapLayer = self.GetPyData(layer)[0]['maplayer']
1464  self.SetItemText(layer, mapName)
1465 
1466  if not mapText or not found:
1467  propwin.Hide()
1468  GWarning(parent = self,
1469  message = _("Map <%s> not found.") % mapName)
1470  return
1471 
1472  # update layer data
1473  if params:
1474  self.SetPyData(layer, (self.GetPyData(layer)[0], params))
1475  self.GetPyData(layer)[0]['propwin'] = propwin
1476 
1477  # change parameters for item in layers list in render.Map
1478  self.ChangeLayer(layer)
1479 
1480  # set region if auto-zooming is enabled
1481  if dcmd and UserSettings.Get(group = 'display', key = 'autoZooming', subkey = 'enabled'):
1482  mapLayer = self.GetPyData(layer)[0]['maplayer']
1483  if mapLayer.GetType() in ('raster', 'vector'):
1484  render = UserSettings.Get(group = 'display', key = 'autoRendering', subkey = 'enabled')
1485  self.mapdisplay.MapWindow.ZoomToMap(layers = [mapLayer,],
1486  render = render)
1487 
1488  # update nviz session
1489  if self.lmgr.IsPaneShown('toolbarNviz') and dcmd:
1490  mapLayer = self.GetPyData(layer)[0]['maplayer']
1491  mapWin = self.mapdisplay.MapWindow
1492  if len(mapLayer.GetCmd()) > 0:
1493  id = -1
1494  if mapLayer.type == 'raster':
1495  if mapWin.IsLoaded(layer):
1496  mapWin.UnloadRaster(layer)
1497 
1498  mapWin.LoadRaster(layer)
1499 
1500  elif mapLayer.type == '3d-raster':
1501  if mapWin.IsLoaded(layer):
1502  mapWin.UnloadRaster3d(layer)
1503 
1504  mapWin.LoadRaster3d(layer)
1505 
1506  elif mapLayer.type == 'vector':
1507  if mapWin.IsLoaded(layer):
1508  mapWin.UnloadVector(layer)
1509 
1510  mapWin.LoadVector(layer)
1511 
1512  # reset view when first layer loaded
1513  nlayers = len(mapWin.Map.GetListOfLayers(l_type = ('raster', '3d-raster', 'vector'),
1514  l_active = True))
1515  if nlayers < 2:
1516  mapWin.ResetView()
1517 
1518  def ReorderLayers(self):
1519  """!Add commands from data associated with any valid layers
1520  (checked or not) to layer list in order to match layers in
1521  layer tree."""
1522 
1523  # make a list of visible layers
1524  treelayers = []
1525 
1526  vislayer = self.GetFirstVisibleItem()
1527 
1528  if not vislayer or self.GetPyData(vislayer) is None:
1529  return
1530 
1531  itemList = ""
1532 
1533  for item in range(self.GetCount()):
1534  itemList += self.GetItemText(vislayer) + ','
1535  if self.GetPyData(vislayer)[0]['type'] != 'group':
1536  treelayers.append(self.GetPyData(vislayer)[0]['maplayer'])
1537 
1538  if not self.GetNextVisible(vislayer):
1539  break
1540  else:
1541  vislayer = self.GetNextVisible(vislayer)
1542 
1543  Debug.msg (4, "LayerTree.ReorderLayers(): items=%s" % \
1544  (itemList))
1545 
1546  # reorder map layers
1547  treelayers.reverse()
1548  self.Map.ReorderLayers(treelayers)
1549  self.reorder = False
1550 
1551  def ChangeLayer(self, item):
1552  """!Change layer"""
1553  type = self.GetPyData(item)[0]['type']
1554  layerName = None
1555 
1556  if type == 'command':
1557  win = self.FindWindowById(self.GetPyData(item)[0]['ctrl'])
1558  if win.GetValue() != None:
1559  cmd = win.GetValue().split(';')
1560  cmdlist = []
1561  for c in cmd:
1562  cmdlist.append(c.split(' '))
1563  opac = 1.0
1564  chk = self.IsItemChecked(item)
1565  hidden = not self.IsVisible(item)
1566  elif type != 'group':
1567  if self.GetPyData(item)[0] is not None:
1568  cmdlist = self.GetPyData(item)[0]['cmd']
1569  opac = self.GetPyData(item)[0]['maplayer'].GetOpacity(float = True)
1570  chk = self.IsItemChecked(item)
1571  hidden = not self.IsVisible(item)
1572  # determine layer name
1573  layerName, found = GetLayerNameFromCmd(cmdlist, fullyQualified = True)
1574  if not found:
1575  layerName = self.GetItemText(item)
1576 
1577  maplayer = self.Map.ChangeLayer(layer = self.GetPyData(item)[0]['maplayer'], type = type,
1578  command = cmdlist, name = layerName,
1579  l_active = chk, l_hidden = hidden, l_opacity = opac, l_render = False)
1580 
1581  self.GetPyData(item)[0]['maplayer'] = maplayer
1582 
1583  # if digitization tool enabled -> update list of available vector map layers
1584  if self.mapdisplay.GetToolbar('vdigit'):
1585  self.mapdisplay.GetToolbar('vdigit').UpdateListOfLayers(updateTool = True)
1586 
1587  # redraw map if auto-rendering is enabled
1588  self.rerender = self.reorder = True
1589 
1590  def OnCloseWindow(self, event):
1591  pass
1592  # self.Map.Clean()
1593 
1594  def FindItemByData(self, key, value):
1595  """!Find item based on key and value (see PyData[0])
1596 
1597  @return item instance
1598  @return None not found
1599  """
1600  item = self.GetFirstChild(self.root)[0]
1601  return self.__FindSubItemByData(item, key, value)
1602 
1603  def FindItemByIndex(self, index):
1604  """!Find item by index (starting at 0)
1605 
1606  @return item instance
1607  @return None not found
1608  """
1609  item = self.GetFirstChild(self.root)[0]
1610  i = 0
1611  while item and item.IsOk():
1612  if i == index:
1613  return item
1614 
1615  item = self.GetNextVisible(item)
1616  i += 1
1617 
1618  return None
1619 
1620  def EnableItemType(self, type, enable = True):
1621  """!Enable/disable items in layer tree"""
1622  item = self.GetFirstChild(self.root)[0]
1623  while item and item.IsOk():
1624  mapLayer = self.GetPyData(item)[0]['maplayer']
1625  if mapLayer and type == mapLayer.type:
1626  self.EnableItem(item, enable)
1627 
1628  item = self.GetNextSibling(item)
1629 
1630  def __FindSubItemByData(self, item, key, value):
1631  """!Support method for FindItemByValue"""
1632  while item and item.IsOk():
1633  try:
1634  itemValue = self.GetPyData(item)[0][key]
1635  except KeyError:
1636  return None
1637 
1638  if value == itemValue:
1639  return item
1640  if self.GetPyData(item)[0]['type'] == 'group':
1641  subItem = self.GetFirstChild(item)[0]
1642  found = self.__FindSubItemByData(subItem, key, value)
1643  if found:
1644  return found
1645  item = self.GetNextSibling(item)
1646 
1647  return None
1648 
1649  def _createCommandCtrl(self):
1650  """!Creates text control for command layer"""
1651  height = 25
1652  if sys.platform in ('win32', 'darwin'):
1653  height = 40
1654  ctrl = wx.TextCtrl(self, id = wx.ID_ANY, value = '',
1655  size = (self.GetSize()[0]-100, height),
1656  style = wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP)
1657  return ctrl
def OnProfile(self, event)
Plot profile of given raster map layer.
Definition: layertree.py:549
wxGUI command interface
def _setGradient
Set gradient for items.
Definition: layertree.py:246
def OnCmdChanged(self, event)
Change command string.
Definition: layertree.py:1185
def OnSetCompRegFromRaster(self, event)
Set computational region from selected raster map (ignore NULLs)
Definition: layertree.py:505
def GetMapDisplay(self)
Get associated MapFrame.
Definition: layertree.py:281
def OnUnivariateStats(self, event)
Univariate raster statistics.
Definition: layertree.py:603
def OnSetBgMap(self, event)
Set background vector map for editing sesstion.
Definition: layertree.py:640
wxGUI debugging
def OnStopEditing(self, event)
Stop editing the current vector map layer.
Definition: layertree.py:628
Creates layer tree structure.
Definition: layertree.py:96
Map display with toolbar for various display management functions, and additional toolbars (vector di...
def ReorderLayers(self)
Add commands from data associated with any valid layers (checked or not) to layer list in order to ma...
Definition: layertree.py:1518
mapdisplay
SetAutoLayout() causes that no vertical scrollbar is displayed when some layers are not visible in la...
Definition: layertree.py:152
def OnLayerChecked(self, event)
Enable/disable data layer.
Definition: layertree.py:1120
def ChangeLayerOpacity(self, layer, value)
Change opacity value of layer.
Definition: layertree.py:682
def GetSelections(self)
Definition: layertree.py:261
def OnRasterColorTable(self, event)
Set color table for raster map.
Definition: layertree.py:572
def RecreateItem
Recreate item (needed for OnEndDrag())
Definition: layertree.py:1356
def OnSetCompRegFromMap(self, event)
Set computational region from selected raster/vector map.
Definition: layertree.py:516
def OnEndDrag(self, event)
Definition: layertree.py:1309
Various dialogs used in wxGUI.
def OnTopology(self, event)
Rebuild topology of selected vector map.
Definition: layertree.py:482
Rendering map layers and overlays into map composition image.
def OnMotion(self, event)
Mouse is moving.
Definition: layertree.py:1202
def OnHistogram(self, event)
Plot histogram for given raster map layer.
Definition: layertree.py:584
def GetMap(self)
Get map instace.
Definition: layertree.py:277
def FindItemByData(self, key, value)
Find item based on key and value (see PyData[0])
Definition: layertree.py:1594
def split(s)
Platform spefic shlex.split.
Definition: core/utils.py:37
def UpdateSettings(self)
Update view from settings values stored in self.mapWindow.view dictionary.
Definition: tools.py:2556
def OnVectorColorTable(self, event)
Set color table for vector map.
Definition: layertree.py:578
def GetLayerNameFromCmd
Get map name from GRASS command.
Definition: core/utils.py:73
Plotting histogram based on d.histogram.
def _createCommandCtrl(self)
Creates text control for command layer.
Definition: layertree.py:1649
def OnDeleteLayer(self, event)
Remove selected layer item from the layer tree.
Definition: layertree.py:1055
def OnActivateLayer(self, event)
Double click on the layer item.
Definition: layertree.py:1039
def OnCloseWindow(self, event)
Definition: layertree.py:1590
def SetRange(self, min, max)
Definition: widgets.py:128
def OnLayerChecking(self, event)
Layer checkbox is being checked.
Definition: layertree.py:1109
def OnChangingSel(self, event)
Selection is changing.
Definition: layertree.py:1217
def OnDrop(self, dropTarget, dragItem)
Definition: layertree.py:1321
Base classes toolbar widgets.
def OnExpandNode(self, event)
Expand node.
Definition: layertree.py:1302
def AddLayer
Add new item to the layer tree, create corresponding MapLayer instance.
Definition: layertree.py:733
def OnRenameLayer(self, event)
Rename layer.
Definition: layertree.py:719
def OnIdle(self, event)
Only re-order and re-render a composite map image from GRASS during idle time instead of multiple tim...
Definition: layertree.py:285
def OnNvizProperties(self, event)
Nviz-related properties (raster/vector/volume)
Definition: layertree.py:705
Misc utilities for wxGUI.
Profiling using PyPlot.
def GetOptData(self, dcmd, layer, params, propwin)
Process layer data (when changes in propertiesdialog are applied)
Definition: layertree.py:1456
def OnRenamed(self, event)
Layer renamed.
Definition: layertree.py:724
def PropertiesDialog
Launch the properties dialog.
Definition: layertree.py:955
def __init__(self, parent, id=wx.ID_ANY, style=wx.SUNKEN_BORDER, ctstyle=CT.TR_HAS_BUTTONS|CT.TR_HAS_VARIABLE_ROW_HEIGHT|CT.TR_HIDE_ROOT|CT.TR_ROW_LINES|CT.TR_FULL_ROW_HIGHLIGHT|CT.TR_MULTIPLE, kwargs)
Definition: layertree.py:103
def OnCollapseNode(self, event)
Collapse node.
Definition: layertree.py:1296
def OnKeyUp(self, event)
Key pressed.
Definition: layertree.py:303
def ChangeLayer(self, item)
Change layer.
Definition: layertree.py:1551
Default GUI settings.
def _getLayerName
Get layer name string.
Definition: layertree.py:1435
def __FindSubItemByData(self, item, key, value)
Support method for FindItemByValue.
Definition: layertree.py:1630
tuple range
Definition: tools.py:1406
def OnApplyLayerOpacity(self, event)
Handles EVT_APPLY_OPACITY event.
Definition: layertree.py:678
def EnableItemType
Enable/disable items in layer tree.
Definition: layertree.py:1620
def OnStartEditing(self, event)
Start editing vector map layer requested by the user.
Definition: layertree.py:608
def OnLayerContextMenu(self, event)
Contextual menu for item/layer.
Definition: layertree.py:313
def OnChangeSel(self, event)
Selection changed.
Definition: layertree.py:1225
def OnMetadata(self, event)
Print metadata of raster/vector map layer TODO: Dialog to modify metadata.
Definition: layertree.py:489
def OnPopupOpacityLevel(self, event)
Popup opacity level indicator.
Definition: layertree.py:661
def FindItemByIndex(self, index)
Find item by index (starting at 0)
Definition: layertree.py:1603
def OnPopupProperties(self, event)
Popup properties dialog.
Definition: layertree.py:657