GRASS Programmer's Manual  6.5.svn(2014)-r66266
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 wx
20 try:
21  import wx.lib.agw.customtreectrl as CT
22 except ImportError:
23  import wx.lib.customtreectrl as CT
24 import wx.lib.buttons as buttons
25 try:
26  import treemixin
27 except ImportError:
28  from wx.lib.mixins import treemixin
29 
30 from grass.script import core as grass
31 from grass.script import vector as gvector
32 
33 from core import globalvar
34 from gui_core.dialogs import SetOpacityDialog, EVT_APPLY_OPACITY
35 from gui_core.forms import GUI
36 from mapdisp.frame import MapFrame
37 from core.render import Map
38 from modules.histogram import HistogramFrame
39 from core.utils import GetLayerNameFromCmd
40 from wxplot.profile import ProfileFrame
41 from core.debug import Debug
42 from core.settings import UserSettings
43 from core.gcmd import GWarning
44 from gui_core.toolbars import BaseIcons
45 from icons.icon import MetaIcon
46 from modules.colorrules import RasterColorTable
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.displayIndex = 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.displayIndex + 1) * 25, (self.displayIndex + 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.displayIndex + 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  ctable = RasterColorTable(self, layerTree = self)
576  ctable.SetMap(name)
577  ctable.Show()
578  ctable.CentreOnScreen()
579 
580  def OnVectorColorTable(self, event):
581  """!Set color table for vector map"""
582  name = self.GetPyData(self.layer_selected)[0]['maplayer'].GetName()
583  GUI(parent = self, centreOnParent = False).ParseCommand(['v.colors',
584  'map=%s' % name])
585 
586  def OnHistogram(self, event):
587  """!Plot histogram for given raster map layer
588  """
589  mapLayer = self.GetPyData(self.layer_selected)[0]['maplayer']
590  if not mapLayer.GetName():
591  GError(parent = self,
592  message = _("Unable to display histogram of "
593  "raster map. No map name defined."))
594  return
595 
596  win = HistogramFrame(parent = self)
597 
598  win.CentreOnScreen()
599  win.Show()
600  win.SetHistLayer(mapLayer.GetName())
601  win.HistWindow.UpdateHist()
602  win.Refresh()
603  win.Update()
604 
605  def OnUnivariateStats(self, event):
606  """!Univariate raster statistics"""
607  name = self.GetPyData(self.layer_selected)[0]['maplayer'].GetName()
608  self.lmgr.goutput.RunCmd(['r.univar', 'map=%s' % name], switchPage = True)
609 
610  def OnStartEditing(self, event):
611  """!Start editing vector map layer requested by the user
612  """
613  try:
614  maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
615  except:
616  event.Skip()
617  return
618 
619  if not self.mapdisplay.GetToolbar('vdigit'): # enable tool
620  self.mapdisplay.AddToolbar('vdigit')
621 
622  if not self.mapdisplay.toolbars['vdigit']:
623  return
624 
625  self.mapdisplay.toolbars['vdigit'].StartEditing(maplayer)
626 
627  self._setGradient('vdigit')
628  self.RefreshLine(self.layer_selected)
629 
630  def OnStopEditing(self, event):
631  """!Stop editing the current vector map layer
632  """
633  maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
634 
635  self.mapdisplay.toolbars['vdigit'].OnExit()
636  if self.lmgr:
637  self.lmgr.toolbars['tools'].Enable('vdigit', enable = True)
638 
639  self._setGradient()
640  self.RefreshLine(self.layer_selected)
641 
642  def OnSetBgMap(self, event):
643  """!Set background vector map for editing sesstion"""
644  digit = self.mapdisplay.GetWindow().digit
645  if event.IsChecked():
646  mapName = self.GetPyData(self.layer_selected)[0]['maplayer'].GetName()
647  UserSettings.Set(group = 'vdigit', key = 'bgmap', subkey = 'value',
648  value = str(mapName), internal = True)
649  digit.OpenBackgroundMap(mapName)
650  self._setGradient('bgmap')
651  else:
652  UserSettings.Set(group = 'vdigit', key = 'bgmap', subkey = 'value',
653  value = '', internal = True)
654  digit.CloseBackgroundMap()
655  self._setGradient()
656 
657  self.RefreshLine(self.layer_selected)
658 
659  def OnPopupProperties (self, event):
660  """!Popup properties dialog"""
662 
663  def OnPopupOpacityLevel(self, event):
664  """!Popup opacity level indicator"""
665  if not self.GetPyData(self.layer_selected)[0]['ctrl']:
666  return
667 
668  maplayer = self.GetPyData(self.layer_selected)[0]['maplayer']
669  current_opacity = maplayer.GetOpacity()
670 
671  dlg = SetOpacityDialog(self, opacity = current_opacity,
672  title = _("Set opacity of <%s>") % maplayer.GetName())
673  dlg.CentreOnParent()
674  dlg.Bind(EVT_APPLY_OPACITY, self.OnApplyLayerOpacity)
675 
676  if dlg.ShowModal() == wx.ID_OK:
677  self.ChangeLayerOpacity(layer = self.layer_selected, value = dlg.GetOpacity())
678  dlg.Destroy()
679 
680  def OnApplyLayerOpacity(self, event):
681  """!Handles EVT_APPLY_OPACITY event."""
682  self.ChangeLayerOpacity(layer = self.layer_selected, value = event.value)
683 
684  def ChangeLayerOpacity(self, layer, value):
685  """!Change opacity value of layer
686  @param layer layer for which to change (item in layertree)
687  @param value opacity value (float between 0 and 1)
688  """
689  maplayer = self.GetPyData(layer)[0]['maplayer']
690  self.Map.ChangeOpacity(maplayer, value)
691  maplayer.SetOpacity(value)
692  self.SetItemText(layer,
693  self._getLayerName(layer))
694 
695  # vector layer currently edited
696  if self.GetMapDisplay().GetToolbar('vdigit') and \
697  self.GetMapDisplay().GetToolbar('vdigit').GetLayer() == maplayer:
698  alpha = int(value * 255)
699  self.GetMapDisplay().GetWindow().digit.GetDisplay().UpdateSettings(alpha = alpha)
700 
701  # redraw map if auto-rendering is enabled
702  renderVector = False
703  if self.GetMapDisplay().GetToolbar('vdigit'):
704  renderVector = True
705  self.GetMapDisplay().GetWindow().UpdateMap(render = False, renderVector = renderVector)
706 
707  def OnNvizProperties(self, event):
708  """!Nviz-related properties (raster/vector/volume)
709 
710  @todo vector/volume
711  """
712  self.lmgr.notebook.SetSelectionByName('nviz')
713  ltype = self.GetPyData(self.layer_selected)[0]['type']
714  if ltype == 'raster':
715  self.lmgr.nviz.SetPage('surface')
716  elif ltype == 'vector':
717  self.lmgr.nviz.SetPage('vector')
718  elif ltype == '3d-raster':
719  self.lmgr.nviz.SetPage('volume')
720 
721  def OnRenameLayer (self, event):
722  """!Rename layer"""
723  self.EditLabel(self.layer_selected)
724  self.GetEditControl().SetSelection(-1, -1)
725 
726  def OnRenamed(self, event):
727  """!Layer renamed"""
728  item = self.layer_selected
729  self.GetPyData(item)[0]['label'] = event.GetLabel()
730  self.SetItemText(item, self._getLayerName(item)) # not working, why?
731 
732  event.Skip()
733 
734  def AddLayer(self, ltype, lname = None, lchecked = None,
735  lopacity = 1.0, lcmd = None, lgroup = None, lvdigit = None, lnviz = None, multiple = True):
736  """!Add new item to the layer tree, create corresponding MapLayer instance.
737  Launch property dialog if needed (raster, vector, etc.)
738 
739  @param ltype layer type (raster, vector, 3d-raster, ...)
740  @param lname layer name
741  @param lchecked if True layer is checked
742  @param lopacity layer opacity level
743  @param lcmd command (given as a list)
744  @param lgroup index of group item (-1 for root) or None
745  @param lvdigit vector digitizer settings (eg. geometry attributes)
746  @param lnviz layer Nviz properties
747  @param multiple True to allow multiple map layers in layer tree
748  """
749  if lname and not multiple:
750  # check for duplicates
751  item = self.GetFirstVisibleItem()
752  while item and item.IsOk():
753  if self.GetPyData(item)[0]['type'] == 'vector':
754  name = self.GetPyData(item)[0]['maplayer'].GetName()
755  if name == lname:
756  return
757  item = self.GetNextVisible(item)
758 
759  self.first = True
760  params = {} # no initial options parameters
761 
762  # deselect active item
763  if self.layer_selected:
764  self.SelectItem(self.layer_selected, select = False)
765 
766  Debug.msg (3, "LayerTree().AddLayer(): ltype=%s" % (ltype))
767 
768  if ltype == 'command':
769  # generic command item
770  ctrl = wx.TextCtrl(self, id = wx.ID_ANY, value = '',
771  pos = wx.DefaultPosition, size = (self.GetSize()[0]-100,25),
772  # style = wx.TE_MULTILINE|wx.TE_WORDWRAP)
773  style = wx.TE_PROCESS_ENTER | wx.TE_DONTWRAP)
774  ctrl.Bind(wx.EVT_TEXT_ENTER, self.OnCmdChanged)
775  # ctrl.Bind(wx.EVT_TEXT, self.OnCmdChanged)
776  elif ltype == 'group':
777  # group item
778  ctrl = None
779  grouptext = _('Layer group:') + str(self.groupnode)
780  self.groupnode += 1
781  else:
782  btnbmp = LMIcons["layerOptions"].GetBitmap((16,16))
783  ctrl = buttons.GenBitmapButton(self, id = wx.ID_ANY, bitmap = btnbmp, size = (24,24))
784  ctrl.SetToolTipString(_("Click to edit layer settings"))
785  self.Bind(wx.EVT_BUTTON, self.OnLayerContextMenu, ctrl)
786  # add layer to the layer tree
787  if self.layer_selected and self.layer_selected != self.GetRootItem():
788  if self.GetPyData(self.layer_selected)[0]['type'] == 'group' \
789  and self.IsExpanded(self.layer_selected):
790  # add to group (first child of self.layer_selected) if group expanded
791  layer = self.PrependItem(parent = self.layer_selected,
792  text = '', ct_type = 1, wnd = ctrl)
793  else:
794  # prepend to individual layer or non-expanded group
795  if lgroup == -1:
796  # -> last child of root (loading from workspace)
797  layer = self.AppendItem(parentId = self.root,
798  text = '', ct_type = 1, wnd = ctrl)
799  elif lgroup > -1:
800  # -> last child of group (loading from workspace)
801  parent = self.FindItemByIndex(index = lgroup)
802  if not parent:
803  parent = self.root
804  layer = self.AppendItem(parentId = parent,
805  text = '', ct_type = 1, wnd = ctrl)
806  elif lgroup is None:
807  # -> previous sibling of selected layer
808  parent = self.GetItemParent(self.layer_selected)
809  layer = self.InsertItem(parentId = parent,
810  input = self.GetPrevSibling(self.layer_selected),
811  text = '', ct_type = 1, wnd = ctrl)
812  else: # add first layer to the layer tree (first child of root)
813  layer = self.PrependItem(parent = self.root, text = '', ct_type = 1, wnd = ctrl)
814 
815  # layer is initially unchecked as inactive (beside 'command')
816  # use predefined value if given
817  if lchecked is not None:
818  checked = lchecked
819  else:
820  checked = True
821 
822  self.forceCheck = True
823  self.CheckItem(layer, checked = checked)
824 
825  # add text and icons for each layer ltype
826  label = _('(double click to set properties)') + ' ' * 15
827  if ltype == 'raster':
828  self.SetItemImage(layer, self.rast_icon)
829  self.SetItemText(layer, '%s %s' % (_('raster'), label))
830  elif ltype == '3d-raster':
831  self.SetItemImage(layer, self.rast3d_icon)
832  self.SetItemText(layer, '%s %s' % (_('3D raster'), label))
833  elif ltype == 'rgb':
834  self.SetItemImage(layer, self.rgb_icon)
835  self.SetItemText(layer, '%s %s' % (_('RGB'), label))
836  elif ltype == 'his':
837  self.SetItemImage(layer, self.his_icon)
838  self.SetItemText(layer, '%s %s' % (_('HIS'), label))
839  elif ltype == 'shaded':
840  self.SetItemImage(layer, self.shaded_icon)
841  self.SetItemText(layer, '%s %s' % (_('shaded relief'), label))
842  elif ltype == 'rastnum':
843  self.SetItemImage(layer, self.rnum_icon)
844  self.SetItemText(layer, '%s %s' % (_('raster cell numbers'), label))
845  elif ltype == 'rastarrow':
846  self.SetItemImage(layer, self.rarrow_icon)
847  self.SetItemText(layer, '%s %s' % (_('raster flow arrows'), label))
848  elif ltype == 'vector':
849  self.SetItemImage(layer, self.vect_icon)
850  self.SetItemText(layer, '%s %s' % (_('vector'), label))
851  elif ltype == 'thememap':
852  self.SetItemImage(layer, self.theme_icon)
853  self.SetItemText(layer, '%s %s' % (_('thematic map'), label))
854  elif ltype == 'themechart':
855  self.SetItemImage(layer, self.chart_icon)
856  self.SetItemText(layer, '%s %s' % (_('thematic charts'), label))
857  elif ltype == 'grid':
858  self.SetItemImage(layer, self.grid_icon)
859  self.SetItemText(layer, '%s %s' % (_('grid'), label))
860  elif ltype == 'geodesic':
861  self.SetItemImage(layer, self.geodesic_icon)
862  self.SetItemText(layer, '%s %s' % (_('geodesic line'), label))
863  elif ltype == 'rhumb':
864  self.SetItemImage(layer, self.rhumb_icon)
865  self.SetItemText(layer, '%s %s' % (_('rhumbline'), label))
866  elif ltype == 'labels':
867  self.SetItemImage(layer, self.labels_icon)
868  self.SetItemText(layer, '%s %s' % (_('vector labels'), label))
869  elif ltype == 'command':
870  self.SetItemImage(layer, self.cmd_icon)
871  elif ltype == 'group':
872  self.SetItemImage(layer, self.folder)
873  self.SetItemText(layer, grouptext)
874 
875  self.first = False
876 
877  if ltype != 'group':
878  if lcmd and len(lcmd) > 1:
879  cmd = lcmd
880  render = False
881  name, found = GetLayerNameFromCmd(lcmd)
882  else:
883  cmd = []
884  if ltype == 'command' and lname:
885  for c in lname.split(';'):
886  cmd.append(c.split(' '))
887 
888  render = False
889  name = None
890 
891  if ctrl:
892  ctrlId = ctrl.GetId()
893  else:
894  ctrlId = None
895 
896  # add a data object to hold the layer's command (does not apply to generic command layers)
897  self.SetPyData(layer, ({'cmd' : cmd,
898  'type' : ltype,
899  'ctrl' : ctrlId,
900  'label' : None,
901  'maplayer' : None,
902  'vdigit' : lvdigit,
903  'nviz' : lnviz,
904  'propwin' : None},
905  None))
906 
907  # find previous map layer instance
908  prevItem = self.GetFirstChild(self.root)[0]
909  prevMapLayer = None
910  pos = -1
911  while prevItem and prevItem.IsOk() and prevItem != layer:
912  if self.GetPyData(prevItem)[0]['maplayer']:
913  prevMapLayer = self.GetPyData(prevItem)[0]['maplayer']
914 
915  prevItem = self.GetNextSibling(prevItem)
916 
917  if prevMapLayer:
918  pos = self.Map.GetLayerIndex(prevMapLayer)
919  else:
920  pos = -1
921 
922  maplayer = self.Map.AddLayer(pos = pos,
923  type = ltype, command = self.GetPyData(layer)[0]['cmd'], name = name,
924  l_active = checked, l_hidden = False,
925  l_opacity = lopacity, l_render = render)
926  self.GetPyData(layer)[0]['maplayer'] = maplayer
927 
928  # run properties dialog if no properties given
929  if len(cmd) == 0:
930  self.PropertiesDialog(layer, show = True)
931 
932  else: # group
933  self.SetPyData(layer, ({'cmd' : None,
934  'type' : ltype,
935  'ctrl' : None,
936  'label' : None,
937  'maplayer' : None,
938  'propwin' : None},
939  None))
940 
941  # select new item
942  self.SelectItem(layer, select = True)
943  self.layer_selected = layer
944 
945  # use predefined layer name if given
946  if lname:
947  if ltype == 'group':
948  self.SetItemText(layer, lname)
949  elif ltype == 'command':
950  ctrl.SetValue(lname)
951  else:
952  self.SetItemText(layer, self._getLayerName(layer, lname))
953 
954  # updated progress bar range (mapwindow statusbar)
955  if checked is True:
956  self.mapdisplay.GetProgressBar().SetRange(len(self.Map.GetListOfLayers(l_active = True)))
957 
958  return layer
959 
960  def PropertiesDialog(self, layer, show = True):
961  """!Launch the properties dialog"""
962  if 'propwin' in self.GetPyData(layer)[0] and \
963  self.GetPyData(layer)[0]['propwin'] is not None:
964  # recycle GUI dialogs
965  win = self.GetPyData(layer)[0]['propwin']
966  if win.IsShown():
967  win.SetFocus()
968  else:
969  win.Show()
970 
971  return
972 
973  completed = ''
974  params = self.GetPyData(layer)[1]
975  ltype = self.GetPyData(layer)[0]['type']
976 
977  Debug.msg (3, "LayerTree.PropertiesDialog(): ltype=%s" % \
978  ltype)
979 
980  cmd = None
981  if self.GetPyData(layer)[0]['cmd']:
982  module = GUI(parent = self, show = show, centreOnParent = False)
983  module.ParseCommand(self.GetPyData(layer)[0]['cmd'],
984  completed = (self.GetOptData,layer,params))
985 
986  self.GetPyData(layer)[0]['cmd'] = module.GetCmd()
987  elif ltype == 'raster':
988  cmd = ['d.rast']
989  if UserSettings.Get(group='cmd', key='rasterOverlay', subkey='enabled'):
990  cmd.append('-o')
991 
992  elif ltype == '3d-raster':
993  cmd = ['d.rast3d.py']
994 
995  elif ltype == 'rgb':
996  cmd = ['d.rgb']
997  if UserSettings.Get(group='cmd', key='rasterOverlay', subkey='enabled'):
998  cmd.append('-o')
999 
1000  elif ltype == 'his':
1001  cmd = ['d.his']
1002 
1003  elif ltype == 'shaded':
1004  cmd = ['d.shadedmap']
1005 
1006  elif ltype == 'rastarrow':
1007  cmd = ['d.rast.arrow']
1008 
1009  elif ltype == 'rastnum':
1010  cmd = ['d.rast.num']
1011 
1012  elif ltype == 'vector':
1013  types = list()
1014  for ftype in ['point', 'line', 'boundary', 'centroid', 'area', 'face']:
1015  if UserSettings.Get(group = 'cmd', key = 'showType', subkey = [ftype, 'enabled']):
1016  types.append(ftype)
1017 
1018  cmd = ['d.vect', 'type=%s' % ','.join(types)]
1019 
1020  elif ltype == 'thememap':
1021  # -s flag requested, otherwise only first thematic category is displayed
1022  # should be fixed by C-based d.thematic.* modules
1023  cmd = ['d.vect.thematic', '-s']
1024 
1025  elif ltype == 'themechart':
1026  cmd = ['d.vect.chart']
1027 
1028  elif ltype == 'grid':
1029  cmd = ['d.grid']
1030 
1031  elif ltype == 'geodesic':
1032  cmd = ['d.geodesic']
1033 
1034  elif ltype == 'rhumb':
1035  cmd = ['d.rhumbline']
1036 
1037  elif ltype == 'labels':
1038  cmd = ['d.labels']
1039 
1040  if cmd:
1041  GUI(parent = self, centreOnParent = False).ParseCommand(cmd,
1042  completed = (self.GetOptData,layer,params))
1043 
1044  def OnActivateLayer(self, event):
1045  """!Double click on the layer item.
1046  Launch property dialog, or expand/collapse group of items, etc.
1047  """
1048  self.lmgr.WorkspaceChanged()
1049  layer = event.GetItem()
1050  self.layer_selected = layer
1051 
1052  self.PropertiesDialog (layer)
1053 
1054  if self.GetPyData(layer)[0]['type'] == 'group':
1055  if self.IsExpanded(layer):
1056  self.Collapse(layer)
1057  else:
1058  self.Expand(layer)
1059 
1060  def OnDeleteLayer(self, event):
1061  """!Remove selected layer item from the layer tree"""
1062  self.lmgr.WorkspaceChanged()
1063  item = event.GetItem()
1064 
1065  try:
1066  item.properties.Close(True)
1067  except:
1068  pass
1069 
1070  if item != self.root:
1071  Debug.msg (3, "LayerTree.OnDeleteLayer(): name=%s" % \
1072  (self.GetItemText(item)))
1073  else:
1074  self.root = None
1075 
1076  # unselect item
1077  self.Unselect()
1078  self.layer_selected = None
1079 
1080  try:
1081  if self.GetPyData(item)[0]['type'] != 'group':
1082  self.Map.DeleteLayer( self.GetPyData(item)[0]['maplayer'])
1083  except:
1084  pass
1085 
1086  # redraw map if auto-rendering is enabled
1087  self.rerender = True
1088  self.reorder = True
1089 
1090  if self.mapdisplay.GetToolbar('vdigit'):
1091  self.mapdisplay.toolbars['vdigit'].UpdateListOfLayers (updateTool = True)
1092 
1093  # update progress bar range (mapwindow statusbar)
1094  self.mapdisplay.GetProgressBar().SetRange(len(self.Map.GetListOfLayers(l_active = True)))
1095 
1096  #
1097  # nviz
1098  #
1099  if self.lmgr.IsPaneShown('toolbarNviz') and \
1100  self.GetPyData(item) is not None:
1101  # nviz - load/unload data layer
1102  mapLayer = self.GetPyData(item)[0]['maplayer']
1103  self.mapdisplay.SetStatusText(_("Please wait, updating data..."), 0)
1104  if mapLayer.type == 'raster':
1105  self.mapdisplay.MapWindow.UnloadRaster(item)
1106  elif mapLayer.type == '3d-raster':
1107  self.mapdisplay.MapWindow.UnloadRaster3d(item)
1108  elif mapLayer.type == 'vector':
1109  self.mapdisplay.MapWindow.UnloadVector(item)
1110  self.mapdisplay.SetStatusText("", 0)
1111 
1112  event.Skip()
1113 
1114  def OnLayerChecking(self, event):
1115  """!Layer checkbox is being checked.
1116 
1117  Continue only if mouse is above checkbox or layer was checked programatically.
1118  """
1119  if self.hitCheckbox or self.forceCheck:
1120  self.forceCheck = False
1121  event.Skip()
1122  else:
1123  event.Veto()
1124 
1125  def OnLayerChecked(self, event):
1126  """!Enable/disable data layer"""
1127  self.lmgr.WorkspaceChanged()
1128 
1129  item = event.GetItem()
1130  checked = item.IsChecked()
1131 
1132  digitToolbar = self.mapdisplay.GetToolbar('vdigit')
1133  if not self.first:
1134  # change active parameter for item in layers list in render.Map
1135  if self.GetPyData(item)[0]['type'] == 'group':
1136  child, cookie = self.GetFirstChild(item)
1137  while child:
1138  self.forceCheck = True
1139  self.CheckItem(child, checked)
1140  mapLayer = self.GetPyData(child)[0]['maplayer']
1141  if not digitToolbar or \
1142  (digitToolbar and digitToolbar.GetLayer() != mapLayer):
1143  # ignore when map layer is edited
1144  self.Map.ChangeLayerActive(mapLayer, checked)
1145  child = self.GetNextSibling(child)
1146  else:
1147  mapLayer = self.GetPyData(item)[0]['maplayer']
1148  if not digitToolbar or \
1149  (digitToolbar and digitToolbar.GetLayer() != mapLayer):
1150  # ignore when map layer is edited
1151  self.Map.ChangeLayerActive(mapLayer, checked)
1152 
1153  # update progress bar range (mapwindow statusbar)
1154  self.mapdisplay.GetProgressBar().SetRange(len(self.Map.GetListOfLayers(l_active = True)))
1155 
1156  # nviz
1157  if self.lmgr.IsPaneShown('toolbarNviz') and \
1158  self.GetPyData(item) is not None:
1159  # nviz - load/unload data layer
1160  mapLayer = self.GetPyData(item)[0]['maplayer']
1161 
1162  self.mapdisplay.SetStatusText(_("Please wait, updating data..."), 0)
1163 
1164  if checked: # enable
1165  if mapLayer.type == 'raster':
1166  self.mapdisplay.MapWindow.LoadRaster(item)
1167  elif mapLayer.type == '3d-raster':
1168  self.mapdisplay.MapWindow.LoadRaster3d(item)
1169  elif mapLayer.type == 'vector':
1170  vInfo = gvector.vector_info_topo(mapLayer.GetName())
1171  if (vInfo['points'] + vInfo['centroids']) > 0:
1172  self.mapdisplay.MapWindow.LoadVector(item, points = True)
1173  if (vInfo['lines'] + vInfo['boundaries']) > 0:
1174  self.mapdisplay.MapWindow.LoadVector(item, points = False)
1175 
1176  else: # disable
1177  if mapLayer.type == 'raster':
1178  self.mapdisplay.MapWindow.UnloadRaster(item)
1179  elif mapLayer.type == '3d-raster':
1180  self.mapdisplay.MapWindow.UnloadRaster3d(item)
1181  elif mapLayer.type == 'vector':
1182  self.mapdisplay.MapWindow.UnloadVector(item)
1183 
1184  self.mapdisplay.SetStatusText("", 0)
1185 
1186  # redraw map if auto-rendering is enabled
1187  self.rerender = True
1188  self.reorder = True
1189 
1190  def OnCmdChanged(self, event):
1191  """!Change command string"""
1192  ctrl = event.GetEventObject().GetId()
1193  cmd = event.GetString()
1194 
1195  # find layer tree item by ctrl
1196  layer = self.GetFirstVisibleItem()
1197  while layer and layer.IsOk():
1198  if self.GetPyData(layer)[0]['ctrl'] == ctrl:
1199  break
1200  layer = self.GetNextVisible(layer)
1201 
1202  # change parameters for item in layers list in render.Map
1203  self.ChangeLayer(layer)
1204 
1205  event.Skip()
1206 
1207  def OnMotion(self, event):
1208  """!Mouse is moving.
1209 
1210  Detects if mouse points at checkbox.
1211  """
1212  thisItem, flags = self.HitTest(event.GetPosition())
1213  # workaround: in order not to check checkox when clicking outside
1214  # we need flag TREE_HITTEST_ONITEMCHECKICON but not TREE_HITTEST_ONITEMLABEL
1215  # this applies only for TR_FULL_ROW_HIGHLIGHT style
1216  if (flags & CT.TREE_HITTEST_ONITEMCHECKICON) and not (flags & CT.TREE_HITTEST_ONITEMLABEL):
1217  self.hitCheckbox = True
1218  else:
1219  self.hitCheckbox = False
1220  event.Skip()
1221 
1222  def OnChangingSel(self, event):
1223  """!Selection is changing.
1224 
1225  If the user is clicking on checkbox, selection change is vetoed.
1226  """
1227  if self.hitCheckbox:
1228  event.Veto()
1229 
1230  def OnChangeSel(self, event):
1231  """!Selection changed"""
1232  layer = event.GetItem()
1233  digitToolbar = self.mapdisplay.GetToolbar('vdigit')
1234  if digitToolbar:
1235  mapLayer = self.GetPyData(layer)[0]['maplayer']
1236  bgmap = UserSettings.Get(group = 'vdigit', key = 'bgmap', subkey = 'value',
1237  internal = True)
1238 
1239  if digitToolbar.GetLayer() == mapLayer:
1240  self._setGradient('vdigit')
1241  elif bgmap == mapLayer.GetName():
1242  self._setGradient('bgmap')
1243  else:
1244  self._setGradient()
1245  else:
1246  self._setGradient()
1247 
1248  self.layer_selected = layer
1249 
1250  try:
1251  if self.IsSelected(oldlayer):
1252  self.SetItemWindowEnabled(oldlayer, True)
1253  else:
1254  self.SetItemWindowEnabled(oldlayer, False)
1255 
1256  if self.IsSelected(layer):
1257  self.SetItemWindowEnabled(layer, True)
1258  else:
1259  self.SetItemWindowEnabled(layer, False)
1260  except:
1261  pass
1262 
1263  try:
1264  self.RefreshLine(oldlayer)
1265  self.RefreshLine(layer)
1266  except:
1267  pass
1268 
1269  # update statusbar -> show command string
1270  if self.GetPyData(layer) and self.GetPyData(layer)[0]['maplayer']:
1271  cmd = self.GetPyData(layer)[0]['maplayer'].GetCmd(string = True)
1272  if len(cmd) > 0:
1273  self.lmgr.SetStatusText(cmd)
1274 
1275  # set region if auto-zooming is enabled
1276  if self.GetPyData(layer) and self.GetPyData(layer)[0]['cmd'] and \
1277  UserSettings.Get(group = 'display', key = 'autoZooming', subkey = 'enabled'):
1278  mapLayer = self.GetPyData(layer)[0]['maplayer']
1279  if mapLayer.GetType() in ('raster', 'vector'):
1280  render = self.mapdisplay.IsAutoRendered()
1281  self.mapdisplay.MapWindow.ZoomToMap(layers = [mapLayer,],
1282  render = render)
1283 
1284  # update nviz tools
1285  if self.lmgr.IsPaneShown('toolbarNviz') and \
1286  self.GetPyData(self.layer_selected) is not None:
1287  if self.layer_selected.IsChecked():
1288  # update Nviz tool window
1289  type = self.GetPyData(self.layer_selected)[0]['maplayer'].type
1290 
1291  if type == 'raster':
1292  self.lmgr.nviz.UpdatePage('surface')
1293  self.lmgr.nviz.SetPage('surface')
1294  elif type == 'vector':
1295  self.lmgr.nviz.UpdatePage('vector')
1296  self.lmgr.nviz.SetPage('vector')
1297  elif type == '3d-raster':
1298  self.lmgr.nviz.UpdatePage('volume')
1299  self.lmgr.nviz.SetPage('volume')
1300 
1301  def OnCollapseNode(self, event):
1302  """!Collapse node
1303  """
1304  if self.GetPyData(self.layer_selected)[0]['type'] == 'group':
1305  self.SetItemImage(self.layer_selected, self.folder)
1306 
1307  def OnExpandNode(self, event):
1308  """!Expand node
1309  """
1310  self.layer_selected = event.GetItem()
1311  if self.GetPyData(self.layer_selected)[0]['type'] == 'group':
1312  self.SetItemImage(self.layer_selected, self.folder_open)
1313 
1314  def OnEndDrag(self, event):
1315  self.StopDragging()
1316  dropTarget = event.GetItem()
1317  self.flag = self.HitTest(event.GetPoint())[1]
1318  if self.IsValidDropTarget(dropTarget):
1319  self.UnselectAll()
1320  if dropTarget != None:
1321  self.SelectItem(dropTarget)
1322  self.OnDrop(dropTarget, self._dragItem)
1323  elif dropTarget == None:
1324  self.OnDrop(dropTarget, self._dragItem)
1325 
1326  def OnDrop(self, dropTarget, dragItem):
1327  # save everthing associated with item to drag
1328  try:
1329  old = dragItem # make sure this member exists
1330  except:
1331  return
1332 
1333  Debug.msg (4, "LayerTree.OnDrop(): layer=%s" % \
1334  (self.GetItemText(dragItem)))
1335 
1336  # recreate data layer, insert copy of layer in new position, and delete original at old position
1337  newItem = self.RecreateItem (dragItem, dropTarget)
1338 
1339  # if recreated layer is a group, also recreate its children
1340  if self.GetPyData(newItem)[0]['type'] == 'group':
1341  (child, cookie) = self.GetFirstChild(dragItem)
1342  if child:
1343  while child:
1344  self.RecreateItem(child, dropTarget, parent = newItem)
1345  self.Delete(child)
1346  child = self.GetNextChild(old, cookie)[0]
1347 
1348  # delete layer at original position
1349  try:
1350  self.Delete(old) # entry in render.Map layers list automatically deleted by OnDeleteLayer handler
1351  except AttributeError:
1352  pass
1353 
1354  # redraw map if auto-rendering is enabled
1355  self.rerender = True
1356  self.reorder = True
1357 
1358  # select new item
1359  self.SelectItem(newItem)
1360 
1361  def RecreateItem (self, dragItem, dropTarget, parent = None):
1362  """!Recreate item (needed for OnEndDrag())
1363  """
1364  Debug.msg (4, "LayerTree.RecreateItem(): layer=%s" % \
1365  self.GetItemText(dragItem))
1366 
1367  # fetch data (dragItem)
1368  checked = self.IsItemChecked(dragItem)
1369  image = self.GetItemImage(dragItem, 0)
1370  text = self.GetItemText(dragItem)
1371  if self.GetPyData(dragItem)[0]['ctrl']:
1372  # recreate data layer
1373  btnbmp = LMIcons["layerOptions"].GetBitmap((16,16))
1374  newctrl = buttons.GenBitmapButton(self, id = wx.ID_ANY, bitmap = btnbmp, size = (24, 24))
1375  newctrl.SetToolTipString(_("Click to edit layer settings"))
1376  self.Bind(wx.EVT_BUTTON, self.OnLayerContextMenu, newctrl)
1377  data = self.GetPyData(dragItem)
1378 
1379  elif self.GetPyData(dragItem)[0]['type'] == 'command':
1380  # recreate command layer
1381  oldctrl = None
1382  newctrl = wx.TextCtrl(self, id = wx.ID_ANY, value = '',
1383  pos = wx.DefaultPosition, size = (250,25),
1384  style = wx.TE_MULTILINE|wx.TE_WORDWRAP)
1385  try:
1386  newctrl.SetValue(self.GetPyData(dragItem)[0]['maplayer'].GetCmd(string = True))
1387  except:
1388  pass
1389  newctrl.Bind(wx.EVT_TEXT_ENTER, self.OnCmdChanged)
1390  newctrl.Bind(wx.EVT_TEXT, self.OnCmdChanged)
1391  data = self.GetPyData(dragItem)
1392 
1393  elif self.GetPyData(dragItem)[0]['type'] == 'group':
1394  # recreate group
1395  newctrl = None
1396  data = None
1397 
1398  # decide where to put recreated item
1399  if dropTarget != None and dropTarget != self.GetRootItem():
1400  if parent:
1401  # new item is a group
1402  afteritem = parent
1403  else:
1404  # new item is a single layer
1405  afteritem = dropTarget
1406 
1407  # dragItem dropped on group
1408  if self.GetPyData(afteritem)[0]['type'] == 'group':
1409  newItem = self.PrependItem(afteritem, text = text, \
1410  ct_type = 1, wnd = newctrl, image = image, \
1411  data = data)
1412  self.Expand(afteritem)
1413  else:
1414  #dragItem dropped on single layer
1415  newparent = self.GetItemParent(afteritem)
1416  newItem = self.InsertItem(newparent, self.GetPrevSibling(afteritem), \
1417  text = text, ct_type = 1, wnd = newctrl, \
1418  image = image, data = data)
1419  else:
1420  # if dragItem not dropped on a layer or group, append or prepend it to the layer tree
1421  if self.flag & wx.TREE_HITTEST_ABOVE:
1422  newItem = self.PrependItem(self.root, text = text, \
1423  ct_type = 1, wnd = newctrl, image = image, \
1424  data = data)
1425  elif (self.flag & wx.TREE_HITTEST_BELOW) or (self.flag & wx.TREE_HITTEST_NOWHERE) \
1426  or (self.flag & wx.TREE_HITTEST_TOLEFT) or (self.flag & wx.TREE_HITTEST_TORIGHT):
1427  newItem = self.AppendItem(self.root, text = text, \
1428  ct_type = 1, wnd = newctrl, image = image, \
1429  data = data)
1430 
1431  #update new layer
1432  self.SetPyData(newItem, self.GetPyData(dragItem))
1433  if newctrl:
1434  self.GetPyData(newItem)[0]['ctrl'] = newctrl.GetId()
1435  else:
1436  self.GetPyData(newItem)[0]['ctrl'] = None
1437 
1438  self.forceCheck = True
1439  self.CheckItem(newItem, checked = checked) # causes a new render
1440 
1441  return newItem
1442 
1443  def _getLayerName(self, item, lname = ''):
1444  """!Get layer name string
1445 
1446  @param lname optional layer name
1447  """
1448  mapLayer = self.GetPyData(item)[0]['maplayer']
1449  if not lname:
1450  lname = self.GetPyData(item)[0]['label']
1451  opacity = int(mapLayer.GetOpacity(float = True) * 100)
1452  if not lname:
1453  dcmd = self.GetPyData(item)[0]['cmd']
1454  lname, found = GetLayerNameFromCmd(dcmd, layerType = mapLayer.GetType(),
1455  fullyQualified = True)
1456  if not found:
1457  return None
1458 
1459  if opacity < 100:
1460  return lname + ' (%s %d' % (_('opacity:'), opacity) + '%)'
1461 
1462  return lname
1463 
1464  def GetOptData(self, dcmd, layer, params, propwin):
1465  """!Process layer data (when changes in propertiesdialog are applied)"""
1466  # set layer text to map name
1467  if dcmd:
1468  self.GetPyData(layer)[0]['cmd'] = dcmd
1469  mapText = self._getLayerName(layer)
1470  mapName, found = GetLayerNameFromCmd(dcmd)
1471  mapLayer = self.GetPyData(layer)[0]['maplayer']
1472  self.SetItemText(layer, mapName)
1473 
1474  if not mapText or not found:
1475  propwin.Hide()
1476  GWarning(parent = self,
1477  message = _("Map <%s> not found.") % mapName)
1478  return
1479 
1480  # update layer data
1481  if params:
1482  self.SetPyData(layer, (self.GetPyData(layer)[0], params))
1483  self.GetPyData(layer)[0]['propwin'] = propwin
1484 
1485  # change parameters for item in layers list in render.Map
1486  self.ChangeLayer(layer)
1487 
1488  # set region if auto-zooming is enabled
1489  if dcmd and UserSettings.Get(group = 'display', key = 'autoZooming', subkey = 'enabled'):
1490  mapLayer = self.GetPyData(layer)[0]['maplayer']
1491  if mapLayer.GetType() in ('raster', 'vector'):
1492  render = UserSettings.Get(group = 'display', key = 'autoRendering', subkey = 'enabled')
1493  self.mapdisplay.MapWindow.ZoomToMap(layers = [mapLayer,],
1494  render = render)
1495 
1496  # update nviz session
1497  if self.lmgr.IsPaneShown('toolbarNviz') and dcmd:
1498  mapLayer = self.GetPyData(layer)[0]['maplayer']
1499  mapWin = self.mapdisplay.MapWindow
1500  if len(mapLayer.GetCmd()) > 0:
1501  id = -1
1502  if mapLayer.type == 'raster':
1503  if mapWin.IsLoaded(layer):
1504  mapWin.UnloadRaster(layer)
1505 
1506  mapWin.LoadRaster(layer)
1507 
1508  elif mapLayer.type == '3d-raster':
1509  if mapWin.IsLoaded(layer):
1510  mapWin.UnloadRaster3d(layer)
1511 
1512  mapWin.LoadRaster3d(layer)
1513 
1514  elif mapLayer.type == 'vector':
1515  if mapWin.IsLoaded(layer):
1516  mapWin.UnloadVector(layer)
1517 
1518  mapWin.LoadVector(layer)
1519 
1520  # reset view when first layer loaded
1521  nlayers = len(mapWin.Map.GetListOfLayers(l_type = ('raster', '3d-raster', 'vector'),
1522  l_active = True))
1523  if nlayers < 2:
1524  mapWin.ResetView()
1525 
1526  def ReorderLayers(self):
1527  """!Add commands from data associated with any valid layers
1528  (checked or not) to layer list in order to match layers in
1529  layer tree."""
1530 
1531  # make a list of visible layers
1532  treelayers = []
1533 
1534  vislayer = self.GetFirstVisibleItem()
1535 
1536  if not vislayer or self.GetPyData(vislayer) is None:
1537  return
1538 
1539  itemList = ""
1540 
1541  for item in range(self.GetCount()):
1542  itemList += self.GetItemText(vislayer) + ','
1543  if self.GetPyData(vislayer)[0]['type'] != 'group':
1544  treelayers.append(self.GetPyData(vislayer)[0]['maplayer'])
1545 
1546  if not self.GetNextVisible(vislayer):
1547  break
1548  else:
1549  vislayer = self.GetNextVisible(vislayer)
1550 
1551  Debug.msg (4, "LayerTree.ReorderLayers(): items=%s" % \
1552  (itemList))
1553 
1554  # reorder map layers
1555  treelayers.reverse()
1556  self.Map.ReorderLayers(treelayers)
1557  self.reorder = False
1558 
1559  def ChangeLayer(self, item):
1560  """!Change layer"""
1561  type = self.GetPyData(item)[0]['type']
1562  layerName = None
1563 
1564  if type == 'command':
1565  win = self.FindWindowById(self.GetPyData(item)[0]['ctrl'])
1566  if win.GetValue() != None:
1567  cmd = win.GetValue().split(';')
1568  cmdlist = []
1569  for c in cmd:
1570  cmdlist.append(c.split(' '))
1571  opac = 1.0
1572  chk = self.IsItemChecked(item)
1573  hidden = not self.IsVisible(item)
1574  elif type != 'group':
1575  if self.GetPyData(item)[0] is not None:
1576  cmdlist = self.GetPyData(item)[0]['cmd']
1577  opac = self.GetPyData(item)[0]['maplayer'].GetOpacity(float = True)
1578  chk = self.IsItemChecked(item)
1579  hidden = not self.IsVisible(item)
1580  # determine layer name
1581  layerName, found = GetLayerNameFromCmd(cmdlist, fullyQualified = True)
1582  if not found:
1583  layerName = self.GetItemText(item)
1584 
1585  maplayer = self.Map.ChangeLayer(layer = self.GetPyData(item)[0]['maplayer'], type = type,
1586  command = cmdlist, name = layerName,
1587  l_active = chk, l_hidden = hidden, l_opacity = opac, l_render = False)
1588 
1589  self.GetPyData(item)[0]['maplayer'] = maplayer
1590 
1591  # if digitization tool enabled -> update list of available vector map layers
1592  if self.mapdisplay.GetToolbar('vdigit'):
1593  self.mapdisplay.GetToolbar('vdigit').UpdateListOfLayers(updateTool = True)
1594 
1595  # redraw map if auto-rendering is enabled
1596  self.rerender = self.reorder = True
1597 
1598  def OnCloseWindow(self, event):
1599  pass
1600  # self.Map.Clean()
1601 
1602  def FindItemByData(self, key, value):
1603  """!Find item based on key and value (see PyData[0])
1604 
1605  @return item instance
1606  @return None not found
1607  """
1608  item = self.GetFirstChild(self.root)[0]
1609  return self.__FindSubItemByData(item, key, value)
1610 
1611  def FindItemByIndex(self, index):
1612  """!Find item by index (starting at 0)
1613 
1614  @return item instance
1615  @return None not found
1616  """
1617  item = self.GetFirstChild(self.root)[0]
1618  i = 0
1619  while item and item.IsOk():
1620  if i == index:
1621  return item
1622 
1623  item = self.GetNextVisible(item)
1624  i += 1
1625 
1626  return None
1627 
1628  def EnableItemType(self, type, enable = True):
1629  """!Enable/disable items in layer tree"""
1630  item = self.GetFirstChild(self.root)[0]
1631  while item and item.IsOk():
1632  mapLayer = self.GetPyData(item)[0]['maplayer']
1633  if mapLayer and type == mapLayer.type:
1634  self.EnableItem(item, enable)
1635 
1636  item = self.GetNextSibling(item)
1637 
1638  def __FindSubItemByData(self, item, key, value):
1639  """!Support method for FindItemByValue"""
1640  while item and item.IsOk():
1641  try:
1642  itemValue = self.GetPyData(item)[0][key]
1643  except KeyError:
1644  return None
1645 
1646  if value == itemValue:
1647  return item
1648  if self.GetPyData(item)[0]['type'] == 'group':
1649  subItem = self.GetFirstChild(item)[0]
1650  found = self.__FindSubItemByData(subItem, key, value)
1651  if found:
1652  return found
1653  item = self.GetNextSibling(item)
1654 
1655  return None
def OnRenamed
Layer renamed.
Definition: layertree.py:726
def FindItemByIndex
Find item by index (starting at 0)
Definition: layertree.py:1611
wxGUI command interface
def OnChangingSel
Selection is changing.
Definition: layertree.py:1222
def _setGradient
Set gradient for items.
Definition: layertree.py:246
def OnSetCompRegFromRaster
Set computational region from selected raster map (ignore NULLs)
Definition: layertree.py:505
def OnMetadata
Print metadata of raster/vector map layer TODO: Dialog to modify metadata.
Definition: layertree.py:489
def OnActivateLayer
Double click on the layer item.
Definition: layertree.py:1044
wxGUI debugging
def OnIdle
Only re-order and re-render a composite map image from GRASS during idle time instead of multiple tim...
Definition: layertree.py:285
def OnLayerChecking
Layer checkbox is being checked.
Definition: layertree.py:1114
def GetMapDisplay
Get associated MapFrame.
Definition: layertree.py:281
def __FindSubItemByData
Support method for FindItemByValue.
Definition: layertree.py:1638
def FindItemByData
Find item based on key and value (see PyData[0])
Definition: layertree.py:1602
Creates layer tree structure.
Definition: layertree.py:96
def UpdateSettings
Update view from settings values stored in self.mapWindow.view dictionary.
Definition: tools.py:2556
Map display with toolbar for various display management functions, and additional toolbars (vector di...
def OnKeyUp
Key pressed.
Definition: layertree.py:303
mapdisplay
SetAutoLayout() causes that no vertical scrollbar is displayed when some layers are not visible in la...
Definition: layertree.py:152
def OnMotion
Mouse is moving.
Definition: layertree.py:1207
def RecreateItem
Recreate item (needed for OnEndDrag())
Definition: layertree.py:1361
def GetOptData
Process layer data (when changes in propertiesdialog are applied)
Definition: layertree.py:1464
def ChangeLayerOpacity
Change opacity value of layer.
Definition: layertree.py:684
Various dialogs used in wxGUI.
Rendering map layers and overlays into map composition image.
def split
Platform spefic shlex.split.
Definition: core/utils.py:37
def OnCollapseNode
Collapse node.
Definition: layertree.py:1301
def OnRasterColorTable
Set color table for raster map.
Definition: layertree.py:572
def OnCmdChanged
Change command string.
Definition: layertree.py:1190
def OnNvizProperties
Nviz-related properties (raster/vector/volume)
Definition: layertree.py:707
def OnPopupOpacityLevel
Popup opacity level indicator.
Definition: layertree.py:663
def ChangeLayer
Change layer.
Definition: layertree.py:1559
def GetLayerNameFromCmd
Get map name from GRASS command.
Definition: core/utils.py:73
Plotting histogram based on d.histogram.
def ReorderLayers
Add commands from data associated with any valid layers (checked or not) to layer list in order to ma...
Definition: layertree.py:1526
def OnChangeSel
Selection changed.
Definition: layertree.py:1230
def OnProfile
Plot profile of given raster map layer.
Definition: layertree.py:549
def OnExpandNode
Expand node.
Definition: layertree.py:1307
def OnSetCompRegFromMap
Set computational region from selected raster/vector map.
Definition: layertree.py:516
def OnStartEditing
Start editing vector map layer requested by the user.
Definition: layertree.py:610
Base classes toolbar widgets.
def OnApplyLayerOpacity
Handles EVT_APPLY_OPACITY event.
Definition: layertree.py:680
def AddLayer
Add new item to the layer tree, create corresponding MapLayer instance.
Definition: layertree.py:735
Misc utilities for wxGUI.
Profiling using PyPlot.
def OnLayerChecked
Enable/disable data layer.
Definition: layertree.py:1125
def OnRenameLayer
Rename layer.
Definition: layertree.py:721
def OnDeleteLayer
Remove selected layer item from the layer tree.
Definition: layertree.py:1060
def SetRange
Definition: widgets.py:128
def OnSetBgMap
Set background vector map for editing sesstion.
Definition: layertree.py:642
def GetMap
Get map instace.
Definition: layertree.py:277
def PropertiesDialog
Launch the properties dialog.
Definition: layertree.py:960
def OnLayerContextMenu
Contextual menu for item/layer.
Definition: layertree.py:313
def OnPopupProperties
Popup properties dialog.
Definition: layertree.py:659
Default GUI settings.
def _getLayerName
Get layer name string.
Definition: layertree.py:1443
def OnVectorColorTable
Set color table for vector map.
Definition: layertree.py:580
tuple range
Definition: tools.py:1406
def OnTopology
Rebuild topology of selected vector map.
Definition: layertree.py:482
def OnStopEditing
Stop editing the current vector map layer.
Definition: layertree.py:630
def EnableItemType
Enable/disable items in layer tree.
Definition: layertree.py:1628
def OnUnivariateStats
Univariate raster statistics.
Definition: layertree.py:605
def OnHistogram
Plot histogram for given raster map layer.
Definition: layertree.py:586