GRASS Programmer's Manual  6.4.4(2014)-r
core/workspace.py
Go to the documentation of this file.
1 """!
2 @package core.workspace
3 
4 @brief Open/save workspace definition file
5 
6 Classes:
7  - workspace::ProcessWorkspaceFile
8  - workspace::WriteWorkspaceFile
9  - workspace::ProcessGrcFile
10 
11 (C) 2007-2011 by the GRASS Development Team
12 
13 This program is free software under the GNU General Public License
14 (>=v2). Read the file COPYING that comes with GRASS for details.
15 
16 @author Martin Landa <landa.martin gmail.com>
17 """
18 
19 import os
20 
21 import wx
22 
23 from core.utils import normalize_whitespace
24 from core.settings import UserSettings
25 from core.gcmd import EncodeString, GetDefaultEncoding
26 from nviz.main import NvizSettings
27 
29  def __init__(self, tree):
30  """!A ElementTree handler for the GXW XML file, as defined in
31  grass-gxw.dtd.
32  """
33  self.tree = tree
34  self.root = self.tree.getroot()
35 
36  #
37  # layer manager properties
38  #
39  self.layerManager = {}
40  self.layerManager['pos'] = None # window position
41  self.layerManager['size'] = None # window size
42 
43  #
44  # list of mapdisplays
45  #
46  self.displays = []
47  #
48  # list of map layers
49  #
50  self.layers = []
51  #
52  # nviz state
53  #
54  self.nviz_state = {}
55 
56  self.displayIndex = -1 # first display has index '0'
57 
58  self.__processFile()
59 
60  if NvizSettings:
62  else:
63  self.nvizDefault = None
64 
65  def __filterValue(self, value):
66  """!Filter value
67 
68  @param value
69  """
70  value = value.replace('&lt;', '<')
71  value = value.replace('&gt;', '>')
72 
73  return value
74 
75  def __getNodeText(self, node, tag, default = ''):
76  """!Get node text"""
77  p = node.find(tag)
78  if p is not None:
79  return normalize_whitespace(p.text)
80 
81  return default
82 
83  def __processFile(self):
84  """!Process workspace file"""
85  #
86  # layer manager
87  #
88  node_lm = self.root.find('layer_manager')
89  if node_lm is not None:
90  posAttr = node_lm.get('dim', '')
91  if posAttr:
92  posVal = map(int, posAttr.split(','))
93  try:
94  self.layerManager['pos'] = (posVal[0], posVal[1])
95  self.layerManager['size'] = (posVal[2], posVal[3])
96  except:
97  pass
98 
99  #
100  # displays
101  #
102  for display in self.root.findall('display'):
103  self.displayIndex += 1
104 
105  # window position and size
106  posAttr = display.get('dim', '')
107  if posAttr:
108  posVal = map(int, posAttr.split(','))
109  try:
110  pos = (posVal[0], posVal[1])
111  size = (posVal[2], posVal[3])
112  except:
113  pos = None
114  size = None
115  else:
116  pos = None
117  size = None
118 
119  extentAttr = display.get('extent', '')
120  if extentAttr:
121  # w, s, e, n
122  extent = map(float, extentAttr.split(','))
123  else:
124  extent = None
125 
126  # projection
127  node_projection = display.find('projection')
128  if node_projection is not None:
129  projection = { 'enabled' : True,
130  'epsg' : node_projection.get('epsg', ''),
131  'proj' : self.__getNodeText(node_projection, 'value') }
132  else:
133  projection = { 'enabled' : False }
134 
135  self.displays.append( {
136  "name" : display.get('name'),
137  "render" : bool(int(display.get('render', "0"))),
138  "mode" : int(display.get('mode', 0)),
139  "showCompExtent" : bool(int(display.get('showCompExtent', "0"))),
140  "pos" : pos,
141  "size" : size,
142  "extent" : extent,
143  "alignExtent" : bool(int(display.get('alignExtent', "0"))),
144  "constrainRes" : bool(int(display.get('constrainRes', "0"))),
145  "projection" : projection,
146  "viewMode" : display.get('viewMode', '2d')} )
147 
148  # process all layers/groups in the display
149  self.__processLayers(display)
150  # process nviz_state
151  self.__processNvizState(display)
152 
153  def __processLayers(self, node, inGroup = -1):
154  """!Process layers/groups of selected display
155 
156  @param node display tree node
157  @param inGroup in group -> index of group item otherwise -1
158  """
159  for item in node.getchildren():
160  if item.tag == 'group':
161  # -> group
162  self.layers.append( {
163  "type" : 'group',
164  "name" : item.get('name', ''),
165  "checked" : bool(int(item.get('checked', "0"))),
166  "opacity" : None,
167  "cmd" : None,
168  "group" : inGroup,
169  "display" : self.displayIndex,
170  "vdigit" : None,
171  "nviz" : None})
172 
173  self.__processLayers(item, inGroup = len(self.layers) - 1) # process items in group
174 
175  elif item.tag == 'layer':
176  cmd, selected, vdigit, nviz = self.__processLayer(item)
177  lname = item.get('name', None)
178  if lname and '\\n' in lname:
179  lname = lname.replace('\\n', os.linesep)
180 
181  self.layers.append( {
182  "type" : item.get('type', None),
183  "name" : lname,
184  "checked" : bool(int(item.get('checked', "0"))),
185  "opacity" : float(item.get('opacity', '1.0')),
186  "cmd" : cmd,
187  "group" : inGroup,
188  "display" : self.displayIndex,
189  "selected" : selected,
190  "vdigit" : vdigit,
191  "nviz" : nviz } )
192 
193  def __processLayer(self, layer):
194  """!Process layer item
195 
196  @param layer tree node
197  """
198  cmd = list()
199 
200  #
201  # layer attributes (task) - 2D settings
202  #
203  node_task = layer.find('task')
204  cmd.append(node_task.get('name', "unknown"))
205 
206  # flags
207  for p in node_task.findall('flag'):
208  flag = p.get('name', '')
209  if len(flag) > 1:
210  cmd.append('--' + flag)
211  else:
212  cmd.append('-' + flag)
213 
214  # parameters
215  for p in node_task.findall('parameter'):
216  cmd.append('%s=%s' % (p.get('name', ''),
217  self.__filterValue(self.__getNodeText(p, 'value'))))
218 
219  if layer.find('selected') is not None:
220  selected = True
221  else:
222  selected = False
223 
224  #
225  # Vector digitizer settings
226  #
227  node_vdigit = layer.find('vdigit')
228  if node_vdigit is not None:
229  vdigit = self.__processLayerVdigit(node_vdigit)
230  else:
231  vdigit = None
232 
233  #
234  # Nviz (3D settings)
235  #
236  node_nviz = layer.find('nviz')
237  if node_nviz is not None:
238  nviz = self.__processLayerNviz(node_nviz)
239  else:
240  nviz = None
241 
242  return (cmd, selected, vdigit, nviz)
243 
244  def __processLayerVdigit(self, node_vdigit):
245  """!Process vector digitizer layer settings
246 
247  @param node_vdigit vdigit node
248  """
249  # init nviz layer properties
250  vdigit = dict()
251  for node in node_vdigit.findall('geometryAttribute'):
252  if 'geomAttr' not in vdigit:
253  vdigit['geomAttr'] = dict()
254  type = node.get('type')
255  vdigit['geomAttr'][type] = dict()
256  vdigit['geomAttr'][type]['column'] = node.get('column') # required
257  # default map units
258  vdigit['geomAttr'][type]['units'] = node.get('units', 'mu')
259 
260  return vdigit
261 
262  def __processLayerNviz(self, node_nviz):
263  """!Process 3D layer settings
264 
265  @param node_nviz nviz node
266  """
267  # init nviz layer properties
268  nviz = {}
269  if node_nviz.find('surface') is not None: # -> raster
270  nviz['surface'] = {}
271  for sec in ('attribute', 'draw', 'position'):
272  nviz['surface'][sec] = {}
273  elif node_nviz.find('vlines') is not None or \
274  node_nviz.find('vpoints') is not None: # -> vector
275  nviz['vector'] = {}
276  for sec in ('lines', 'points'):
277  nviz['vector'][sec] = {}
278 
279  if 'surface' in nviz:
280  node_surface = node_nviz.find('surface')
281  # attributes
282  for attrb in node_surface.findall('attribute'):
283  tagName = str(attrb.tag)
284  attrbName = attrb.get('name', '')
285  dc = nviz['surface'][tagName][attrbName] = {}
286  if attrb.get('map', '0') == '0':
287  dc['map'] = False
288  else:
289  dc['map'] = True
290  value = self.__getNodeText(attrb, 'value')
291  try:
292  dc['value'] = int(value)
293  except ValueError:
294  try:
295  dc['value'] = float(value)
296  except ValueError:
297  dc['value'] = str(value)
298 
299  # draw
300  node_draw = node_surface.find('draw')
301  if node_draw is not None:
302  tagName = str(node_draw.tag)
303  nviz['surface'][tagName]['all'] = False
304  nviz['surface'][tagName]['mode'] = {}
305  nviz['surface'][tagName]['mode']['value'] = -1 # to be calculated
306  nviz['surface'][tagName]['mode']['desc'] = {}
307  nviz['surface'][tagName]['mode']['desc']['shading'] = \
308  str(node_draw.get('shading', ''))
309  nviz['surface'][tagName]['mode']['desc']['style'] = \
310  str(node_draw.get('style', ''))
311  nviz['surface'][tagName]['mode']['desc']['mode'] = \
312  str(node_draw.get('mode', ''))
313 
314  # resolution
315  for node_res in node_draw.findall('resolution'):
316  resType = str(node_res.get('type', ''))
317  if 'resolution' not in nviz['surface']['draw']:
318  nviz['surface']['draw']['resolution'] = {}
319  value = int(self.__getNodeText(node_res, 'value'))
320  nviz['surface']['draw']['resolution'][resType] = value
321 
322  # wire-color
323  node_wire_color = node_draw.find('wire_color')
324  if node_wire_color is not None:
325  nviz['surface']['draw']['wire-color'] = {}
326  value = str(self.__getNodeText(node_wire_color, 'value'))
327  nviz['surface']['draw']['wire-color']['value'] = value
328 
329  # position
330  node_pos = node_surface.find('position')
331  if node_pos is not None:
332  dc = nviz['surface']['position'] = {}
333  for coor in ['x', 'y', 'z']:
334  node = node_pos.find(coor)
335  if node is None:
336  continue
337  value = int(self.__getNodeText(node_pos, coor))
338  dc[coor] = value
339 
340  elif 'vector' in nviz:
341  # vpoints
342  node_vpoints = node_nviz.find('vpoints')
343  if node_vpoints is not None:
344  marker = str(node_vpoints.get('marker', ''))
345  markerId = list(UserSettings.Get(group='nviz', key='vector',
346  subkey=['points', 'marker'], internal=True)).index(marker)
347  nviz['vector']['points']['marker'] = { 'value' : markerId }
348 
349  node_mode = node_vpoints.find('mode')
350  if node_mode is not None:
351  nviz['vector']['points']['mode'] = {}
352  nviz['vector']['points']['mode']['type'] = str(node_mode.get('type', 'surface'))
353  nviz['vector']['points']['mode']['surface'] = {}
354  nviz['vector']['points']['mode']['surface']['value'] = []
355  nviz['vector']['points']['mode']['surface']['show'] = []
356 
357  # map
358  for node_map in node_mode.findall('map'):
359  nviz['vector']['points']['mode']['surface']['value'].append(
360  self.__processLayerNvizNode(node_map, 'name', str))
361  nviz['vector']['points']['mode']['surface']['show'].append(bool(
362  self.__processLayerNvizNode(node_map, 'checked', int)))
363 
364  # color
365  self.__processLayerNvizNode(node_vpoints, 'color', str,
366  nviz['vector']['points'])
367 
368  # width
369  self.__processLayerNvizNode(node_vpoints, 'width', int,
370  nviz['vector']['points'])
371 
372  # height
373  self.__processLayerNvizNode(node_vpoints, 'height', float,
374  nviz['vector']['points'])
375 
376  # height
377  self.__processLayerNvizNode(node_vpoints, 'size', float,
378  nviz['vector']['points'])
379 
380  # vlines
381  node_vlines = node_nviz.find('vlines')
382  if node_vlines is not None:
383  node_mode = node_vlines.find('mode')
384  if node_mode is not None:
385  nviz['vector']['lines']['mode'] = {}
386  nviz['vector']['lines']['mode']['type'] = str(node_mode.get('type', ''))
387  nviz['vector']['lines']['mode']['surface'] = {}
388  nviz['vector']['lines']['mode']['surface']['value'] = []
389  nviz['vector']['lines']['mode']['surface']['show'] = []
390 
391  # map
392  for node_map in node_mode.findall('map'):
393  nviz['vector']['lines']['mode']['surface']['value'].append(
394  self.__processLayerNvizNode(node_map, 'name', str))
395  nviz['vector']['lines']['mode']['surface']['show'].append(bool(
396  self.__processLayerNvizNode(node_map, 'checked', int)))
397 
398  # color
399  self.__processLayerNvizNode(node_vlines, 'color', str,
400  nviz['vector']['lines'])
401 
402  # width
403  self.__processLayerNvizNode(node_vlines, 'width', int,
404  nviz['vector']['lines'])
405 
406  # height
407  self.__processLayerNvizNode(node_vlines, 'height', int,
408  nviz['vector']['lines'])
409 
410  return nviz
411 
412  def __processLayerNvizNode(self, node, tag, cast, dc = None):
413  """!Process given tag nviz/vector"""
414  node_tag = node.find(tag)
415  if node_tag is not None:
416  if node_tag.find('value') is not None:
417  value = cast(self.__getNodeText(node_tag, 'value'))
418  else:
419  try:
420  value = cast(node_tag.text)
421  except ValueError:
422  if cast == str:
423  value = ''
424  else:
425  value = None
426  if dc:
427  dc[tag] = dict()
428  dc[tag]['value'] = value
429  else:
430  return value
431 
432  def __processNvizState(self, node):
433  """!Process tag nviz_state"""
434  node_state = node.find('nviz_state')
435  if node_state is None:
436  return
437  self.nviz_state['display'] = self.displayIndex
438  #
439  # view
440  #
441  node_view = node_state.find('view')
442  view = {}
443  iview = {}
444 
445  node_position = node_view.find('v_position')
446  view['position'] = {}
447  view['position']['x'] = self.__processLayerNvizNode(node_position, 'x', float)
448  view['position']['y'] = self.__processLayerNvizNode(node_position, 'y', float)
449  node_persp = node_view.find('persp')
450  view['persp'] = {}
451  iview['persp'] = {}
452  view['persp']['value'] = self.__processLayerNvizNode(node_persp, 'value', int)
453  view['persp']['step'] = self.__processLayerNvizNode(node_persp, 'step', int)
454  iview['persp']['min'] = self.__processLayerNvizNode(node_persp, 'min', int)
455  iview['persp']['max'] = self.__processLayerNvizNode(node_persp, 'max', int)
456  node_height = node_view.find('v_height')
457  iview['height'] = {}
458  iview['height']['value'] = self.__processLayerNvizNode(node_height, 'value', int)
459  iview['height']['min'] = self.__processLayerNvizNode(node_height, 'min', int)
460  iview['height']['max'] = self.__processLayerNvizNode(node_height, 'max', int)
461  node_twist = node_view.find('twist')
462  view['twist'] = {}
463  iview['twist'] = {}
464  view['twist']['value'] = self.__processLayerNvizNode(node_twist, 'value', int)
465  iview['twist']['min'] = self.__processLayerNvizNode(node_twist, 'min', int)
466  iview['twist']['max'] = self.__processLayerNvizNode(node_twist, 'max', int)
467  node_zexag = node_view.find('z-exag')
468  view['z-exag'] = {}
469  iview['z-exag'] = {}
470  view['z-exag']['value'] = self.__processLayerNvizNode(node_zexag, 'value', float)
471  view['z-exag']['min'] = self.__processLayerNvizNode(node_zexag, 'min', int)
472  view['z-exag']['max'] = self.__processLayerNvizNode(node_zexag, 'max', int)
473  iview['z-exag']['llRatio'] = self.__processLayerNvizNode(node_zexag, 'llRatio', float)
474  node_focus = node_view.find('focus')
475  iview['focus'] = {}
476  iview['focus']['x'] = self.__processLayerNvizNode(node_focus, 'x', int)
477  iview['focus']['y'] = self.__processLayerNvizNode(node_focus, 'y', int)
478  iview['focus']['z'] = self.__processLayerNvizNode(node_focus, 'z', int)
479  node_dir = node_view.find('dir')
480  if node_dir:
481  iview['dir'] = {}
482  iview['dir']['x'] = self.__processLayerNvizNode(node_dir, 'x', int)
483  iview['dir']['y'] = self.__processLayerNvizNode(node_dir, 'y', int)
484  iview['dir']['z'] = self.__processLayerNvizNode(node_dir, 'z', int)
485  iview['dir']['use'] = True
486  else:
487  iview['dir'] = {}
488  iview['dir']['x'] = -1
489  iview['dir']['y'] = -1
490  iview['dir']['z'] = -1
491  iview['dir']['use'] = False
492 
493  view['background'] = {}
494  color = self.__processLayerNvizNode(node_view, 'background_color', str)
495  view['background']['color'] = tuple(map(int, color.split(':')))
496 
497  self.nviz_state['view'] = view
498  self.nviz_state['iview'] = iview
499  #
500  # light
501  #
502  node_light = node_state.find('light')
503  light = {}
504 
505  node_position = node_light.find('l_position')
506  light['position'] = {}
507  light['position']['x'] = self.__processLayerNvizNode(node_position, 'x', float)
508  light['position']['y'] = self.__processLayerNvizNode(node_position, 'y', float)
509  light['position']['z'] = self.__processLayerNvizNode(node_position, 'z', int)
510 
511  light['bright'] = self.__processLayerNvizNode(node_light, 'bright', int)
512  light['ambient'] = self.__processLayerNvizNode(node_light, 'ambient', int)
513  color = self.__processLayerNvizNode(node_light, 'color', str)
514  light['color'] = tuple(map(int, color.split(':')))
515 
516  self.nviz_state['light'] = light
517 
518  node_constants = node_state.find('constant_planes')
519  constants = []
520  if node_constants:
521  for i, node_plane in enumerate(node_constants.findall('plane')):
522  plane = {}
523  plane['color'] = self.__processLayerNvizNode(node_plane, 'color', str)
524  plane['resolution'] = self.__processLayerNvizNode(node_plane, 'fine_resolution', int)
525  plane['value'] = self.__processLayerNvizNode(node_plane, 'height', int)
526  plane['object'] = {}
527  constants.append({'constant': plane})
528  self.nviz_state['constants'] = constants
529 
530 class WriteWorkspaceFile(object):
531  """!Generic class for writing workspace file"""
532  def __init__(self, lmgr, file):
533  self.file = file
534  self.lmgr = lmgr
535  self.indent = 0
536 
537  # write header
538 
539  self.file.write('<?xml version="1.0" encoding="%s"?>\n' % GetDefaultEncoding(forceUTF8 = True))
540  self.file.write('<!DOCTYPE gxw SYSTEM "grass-gxw.dtd">\n')
541  self.file.write('%s<gxw>\n' % (' ' * self.indent))
542 
543  self.indent =+ 4
544 
545  # layer manager
546  windowPos = self.lmgr.GetPosition()
547  windowSize = self.lmgr.GetSize()
548  file.write('%s<layer_manager dim="%d,%d,%d,%d">\n' % (' ' * self.indent,
549  windowPos[0],
550  windowPos[1],
551  windowSize[0],
552  windowSize[1]
553  ))
554 
555  file.write('%s</layer_manager>\n' % (' ' * self.indent))
556 
557  # list of displays
558  for page in range(0, self.lmgr.gm_cb.GetPageCount()):
559  dispName = self.lmgr.gm_cb.GetPageText(page)
560  mapTree = self.lmgr.gm_cb.GetPage(page).maptree
561  region = mapTree.Map.region
562 
563  displayPos = mapTree.mapdisplay.GetPosition()
564  displaySize = mapTree.mapdisplay.GetSize()
565  if mapTree.mapdisplay.toolbars['map'].combo.GetSelection() == 1:
566  viewmode = '3d'
567  else:
568  viewmode = '2d'
569 
570  file.write('%s<display '
571  'name="%s" render="%d" '
572  'mode="%d" showCompExtent="%d" '
573  'alignExtent="%d" '
574  'constrainRes="%d" '
575  'dim="%d,%d,%d,%d" '
576  'extent="%f,%f,%f,%f" '
577  'viewMode="%s" >\n' % (' ' * self.indent,
578  dispName.encode('utf8'),
579  int(mapTree.mapdisplay.GetProperty('render')),
580  mapTree.mapdisplay.statusbarManager.GetMode(),
581  int(mapTree.mapdisplay.GetProperty('region')),
582  int(mapTree.mapdisplay.GetProperty('alignExtent')),
583  int(mapTree.mapdisplay.GetProperty('resolution')),
584  displayPos[0],
585  displayPos[1],
586  displaySize[0],
587  displaySize[1],
588  region['w'],
589  region['s'],
590  region['e'],
591  region['n'],
592  viewmode
593  ))
594  # projection statusbar info
595  if mapTree.mapdisplay.GetProperty('projection') and \
596  UserSettings.Get(group='display', key='projection', subkey='proj4'):
597  self.indent += 4
598  file.write('%s<projection' % (' ' * self.indent))
599  epsg = UserSettings.Get(group='display', key='projection', subkey='epsg')
600  if epsg:
601  file.write(' epsg="%s"' % epsg)
602  file.write('>\n')
603  proj = UserSettings.Get(group='display', key='projection', subkey='proj4')
604  self.indent += 4
605  file.write('%s<value>%s</value>\n' % (' ' * self.indent, proj))
606  self.indent -= 4
607  file.write('%s</projection>\n' % (' ' * self.indent))
608  self.indent -= 4
609 
610  # list of layers
611  item = mapTree.GetFirstChild(mapTree.root)[0]
612  self.__writeLayer(mapTree, item)
613 
614  if mapTree.mapdisplay.MapWindow3D is not None:
615  nvizDisp = mapTree.mapdisplay.MapWindow3D
616  self.__writeNvizState(view = nvizDisp.view, iview = nvizDisp.iview,
617  light = nvizDisp.light, constants = nvizDisp.constants)
618 
619  file.write('%s</display>\n' % (' ' * self.indent))
620 
621  self.indent =- 4
622  file.write('%s</gxw>\n' % (' ' * self.indent))
623 
624  def __filterValue(self, value):
625  """!Make value XML-valid"""
626  value = value.replace('<', '&lt;')
627  value = value.replace('>', '&gt;')
628 
629  return value
630 
631  def __writeLayer(self, mapTree, item):
632  """!Write bunch of layers to GRASS Workspace XML file"""
633  self.indent += 4
634  itemSelected = mapTree.GetSelections()
635  while item and item.IsOk():
636  type = mapTree.GetPyData(item)[0]['type']
637  if type != 'group':
638  maplayer = mapTree.GetPyData(item)[0]['maplayer']
639  else:
640  maplayer = None
641 
642  checked = int(item.IsChecked())
643  if type == 'command':
644  cmd = mapTree.GetPyData(item)[0]['maplayer'].GetCmd(string=True)
645  self.file.write('%s<layer type="%s" name="%s" checked="%d">\n' % \
646  (' ' * self.indent, type, EncodeString(cmd), checked));
647  self.file.write('%s</layer>\n' % (' ' * self.indent));
648  elif type == 'group':
649  name = mapTree.GetItemText(item)
650  self.file.write('%s<group name="%s" checked="%d">\n' % \
651  (' ' * self.indent, EncodeString(name), checked));
652  self.indent += 4
653  subItem = mapTree.GetFirstChild(item)[0]
654  self.__writeLayer(mapTree, subItem)
655  self.indent -= 4
656  self.file.write('%s</group>\n' % (' ' * self.indent));
657  else:
658  cmd = mapTree.GetPyData(item)[0]['maplayer'].GetCmd(string = False)
659  name = mapTree.GetItemText(item).replace(os.linesep, '\\n')
660  opacity = maplayer.GetOpacity(float = True)
661  # remove 'opacity' part
662  if opacity < 1:
663  name = name.split('(', -1)[0].strip()
664  self.file.write('%s<layer type="%s" name="%s" checked="%d" opacity="%f">\n' % \
665  (' ' * self.indent, type, EncodeString(name), checked, opacity));
666 
667  self.indent += 4
668  # selected ?
669  if item in itemSelected:
670  self.file.write('%s<selected />\n' % (' ' * self.indent))
671  # layer properties
672  self.file.write('%s<task name="%s">\n' % (' ' * self.indent, cmd[0]))
673  self.indent += 4
674  for key, val in cmd[1].iteritems():
675  if key == 'flags':
676  for f in val:
677  self.file.write('%s<flag name="%s" />\n' %
678  (' ' * self.indent, f))
679  elif val in (True, False):
680  self.file.write('%s<flag name="%s" />\n' %
681  (' ' * self.indent, key))
682  else: # parameter
683  self.file.write('%s<parameter name="%s">\n' %
684  (' ' * self.indent, key))
685  self.indent += 4
686  self.file.write('%s<value>%s</value>\n' %
687  (' ' * self.indent, self.__filterValue(val)))
688  self.indent -= 4
689  self.file.write('%s</parameter>\n' % (' ' * self.indent));
690  self.indent -= 4
691  self.file.write('%s</task>\n' % (' ' * self.indent));
692  # vector digitizer
693  vdigit = mapTree.GetPyData(item)[0]['vdigit']
694  if vdigit:
695  self.file.write('%s<vdigit>\n' % (' ' * self.indent))
696  if 'geomAttr' in vdigit:
697  self.indent += 4
698  for type, val in vdigit['geomAttr'].iteritems():
699  units = ''
700  if val['units'] != 'mu':
701  units = ' units="%s"' % val['units']
702  self.file.write('%s<geometryAttribute type="%s" column="%s"%s />\n' % \
703  (' ' * self.indent, type, val['column'], units))
704  self.indent -= 4
705  self.file.write('%s</vdigit>\n' % (' ' * self.indent))
706  # nviz
707  nviz = mapTree.GetPyData(item)[0]['nviz']
708  if nviz:
709  self.file.write('%s<nviz>\n' % (' ' * self.indent))
710  if maplayer.type == 'raster':
711  self.__writeNvizSurface(nviz['surface'])
712  elif maplayer.type == 'vector':
713  self.__writeNvizVector(nviz['vector'])
714  self.file.write('%s</nviz>\n' % (' ' * self.indent))
715  self.indent -= 4
716  self.file.write('%s</layer>\n' % (' ' * self.indent))
717  item = mapTree.GetNextSibling(item)
718  self.indent -= 4
719 
720  def __writeNvizSurface(self, data):
721  """!Save Nviz raster layer properties to workspace
722 
723  @param data Nviz layer properties
724  """
725  if 'object' not in data: # skip disabled
726  return
727  self.indent += 4
728  self.file.write('%s<surface>\n' % (' ' * self.indent))
729  self.indent += 4
730  for attrb in data.iterkeys():
731  if len(data[attrb]) < 1: # skip empty attributes
732  continue
733  if attrb == 'object':
734  continue
735 
736  for name in data[attrb].iterkeys():
737  # surface attribute
738  if attrb == 'attribute':
739  if data[attrb][name]['map'] is None:
740  continue
741  self.file.write('%s<%s name="%s" map="%d">\n' % \
742  (' ' * self.indent, attrb, name, data[attrb][name]['map']))
743  self.indent += 4
744  self.file.write('%s<value>%s</value>\n' % (' ' * self.indent, data[attrb][name]['value']))
745  self.indent -= 4
746  # end tag
747  self.file.write('%s</%s>\n' % (' ' * self.indent, attrb))
748 
749  # draw mode
750  if attrb == 'draw':
751  self.file.write('%s<%s' %(' ' * self.indent, attrb))
752  if 'mode' in data[attrb]:
753  for tag, value in data[attrb]['mode']['desc'].iteritems():
754  self.file.write(' %s="%s"' % (tag, value))
755  self.file.write('>\n') # <draw ...>
756 
757  if 'resolution' in data[attrb]:
758  self.indent += 4
759  for type in ('coarse', 'fine'):
760  self.file.write('%s<resolution type="%s">\n' % (' ' * self.indent, type))
761  self.indent += 4
762  self.file.write('%s<value>%d</value>\n' % (' ' * self.indent,
763  data[attrb]['resolution'][type]))
764  self.indent -= 4
765  self.file.write('%s</resolution>\n' % (' ' * self.indent))
766 
767  if 'wire-color' in data[attrb]:
768  self.file.write('%s<wire_color>\n' % (' ' * self.indent))
769  self.indent += 4
770  self.file.write('%s<value>%s</value>\n' % (' ' * self.indent,
771  data[attrb]['wire-color']['value']))
772  self.indent -= 4
773  self.file.write('%s</wire_color>\n' % (' ' * self.indent))
774  self.indent -= 4
775 
776  # position
777  elif attrb == 'position':
778  self.file.write('%s<%s>\n' %(' ' * self.indent, attrb))
779  i = 0
780  for tag in ('x', 'y', 'z'):
781  self.indent += 4
782  self.file.write('%s<%s>%d</%s>\n' % (' ' * self.indent, tag,
783  data[attrb][tag], tag))
784  i += 1
785  self.indent -= 4
786 
787  if attrb != 'attribute':
788  # end tag
789  self.file.write('%s</%s>\n' % (' ' * self.indent, attrb))
790 
791  self.indent -= 4
792  self.file.write('%s</surface>\n' % (' ' * self.indent))
793  self.indent -= 4
794 
795  def __writeNvizVector(self, data):
796  """!Save Nviz vector layer properties (lines/points) to workspace
797 
798  @param data Nviz layer properties
799  """
800  self.indent += 4
801  for attrb in data.iterkeys():
802  if len(data[attrb]) < 1: # skip empty attributes
803  continue
804 
805  if 'object' not in data[attrb]: # skip disabled
806  continue
807  if attrb == 'lines':
808  self.file.write('%s<v%s>\n' % (' ' * self.indent, attrb))
809  elif attrb == 'points':
810  markerId = data[attrb]['marker']['value']
811  marker = UserSettings.Get(group = 'nviz', key = 'vector',
812  subkey = ['points', 'marker'], internal = True)[markerId]
813  self.file.write('%s<v%s marker="%s">\n' % (' ' * self.indent,
814  attrb,
815  marker))
816  self.indent += 4
817  for name in data[attrb].iterkeys():
818  if name in ('object', 'marker'):
819  continue
820  if name == 'mode':
821  self.file.write('%s<%s type="%s">\n' % (' ' * self.indent, name,
822  data[attrb][name]['type']))
823  if data[attrb][name]['type'] == 'surface':
824  self.indent += 4
825  for idx, surface in enumerate(data[attrb][name]['surface']['value']):
826  checked = data[attrb][name]['surface']['show'][idx]
827  self.file.write('%s<map>\n' % (' ' * self.indent))
828  self.indent += 4
829  self.file.write('%s<name>%s</name>\n' % (' ' * self.indent, surface))
830  self.file.write('%s<checked>%s</checked>\n' % (' ' * self.indent, int(checked)))
831  self.indent -= 4
832  self.file.write('%s</map>\n' % (' ' * self.indent))
833  self.indent -= 4
834  self.file.write('%s</%s>\n' % ((' ' * self.indent, name)))
835  else:
836  self.file.write('%s<%s>\n' % (' ' * self.indent, name))
837  self.indent += 4
838  self.file.write('%s<value>%s</value>\n' % (' ' * self.indent, data[attrb][name]['value']))
839  self.indent -= 4
840  self.file.write('%s</%s>\n' % (' ' * self.indent, name))
841  self.indent -= 4
842  self.file.write('%s</v%s>\n' % (' ' * self.indent, attrb))
843 
844  self.indent -= 4
845 
846  def __writeNvizState(self, view, iview, light, constants):
847  """"!Save Nviz properties (view, light) to workspace
848 
849  @param view Nviz view properties
850  @param iview Nviz internal view properties
851  @param light Nviz light properties
852  """
853  self.indent += 4
854  self.file.write('%s<nviz_state>\n' % (' ' * self.indent))
855  #
856  # view
857  #
858  self.indent += 4
859  self.file.write('%s<view>\n' % (' ' * self.indent))
860  self.indent += 4
861  # position
862  self.file.write('%s<v_position>\n' % (' ' * self.indent))
863  self.indent += 4
864  self.file.write('%s<x>%.2f</x>\n' % (' ' * self.indent, view['position']['x']))
865  self.file.write('%s<y>%.2f</y>\n' % (' ' * self.indent, view['position']['y']))
866  self.indent -= 4
867  self.file.write('%s</v_position>\n' % (' ' * self.indent))
868  # perspective
869  self.file.write('%s<persp>\n' % (' ' * self.indent))
870  self.indent += 4
871  self.file.write('%s<value>%d</value>\n' % (' ' * self.indent, view['persp']['value']))
872  self.file.write('%s<step>%d</step>\n' % (' ' * self.indent, view['persp']['step']))
873  self.file.write('%s<min>%d</min>\n' % (' ' * self.indent, iview['persp']['min']))
874  self.file.write('%s<max>%d</max>\n' % (' ' * self.indent, iview['persp']['max']))
875  self.indent -= 4
876  self.file.write('%s</persp>\n' % (' ' * self.indent))
877  # height
878  self.file.write('%s<v_height>\n' % (' ' * self.indent))
879  self.indent += 4
880  self.file.write('%s<value>%d</value>\n' % (' ' * self.indent, iview['height']['value']))
881  self.file.write('%s<min>%d</min>\n' % (' ' * self.indent, iview['height']['min']))
882  self.file.write('%s<max>%d</max>\n' % (' ' * self.indent, iview['height']['max']))
883  self.indent -= 4
884  self.file.write('%s</v_height>\n' % (' ' * self.indent))
885  # twist
886  self.file.write('%s<twist>\n' % (' ' * self.indent))
887  self.indent += 4
888  self.file.write('%s<value>%d</value>\n' % (' ' * self.indent, view['twist']['value']))
889  self.file.write('%s<min>%d</min>\n' % (' ' * self.indent, iview['twist']['min']))
890  self.file.write('%s<max>%d</max>\n' % (' ' * self.indent, iview['twist']['max']))
891  self.indent -= 4
892  self.file.write('%s</twist>\n' % (' ' * self.indent))
893  # z-exag
894  self.file.write('%s<z-exag>\n' % (' ' * self.indent))
895  self.indent += 4
896  self.file.write('%s<value>%.2f</value>\n' % (' ' * self.indent, view['z-exag']['value']))
897  self.file.write('%s<min>%d</min>\n' % (' ' * self.indent, view['z-exag']['min']))
898  self.file.write('%s<max>%d</max>\n' % (' ' * self.indent, view['z-exag']['max']))
899  self.file.write('%s<llRatio>%.2f</llRatio>\n' % (' ' * self.indent, iview['z-exag']['llRatio']))
900  self.indent -= 4
901  self.file.write('%s</z-exag>\n' % (' ' * self.indent))
902  # focus (look here)
903  self.file.write('%s<focus>\n' % (' ' * self.indent))
904  self.indent += 4
905  self.file.write('%s<x>%d</x>\n' % (' ' * self.indent, iview['focus']['x']))
906  self.file.write('%s<y>%d</y>\n' % (' ' * self.indent, iview['focus']['y']))
907  self.file.write('%s<z>%d</z>\n' % (' ' * self.indent, iview['focus']['z']))
908  self.indent -= 4
909  self.file.write('%s</focus>\n' % (' ' * self.indent))
910  # background
911  self.__writeTagWithValue('background_color', view['background']['color'][:3], format = 'd:%d:%d')
912 
913  self.indent -= 4
914  self.file.write('%s</view>\n' % (' ' * self.indent))
915  #
916  # light
917  #
918  self.file.write('%s<light>\n' % (' ' * self.indent))
919  self.indent += 4
920  # position
921  self.file.write('%s<l_position>\n' % (' ' * self.indent))
922  self.indent += 4
923  self.file.write('%s<x>%.2f</x>\n' % (' ' * self.indent, light['position']['x']))
924  self.file.write('%s<y>%.2f</y>\n' % (' ' * self.indent, light['position']['y']))
925  self.file.write('%s<z>%d</z>\n' % (' ' * self.indent, light['position']['z']))
926  self.indent -= 4
927  self.file.write('%s</l_position>\n' % (' ' * self.indent))
928  # bright
929  self.__writeTagWithValue('bright', light['bright'])
930  # ambient
931  self.__writeTagWithValue('ambient', light['ambient'])
932  # color
933  self.__writeTagWithValue('color', light['color'][:3], format = 'd:%d:%d')
934 
935  self.indent -= 4
936  self.file.write('%s</light>\n' % (' ' * self.indent))
937  #
938  # constant planes
939  #
940  if constants:
941  self.file.write('%s<constant_planes>\n' % (' ' * self.indent))
942  self.indent += 4
943  for idx, plane in enumerate(constants):
944  self.file.write('%s<plane>\n' % (' ' * self.indent))
945  self.indent += 4
946  self.__writeTagWithValue('height', constants[idx]['constant']['value'])
947  self.__writeTagWithValue('fine_resolution', constants[idx]['constant']['resolution'])
948  self.__writeTagWithValue('color', constants[idx]['constant']['color'], format = 's')
949  self.indent -= 4
950  self.file.write('%s</plane>\n' % (' ' * self.indent))
951  self.indent -= 4
952  self.file.write('%s</constant_planes>\n' % (' ' * self.indent))
953  self.indent -= 4
954 
955  self.file.write('%s</nviz_state>\n' % (' ' * self.indent))
956  self.indent -= 4
957 
958  def __writeTagWithValue(self, tag, data, format = 'd'):
959  """!Helper function for writing pair tag
960 
961  @param tag written tag
962  @param data written data
963  @param format conversion type
964  """
965  self.file.write('%s<%s>\n' % (' ' * self.indent, tag))
966  self.indent += 4
967  self.file.write('%s' % (' ' * self.indent))
968  self.file.write(('<value>%' + format + '</value>\n') % data)
969  self.indent -= 4
970  self.file.write('%s</%s>\n' % (' ' * self.indent, tag))
971 
972 class ProcessGrcFile(object):
973  def __init__(self, filename):
974  """!Process GRC file"""
975  self.filename = filename
976 
977  # elements
978  self.inGroup = False
979  self.inRaster = False
980  self.inVector = False
981 
982  # list of layers
983  self.layers = []
984 
985  # error message
986  self.error = ''
987  self.num_error = 0
988 
989  def read(self, parent):
990  """!Read GRC file
991 
992  @param parent parent window
993 
994  @return list of map layers
995  """
996  try:
997  file = open(self.filename, "r")
998  except IOError:
999  wx.MessageBox(parent=parent,
1000  message=_("Unable to open file <%s> for reading.") % self.filename,
1001  caption=_("Error"), style=wx.OK | wx.ICON_ERROR)
1002  return []
1003 
1004  line_id = 1
1005  for line in file.readlines():
1006  self.process_line(line.rstrip('\n'), line_id)
1007  line_id +=1
1008 
1009  file.close()
1010 
1011  if self.num_error > 0:
1012  wx.MessageBox(parent=parent,
1013  message=_("Some lines were skipped when reading settings "
1014  "from file <%(file)s>.\nSee 'Command output' window for details.\n\n"
1015  "Number of skipped lines: %(line)d") % \
1016  { 'file' : self.filename, 'line' : self.num_error },
1017  caption=_("Warning"), style=wx.OK | wx.ICON_EXCLAMATION)
1018  parent.goutput.WriteLog('Map layers loaded from GRC file <%s>' % self.filename)
1019  parent.goutput.WriteLog('Skipped lines:\n%s' % self.error)
1020 
1021  return self.layers
1022 
1023  def process_line(self, line, line_id):
1024  """!Process line definition"""
1025  element = self._get_element(line)
1026  if element == 'Group':
1027  self.groupName = self._get_value(line)
1028  self.layers.append({
1029  "type" : 'group',
1030  "name" : self.groupName,
1031  "checked" : None,
1032  "opacity" : None,
1033  "cmd" : None,
1034  "group" : self.inGroup,
1035  "display" : 0 })
1036  self.inGroup = True
1037 
1038  elif element == '_check':
1039  if int(self._get_value(line)) == 1:
1040  self.layers[-1]['checked'] = True
1041  else:
1042  self.layers[-1]['checked'] = False
1043 
1044  elif element == 'End':
1045  if self.inRaster:
1046  self.inRaster = False
1047  elif self.inVector:
1048  self.inVector = False
1049  elif self.inGroup:
1050  self.inGroup = False
1051  elif self.inGridline:
1052  self.inGridline = False
1053 
1054  elif element == 'opacity':
1055  self.layers[-1]['opacity'] = float(self._get_value(line))
1056 
1057  # raster
1058  elif element == 'Raster':
1059  self.inRaster = True
1060  self.layers.append({
1061  "type" : 'raster',
1062  "name" : self._get_value(line),
1063  "checked" : None,
1064  "opacity" : None,
1065  "cmd" : ['d.rast'],
1066  "group" : self.inGroup,
1067  "display" : 0})
1068 
1069  elif element == 'map' and self.inRaster:
1070  self.layers[-1]['cmd'].append('map=%s' % self._get_value(line))
1071 
1072  elif element == 'overlay' and self.inRaster:
1073  if int(self._get_value(line)) == 1:
1074  self.layers[-1]['cmd'].append('-o')
1075 
1076  elif element == 'rastquery' and self.inRaster:
1077  value = self._get_value(line)
1078  if value != '':
1079  self.layers[-1]['cmd'].append('catlist=%s' % value)
1080 
1081  elif element == 'bkcolor' and self.inRaster:
1082  value = self._get_value(line)
1083  if value != '':
1084  self.layers[-1]['cmd'].append('bg=%s' % value)
1085 
1086  # vector
1087  elif element == 'Vector':
1088  self.inVector = True
1089  self.layers.append({
1090  "type" : 'vector',
1091  "name" : self._get_value(line),
1092  "checked" : None,
1093  "opacity" : None,
1094  "cmd" : ['d.vect'],
1095  "group" : self.inGroup,
1096  "display" : 0})
1097 
1098  elif element == 'vect' and self.inVector:
1099  self.layers[-1]['cmd'].append('map=%s' % self._get_value(line))
1100 
1101  elif element in ('display_shape',
1102  'display_cat',
1103  'display_topo',
1104  'display_dir',
1105  'display_attr',
1106  'type_point',
1107  'type_line',
1108  'type_boundary',
1109  'type_centroid',
1110  'type_area',
1111  'type_face') and self.inVector:
1112 
1113  if int(self._get_value(line)) == 1:
1114  name = element.split('_')[0]
1115  type = element.split('_')[1]
1116  paramId = self._get_cmd_param_index(self.layers[-1]['cmd'], name)
1117  if paramId == -1:
1118  self.layers[-1]['cmd'].append('%s=%s' % (name, type))
1119  else:
1120  self.layers[-1]['cmd'][paramId] += ',%s' % type
1121 
1122  elif element in ('color',
1123  'fcolor',
1124  'lcolor') and self.inVector:
1125  value = self._get_value(line)
1126  if value != '':
1127  self.layers[-1]['cmd'].append('%s=%s' % (element,
1128  self._color_name_to_rgb(value)))
1129 
1130  elif element == 'rdmcolor' and self.inVector:
1131  if int(self._get_value(line)) == 1:
1132  self.layers[-1]['cmd'].append('-c')
1133 
1134  elif element == 'sqlcolor' and self.inVector:
1135  if int(self._get_value(line)) == 1:
1136  self.layers[-1]['cmd'].append('-a')
1137 
1138  elif element in ('icon',
1139  'size',
1140  'layer',
1141  'xref',
1142  'yref',
1143  'lsize',
1144  'where',
1145  'minreg',
1146  'maxreg') and self.inVector:
1147  value = self._get_value(line)
1148  if value != '':
1149  self.layers[-1]['cmd'].append('%s=%s' % (element,
1150  value))
1151 
1152  elif element == 'lwidth':
1153  value = self._get_value(line)
1154  if value != '':
1155  self.layers[-1]['cmd'].append('width=%s' % value)
1156 
1157  elif element == 'lfield':
1158  value = self._get_value(line)
1159  if value != '':
1160  self.layers[-1]['cmd'].append('llayer=%s' % value)
1161 
1162  elif element == 'attribute':
1163  value = self._get_value(line)
1164  if value != '':
1165  self.layers[-1]['cmd'].append('attrcol=%s' % value)
1166 
1167  elif element == 'cat':
1168  value = self._get_value(line)
1169  if value != '':
1170  self.layers[-1]['cmd'].append('cats=%s' % value)
1171 
1172  # gridline
1173  elif element == 'gridline':
1174  self.inGridline = True
1175  self.layers.append({
1176  "type" : 'grid',
1177  "name" : self._get_value(line),
1178  "checked" : None,
1179  "opacity" : None,
1180  "cmd" : ['d.grid'],
1181  "group" : self.inGroup,
1182  "display" : 0})
1183 
1184  elif element == 'gridcolor':
1185  value = self._get_value(line)
1186  if value != '':
1187  self.layers[-1]['cmd'].append('color=%s' % self._color_name_to_rgb(value))
1188 
1189  elif element == 'gridborder':
1190  value = self._get_value(line)
1191  if value != '':
1192  self.layers[-1]['cmd'].append('bordercolor=%s' % self._color_name_to_rgb(value))
1193 
1194  elif element == 'textcolor':
1195  value = self._get_value(line)
1196  if value != '':
1197  self.layers[-1]['cmd'].append('textcolor=%s' % self._color_name_to_rgb(value))
1198 
1199  elif element in ('gridsize',
1200  'gridorigin'):
1201  value = self._get_value(line)
1202  if value != '':
1203  self.layers[-1]['cmd'].append('%s=%s' % (element[4:], value))
1204 
1205  elif element in 'fontsize':
1206  value = self._get_value(line)
1207  if value != '':
1208  self.layers[-1]['cmd'].append('%s=%s' % (element, value))
1209 
1210  elif element == 'griddraw':
1211  value = self._get_value(line)
1212  if value == '0':
1213  self.layers[-1]['cmd'].append('-n')
1214 
1215  elif element == 'gridgeo':
1216  value = self._get_value(line)
1217  if value == '1':
1218  self.layers[-1]['cmd'].append('-g')
1219 
1220  elif element == 'borderdraw':
1221  value = self._get_value(line)
1222  if value == '0':
1223  self.layers[-1]['cmd'].append('-b')
1224 
1225  elif element == 'textdraw':
1226  value = self._get_value(line)
1227  if value == '0':
1228  self.layers[-1]['cmd'].append('-t')
1229 
1230  else:
1231  self.error += _(' row %d:') % line_id + line + os.linesep
1232  self.num_error += 1
1233 
1234  def _get_value(self, line):
1235  """!Get value of element"""
1236  try:
1237  return line.strip(' ').split(' ')[1].strip(' ')
1238  except:
1239  return ''
1240 
1241  def _get_element(self, line):
1242  """!Get element tag"""
1243  return line.strip(' ').split(' ')[0].strip(' ')
1244 
1245  def _get_cmd_param_index(self, cmd, name):
1246  """!Get index of parameter in cmd list
1247 
1248  @param cmd cmd list
1249  @param name parameter name
1250 
1251  @return index
1252  @return -1 if not found
1253  """
1254  i = 0
1255  for param in cmd:
1256  if '=' not in param:
1257  i += 1
1258  continue
1259  if param.split('=')[0] == name:
1260  return i
1261 
1262  i += 1
1263 
1264  return -1
1265 
1266  def _color_name_to_rgb(self, value):
1267  """!Convert color name (#) to rgb values"""
1268  col = wx.NamedColour(value)
1269  return str(col.Red()) + ':' + \
1270  str(col.Green()) + ':' + \
1271  str(col.Blue())
def __init__(self, tree)
A ElementTree handler for the GXW XML file, as defined in grass-gxw.dtd.
def __writeNvizState(self, view, iview, light, constants)
def _get_value(self, line)
Get value of element.
wxGUI command interface
def __processLayerNvizNode
Process given tag nviz/vector.
def read(self, parent)
Read GRC file.
def process_line(self, line, line_id)
Process line definition.
def __writeTagWithValue
Helper function for writing pair tag.
def __filterValue(self, value)
Make value XML-valid.
def __writeNvizSurface(self, data)
Save Nviz raster layer properties to workspace.
def __processLayerNviz(self, node_nviz)
Process 3D layer settings.
def __writeNvizVector(self, data)
Save Nviz vector layer properties (lines/points) to workspace.
Nviz (3D view) module.
def split(s)
Platform spefic shlex.split.
Definition: core/utils.py:37
def __processNvizState(self, node)
Process tag nviz_state.
def __processLayerVdigit(self, node_vdigit)
Process vector digitizer layer settings.
def __processFile(self)
Process workspace file.
def _color_name_to_rgb(self, value)
Convert color name (#) to rgb values.
def GetDefaultEncoding
Get default system encoding.
Definition: gcmd.py:709
def __init__(self, lmgr, file)
def __init__(self, filename)
Process GRC file.
def __processLayer(self, layer)
Process layer item.
Misc utilities for wxGUI.
def __filterValue(self, value)
Filter value.
def EncodeString(string)
Return encoded string using system locales.
Definition: gcmd.py:91
def normalize_whitespace(text)
Remove redundant whitespace from a string.
Definition: core/utils.py:33
def __processLayers
Process layers/groups of selected display.
Default GUI settings.
tuple range
Definition: tools.py:1406
def __writeLayer(self, mapTree, item)
Write bunch of layers to GRASS Workspace XML file.
Generic class for writing workspace file.
def __getNodeText
Get node text.
def _get_element(self, line)
Get element tag.
def _get_cmd_param_index(self, cmd, name)
Get index of parameter in cmd list.