GRASS Programmer's Manual  6.4.2(2012)
workspace.py
Go to the documentation of this file.
00001 """!
00002 @package workspace.py
00003 
00004 @brief Open/save workspace definition file
00005 
00006 Classes:
00007  - ProcessWorkspaceFile
00008  - Nviz
00009  - WriteWorkspaceFile
00010  - ProcessGrcFile
00011 
00012 (C) 2007-2010 by the GRASS Development Team
00013 This program is free software under the GNU General Public
00014 License (>=v2). Read the file COPYING that comes with GRASS
00015 for details.
00016 
00017 @author Martin Landa <landa.martin gmail.com>
00018 """
00019 
00020 import os
00021 import sys
00022 
00023 import wx
00024 
00025 ### for gxw (workspace file) parsering
00026 # xmlproc not available on Mac OS
00027 # from xml.parsers.xmlproc import xmlproc
00028 # from xml.parsers.xmlproc import xmlval
00029 # from xml.parsers.xmlproc import xmldtd
00030 try:
00031     import xml.etree.ElementTree as etree
00032 except ImportError:
00033     import elementtree.ElementTree as etree # Python <= 2.4
00034 
00035 import utils
00036 import globalvar
00037 from preferences import globalSettings as UserSettings
00038 
00039 try:
00040     import wxnviz
00041 except (ImportError, NameError):
00042     wxnviz = None
00043 
00044 class ProcessWorkspaceFile:
00045     def __init__(self, tree):
00046         """!A ElementTree handler for the GXW XML file, as defined in
00047         grass-gxw.dtd.
00048         """
00049         self.tree = tree
00050         self.root = self.tree.getroot()
00051         
00052         #
00053         # layer manager properties
00054         #
00055         self.layerManager = {}
00056         self.layerManager['pos']  = None # window position
00057         self.layerManager['size'] = None # window size
00058         
00059         #
00060         # list of mapdisplays
00061         #
00062         self.displays = []
00063         #
00064         # list of map layers
00065         #
00066         self.layers = []
00067         
00068         self.displayIndex = -1 # first display has index '0'
00069         
00070         self.__processFile()
00071         
00072         self.nvizDefault = Nviz()
00073         
00074     def __filterValue(self, value):
00075         """!Filter value
00076         
00077         @param value
00078         """
00079         value = value.replace('&lt;', '<')
00080         value = value.replace('&gt;', '>')
00081         
00082         return value
00083 
00084     def __getNodeText(self, node, tag, default = ''):
00085         """!Get node text"""
00086         p = node.find(tag)
00087         if p is not None:
00088             return utils.normalize_whitespace(p.text)
00089         
00090         return default
00091     
00092     def __processFile(self):
00093         """!Process workspace file"""
00094         #
00095         # layer manager
00096         #
00097         node_lm = self.root.find('layer_manager')
00098         if node_lm is not None:
00099             posAttr = node_lm.get('dim', '')
00100             if posAttr:
00101                 posVal = map(int, posAttr.split(','))
00102                 try:
00103                     self.layerManager['pos']  = (posVal[0], posVal[1])
00104                     self.layerManager['size'] = (posVal[2], posVal[3])
00105                 except:
00106                     pass
00107         
00108         #
00109         # displays
00110         #
00111         for display in self.root.findall('display'):
00112             self.displayIndex += 1
00113             
00114             # window position and size
00115             posAttr = display.get('dim', '')
00116             if posAttr:
00117                 posVal = map(int, posAttr.split(','))
00118                 try:
00119                     pos  = (posVal[0], posVal[1])
00120                     size = (posVal[2], posVal[3])
00121                 except:
00122                     pos  = None
00123                     size = None
00124             else:
00125                 pos  = None
00126                 size = None
00127             
00128             extentAttr = display.get('extent', '')
00129             if extentAttr:
00130                 # w, s, e, n
00131                 extent = map(float, extentAttr.split(','))
00132             else:
00133                 extent = None
00134             
00135             # projection
00136             node_projection = display.find('projection')
00137             if node_projection is not None:
00138                 projection = { 'enabled' : True,
00139                                'epsg' : node_projection.get('epsg', ''),
00140                                'proj' : self.__getNodeText(node_projection, 'value') }
00141             else:
00142                 projection = { 'enabled' : False }
00143             
00144             self.displays.append( {
00145                     "render"         : bool(int(display.get('render', "0"))),
00146                     "mode"           : int(display.get('mode', 0)),
00147                     "showCompExtent" : bool(int(display.get('showCompExtent', "0"))),
00148                     "pos"            : pos,
00149                     "size"           : size,
00150                     "extent"         : extent,
00151                     "constrainRes"   : bool(int(display.get('constrainRes', "0"))),
00152                     "projection"     : projection, } )
00153             
00154             # process all layers/groups in the display
00155             self.__processLayers(display)
00156 
00157     def __processLayers(self, node, inGroup = -1):
00158         """!Process layers/groups of selected display
00159         
00160         @param node display tree node
00161         @param inGroup in group -> index of group item otherwise -1
00162         """
00163         for item in node.getchildren():
00164             if item.tag == 'group':
00165                 # -> group
00166                 self.layers.append( {
00167                         "type"    : 'group',
00168                         "name"    : item.get('name', ''),
00169                         "checked" : bool(int(item.get('checked', "0"))),
00170                         "opacity" : None,
00171                         "cmd"     : None,
00172                         "group"   : inGroup,
00173                         "display" : self.displayIndex,
00174                         "vdigit"  : None,
00175                         "nviz"    : None})
00176                 
00177                 self.__processLayers(item, inGroup = len(self.layers) - 1) # process items in group
00178                 
00179             elif item.tag == 'layer':
00180                 cmd, selected, vdigit, nviz = self.__processLayer(item)
00181                 
00182                 self.layers.append( {
00183                         "type"     : item.get('type', None),
00184                         "name"     : item.get('name', None),
00185                         "checked"  : bool(int(item.get('checked', "0"))),
00186                         "opacity"  : float(item.get('opacity', '1.0')),
00187                         "cmd"      : cmd,
00188                         "group"    : inGroup,
00189                         "display"  : self.displayIndex,
00190                         "selected" : selected,
00191                         "vdigit"   : vdigit,
00192                         "nviz"     : nviz } )
00193             
00194     def __processLayer(self, layer):
00195         """!Process layer item
00196 
00197         @param layer tree node
00198         """
00199         cmd = list()
00200         
00201         #
00202         # layer attributes (task) - 2D settings
00203         #
00204         node_task = layer.find('task')
00205         cmd.append(node_task.get('name', "unknown"))
00206         
00207         # flags
00208         for p in node_task.findall('flag'):
00209             flag = p.get('name', '')
00210             if len(flag) > 1:
00211                 cmd.append('--' + flag)
00212             else:
00213                 cmd.append('-' + flag)
00214         
00215         # parameters
00216         for p in node_task.findall('parameter'):
00217             cmd.append('%s=%s' % (p.get('name', ''),
00218                                   self.__filterValue(self.__getNodeText(p, 'value'))))
00219         
00220         if layer.find('selected') is not None:
00221             selected = True
00222         else:
00223             selected = False
00224         
00225         #
00226         # Vector digitizer settings
00227         #
00228         node_vdigit = layer.find('vdigit')
00229         if node_vdigit is not None:
00230             vdigit = self.__processLayerVdigit(node_vdigit)
00231         else:
00232             vdigit = None
00233         
00234         #
00235         # Nviz (3D settings)
00236         #
00237         node_nviz = layer.find('nviz')
00238         if node_nviz is not None:
00239             nviz = self.__processLayerNviz(node_nviz)
00240         else:
00241             nviz = None
00242         
00243         return (cmd, selected, vdigit, nviz)
00244 
00245     def __processLayerVdigit(self, node_vdigit):
00246         """!Process vector digitizer layer settings
00247 
00248         @param node_vdigit vdigit node
00249         """
00250         # init nviz layer properties
00251         vdigit = dict()
00252         for node in node_vdigit.findall('geometryAttribute'):
00253             if 'geomAttr' not in vdigit:
00254                 vdigit['geomAttr'] = dict()
00255             type = node.get('type')
00256             vdigit['geomAttr'][type] = dict()
00257             vdigit['geomAttr'][type]['column'] = node.get('column') # required
00258             # default map units
00259             vdigit['geomAttr'][type]['units'] = node.get('units', 'mu')
00260         
00261         return vdigit
00262     
00263     def __processLayerNviz(self, node_nviz):
00264         """!Process 3D layer settings
00265 
00266         @param node_nviz nviz node
00267         """
00268         # init nviz layer properties
00269         nviz = {}
00270         if node_nviz.find('surface') is not None: # -> raster
00271             nviz['surface'] = {}
00272             for sec in ('attribute', 'draw', 'mask', 'position'):
00273                 nviz['surface'][sec] = {}
00274         elif node_nviz.find('vlines') is not None or \
00275                 node_nviz.find('vpoints') is not None: # -> vector
00276             nviz['vector'] = {}
00277             for sec in ('lines', 'points'):
00278                 nviz['vector'][sec] = {}
00279         
00280         if 'surface' in nviz:
00281             node_surface = node_nviz.find('surface')
00282             # attributes
00283             for attrb in node_surface.findall('attribute'):
00284                 tagName = str(attrb.tag)
00285                 attrbName = attrb.get('name', '')
00286                 dc = nviz['surface'][tagName][attrbName] = {}
00287                 if attrb.get('map', '0') == '0':
00288                     dc['map'] = False
00289                 else:
00290                     dc['map'] = True
00291                 value = self.__getNodeText(attrb, 'value')
00292                 try:
00293                     dc['value'] = int(value)
00294                 except ValueError:
00295                     try:
00296                         dc['value'] = float(value)
00297                     except ValueError:
00298                         dc['value'] = str(value)
00299             
00300             # draw
00301             node_draw = node_surface.find('draw')
00302             if node_draw is not None:
00303                 tagName = str(node_draw.tag)
00304                 nviz['surface'][tagName]['all'] = False
00305                 nviz['surface'][tagName]['mode'] = {}
00306                 nviz['surface'][tagName]['mode']['value'] = -1 # to be calculated
00307                 nviz['surface'][tagName]['mode']['desc'] = {}
00308                 nviz['surface'][tagName]['mode']['desc']['shading'] = \
00309                     str(node_draw.get('shading', ''))
00310                 nviz['surface'][tagName]['mode']['desc']['style'] = \
00311                     str(node_draw.get('style', ''))
00312                 nviz['surface'][tagName]['mode']['desc']['mode'] = \
00313                     str(node_draw.get('mode', ''))
00314                 
00315                 # resolution
00316                 for node_res in node_draw.findall('resolution'):
00317                     resType = str(node_res.get('type', ''))
00318                     if 'resolution' not in nviz['surface']['draw']:
00319                         nviz['surface']['draw']['resolution'] = {}
00320                     value = int(self.__getNodeText(node_res, 'value'))
00321                     nviz['surface']['draw']['resolution'][resType] = value
00322                 
00323                 # wire-color
00324                 node_wire_color = node_draw.find('wire_color')
00325                 if node_wire_color is not None:
00326                     nviz['surface']['draw']['wire-color'] = {}
00327                     value = str(self.__getNodeText(node_wire_color, 'value'))
00328                     nviz['surface']['draw']['wire-color']['value'] = value
00329                 
00330             # position
00331             node_pos = node_surface.find('position')
00332             if node_pos is not None:
00333                 dc = self.nviz['surface']['position'] = {}
00334                 for coor in ['x', 'y', 'z']:
00335                     node = node_pos.find(coor)
00336                     if node is None:
00337                         continue
00338                     value = int(self.__getNodeText(node, 'value'))
00339                     dc[coor] = value
00340             
00341         elif 'vector' in nviz:
00342             # vpoints
00343             node_vpoints = node_nviz.find('vpoints')
00344             if node_vpoints is not None:
00345                 marker = str(node_vpoints.get('marker', ''))
00346                 markerId = list(UserSettings.Get(group='nviz', key='vector',
00347                                                  subkey=['points', 'marker'], internal=True)).index(marker)
00348                 nviz['vector']['points']['marker'] = { 'value' : markerId }
00349                 
00350                 node_mode = node_vpoints.find('mode')
00351                 if node_mode is not None:
00352                     nviz['vector']['points']['mode'] = {}
00353                     nviz['vector']['points']['mode']['type'] = str(node_mode.get('type', ''))
00354                     nviz['vector']['points']['mode']['surface'] = \
00355                         self.__processLayerNvizNode(node_mode, 'map', str)
00356                 
00357                 # color
00358                 self.__processLayerNvizNode(node_vpoints, 'color', str,
00359                                             nviz['vector']['points'])
00360                 
00361                 # width
00362                 self.__processLayerNvizNode(node_vpoints, 'width', int,
00363                                             nviz['vector']['points'])
00364                 
00365                 # height
00366                 self.__processLayerNvizNode(node_vpoints, 'height', int,
00367                                             nviz['vector']['points'])
00368                 
00369                 # height
00370                 self.__processLayerNvizNode(node_vpoints, 'size', int,
00371                                             nviz['vector']['points'])
00372             
00373             # vlines
00374             node_vlines = node_nviz.find('vlines')
00375             if node_vlines is not None:
00376                 node_mode = node_vlines.find('mode')
00377                 if node_mode is not None:
00378                     nviz['vector']['lines']['mode'] = {}
00379                     nviz['vector']['lines']['mode']['type'] = str(node_mode.get('type', ''))
00380                     nviz['vector']['lines']['mode']['surface'] = ''
00381                     
00382                     # map
00383                     nviz['vector']['lines']['mode']['surface'] = \
00384                         self.__processLayerNvizNode(node_mode, 'map', str)
00385                 
00386                 # color
00387                 self.__processLayerNvizNode(node_vlines, 'color', str,
00388                                             nviz['vector']['lines'])
00389                 
00390                 # width
00391                 self.__processLayerNvizNode(node_vlines, 'width', int,
00392                                             nviz['vector']['lines'])
00393                 
00394                 # height
00395                 self.__processLayerNvizNode(node_vlines, 'height', int,
00396                                             nviz['vector']['lines'])
00397             
00398         return nviz
00399     
00400     def __processLayerNvizNode(self, node, tag, cast, dc = None):
00401         """!Process given tag nviz/vector"""
00402         node_tag = node.find(tag)
00403         if node_tag is not None:
00404             if node_tag.find('value') is not None:
00405                 value = cast(self.__getNodeText(node_tag, 'value'))
00406             else:
00407                 try:
00408                     value = cast(node_tag.text)
00409                 except ValueError:
00410                     if cast == str:
00411                         value = ''
00412                     else:
00413                         value = None
00414             if dc:
00415                 dc[tag] = dict()
00416                 dc[tag]['value'] = value
00417             else:
00418                 return value
00419     
00420 class Nviz:
00421     def __init__(self):
00422         """Default 3D settings"""
00423         pass
00424     
00425     def SetSurfaceDefaultProp(self):
00426         """Set default surface data properties"""
00427         data = dict()
00428         for sec in ('attribute', 'draw', 'mask', 'position'):
00429             data[sec] = {}
00430         
00431         #
00432         # attributes
00433         #
00434         for attrb in ('shine', ):
00435             data['attribute'][attrb] = {}
00436             for key, value in UserSettings.Get(group='nviz', key='volume',
00437                                                subkey=attrb).iteritems():
00438                 data['attribute'][attrb][key] = value
00439             data['attribute'][attrb]['update'] = None
00440         
00441         #
00442         # draw
00443         #
00444         data['draw']['all'] = False # apply only for current surface
00445         for control, value in UserSettings.Get(group='nviz', key='surface', subkey='draw').iteritems():
00446             if control[:3] == 'res':
00447                 if 'resolution' not in data['draw']:
00448                     data['draw']['resolution'] = {}
00449                 if 'update' not in data['draw']['resolution']:
00450                     data['draw']['resolution']['update'] = None
00451                 data['draw']['resolution'][control[4:]] = value
00452                 continue
00453             
00454             if control == 'wire-color':
00455                 value = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
00456             elif control in ('mode', 'style', 'shading'):
00457                 if 'mode' not in data['draw']:
00458                     data['draw']['mode'] = {}
00459                 continue
00460 
00461             data['draw'][control] = { 'value' : value }
00462             data['draw'][control]['update'] = None
00463         
00464         value, desc = self.GetDrawMode(UserSettings.Get(group='nviz', key='surface', subkey=['draw', 'mode']),
00465                                        UserSettings.Get(group='nviz', key='surface', subkey=['draw', 'style']),
00466                                        UserSettings.Get(group='nviz', key='surface', subkey=['draw', 'shading']))
00467     
00468         data['draw']['mode'] = { 'value' : value,
00469                                  'desc' : desc, 
00470                                  'update': None }
00471         
00472         return data
00473     
00474     def SetVolumeDefaultProp(self):
00475         """Set default volume data properties"""
00476         data = dict()
00477         for sec in ('attribute', 'draw', 'position'):
00478             data[sec] = dict()
00479             for sec in ('isosurface', 'slice'):
00480                     data[sec] = list()
00481         
00482         #
00483         # draw
00484         #
00485         for control, value in UserSettings.Get(group='nviz', key='volume', subkey='draw').iteritems():
00486             if control == 'mode':
00487                 continue
00488             if control == 'shading':
00489                 sel = UserSettings.Get(group='nviz', key='surface', subkey=['draw', 'shading'])
00490                 value, desc = self.GetDrawMode(shade=sel, string=False)
00491 
00492                 data['draw']['shading'] = { 'value' : value,
00493                                             'desc' : desc['shading'] }
00494             elif control == 'mode':
00495                 sel = UserSettings.Get(group='nviz', key='volume', subkey=['draw', 'mode'])
00496                 if sel == 0:
00497                     desc = 'isosurface'
00498                 else:
00499                     desc = 'slice'
00500                 data['draw']['mode'] = { 'value' : sel,
00501                                          'desc' : desc, }
00502             else:
00503                 data['draw'][control] = { 'value' : value }
00504 
00505             if 'update' not in data['draw'][control]:
00506                 data['draw'][control]['update'] = None
00507         
00508         #
00509         # isosurface attributes
00510         #
00511         for attrb in ('shine', ):
00512             data['attribute'][attrb] = {}
00513             for key, value in UserSettings.Get(group='nviz', key='volume',
00514                                                subkey=attrb).iteritems():
00515                 data['attribute'][attrb][key] = value
00516         
00517         return data
00518     
00519     def SetVectorDefaultProp(self):
00520         """Set default vector data properties"""
00521         data = dict()
00522         for sec in ('lines', 'points'):
00523             data[sec] = {}
00524         
00525         self.SetVectorLinesDefaultProp(data['lines'])
00526         self.SetVectorPointsDefaultProp(data['points'])
00527 
00528         return data
00529     
00530     def SetVectorLinesDefaultProp(self, data):
00531         """Set default vector properties -- lines"""
00532         # width
00533         data['width'] = {'value' : UserSettings.Get(group='nviz', key='vector',
00534                                                     subkey=['lines', 'width']) }
00535         
00536         # color
00537         value = UserSettings.Get(group='nviz', key='vector',
00538                                  subkey=['lines', 'color'])
00539         color = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
00540         data['color'] = { 'value' : color }
00541 
00542         # mode
00543         if UserSettings.Get(group='nviz', key='vector',
00544                             subkey=['lines', 'flat']):
00545             type = 'flat'
00546             map  = None
00547         else:
00548             type = 'flat'
00549             map = None
00550 
00551         data['mode'] = {}
00552         data['mode']['type'] = type
00553         data['mode']['update'] = None
00554         if map:
00555             data['mode']['surface'] = map
00556 
00557         # height
00558         data['height'] = { 'value' : UserSettings.Get(group='nviz', key='vector',
00559                                                       subkey=['lines', 'height']) }
00560 
00561         if 'object' in data:
00562             for attrb in ('color', 'width', 'mode', 'height'):
00563                 data[attrb]['update'] = None
00564         
00565     def SetVectorPointsDefaultProp(self, data):
00566         """Set default vector properties -- points"""
00567         # size
00568         data['size'] = { 'value' : UserSettings.Get(group='nviz', key='vector',
00569                                                     subkey=['points', 'size']) }
00570 
00571         # width
00572         data['width'] = { 'value' : UserSettings.Get(group='nviz', key='vector',
00573                                                      subkey=['points', 'width']) }
00574 
00575         # marker
00576         data['marker'] = { 'value' : UserSettings.Get(group='nviz', key='vector',
00577                                                       subkey=['points', 'marker']) }
00578 
00579         # color
00580         value = UserSettings.Get(group='nviz', key='vector',
00581                                  subkey=['points', 'color'])
00582         color = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
00583         data['color'] = { 'value' : color }
00584 
00585         # mode
00586         data['mode'] = { 'type' : 'surface',
00587                          'surface' : '', }
00588         
00589         # height
00590         data['height'] = { 'value' : UserSettings.Get(group='nviz', key='vector',
00591                                                       subkey=['points', 'height']) }
00592 
00593         if 'object' in data:
00594             for attrb in ('size', 'width', 'marker',
00595                           'color', 'surface', 'height'):
00596                 data[attrb]['update'] = None
00597         
00598     def GetDrawMode(self, mode=None, style=None, shade=None, string=False):
00599         """Get surface draw mode (value) from description/selection
00600 
00601         @param mode,style,shade modes
00602         @param string if True input parameters are strings otherwise
00603         selections
00604         """
00605         if not wxnviz:
00606             return None
00607         
00608         value = 0
00609         desc = {}
00610 
00611         if string:
00612             if mode is not None:
00613                 if mode == 'coarse':
00614                     value |= wxnviz.DM_WIRE
00615                 elif mode == 'fine':
00616                     value |= wxnviz.DM_POLY
00617                 else: # both
00618                     value |= wxnviz.DM_WIRE_POLY
00619 
00620             if style is not None:
00621                 if style == 'wire':
00622                     value |= wxnviz.DM_GRID_WIRE
00623                 else: # surface
00624                     value |= wxnviz.DM_GRID_SURF
00625                     
00626             if shade is not None:
00627                 if shade == 'flat':
00628                     value |= wxnviz.DM_FLAT
00629                 else: # surface
00630                     value |= wxnviz.DM_GOURAUD
00631 
00632             return value
00633 
00634         # -> string is False
00635         if mode is not None:
00636             if mode == 0: # coarse
00637                 value |= wxnviz.DM_WIRE
00638                 desc['mode'] = 'coarse'
00639             elif mode == 1: # fine
00640                 value |= wxnviz.DM_POLY
00641                 desc['mode'] = 'fine'
00642             else: # both
00643                 value |= wxnviz.DM_WIRE_POLY
00644                 desc['mode'] = 'both'
00645 
00646         if style is not None:
00647             if style == 0: # wire
00648                 value |= wxnviz.DM_GRID_WIRE
00649                 desc['style'] = 'wire'
00650             else: # surface
00651                 value |= wxnviz.DM_GRID_SURF
00652                 desc['style'] = 'surface'
00653 
00654         if shade is not None:
00655             if shade == 0:
00656                 value |= wxnviz.DM_FLAT
00657                 desc['shading'] = 'flat'
00658             else: # surface
00659                 value |= wxnviz.DM_GOURAUD
00660                 desc['shading'] = 'gouraud'
00661         
00662         return (value, desc)
00663     
00664 class WriteWorkspaceFile(object):
00665     """!Generic class for writing workspace file"""
00666     def __init__(self, lmgr, file):
00667         self.file =  file
00668         self.lmgr = lmgr
00669         self.indent = 0
00670         
00671         # write header
00672         self.file.write('<?xml version="1.0" encoding="UTF-8"?>\n')
00673         self.file.write('<!DOCTYPE gxw SYSTEM "grass-gxw.dtd">\n')
00674         self.file.write('%s<gxw>\n' % (' ' * self.indent))
00675         
00676         self.indent =+ 4
00677         
00678         # layer manager
00679         windowPos = self.lmgr.GetPosition()
00680         windowSize = self.lmgr.GetSize()
00681         file.write('%s<layer_manager dim="%d,%d,%d,%d">\n' % (' ' * self.indent,
00682                                                               windowPos[0],
00683                                                               windowPos[1],
00684                                                               windowSize[0],
00685                                                               windowSize[1]
00686                                                               ))
00687         
00688         file.write('%s</layer_manager>\n' % (' ' * self.indent))
00689         
00690         # list of displays
00691         for page in range(0, self.lmgr.gm_cb.GetPageCount()):
00692             mapTree = self.lmgr.gm_cb.GetPage(page).maptree
00693             region = mapTree.Map.region
00694             
00695             displayPos = mapTree.mapdisplay.GetPosition()
00696             displaySize = mapTree.mapdisplay.GetSize()
00697             
00698             file.write('%s<display render="%d" '
00699                        'mode="%d" showCompExtent="%d" '
00700                        'constrainRes="%d" '
00701                        'dim="%d,%d,%d,%d" '
00702                        'extent="%f,%f,%f,%f">\n' % (' ' * self.indent,
00703                                                     int(mapTree.mapdisplay.statusbarWin['render'].IsChecked()),
00704                                                     mapTree.mapdisplay.statusbarWin['toggle'].GetSelection(),
00705                                                     int(mapTree.mapdisplay.statusbarWin['region'].IsChecked()),
00706                                                     int(mapTree.mapdisplay.statusbarWin['resolution'].IsChecked()),
00707                                                     displayPos[0],
00708                                                     displayPos[1],
00709                                                     displaySize[0],
00710                                                     displaySize[1],
00711                                                     region['w'],
00712                                                     region['s'],
00713                                                     region['e'],
00714                                                     region['n']
00715                                                     ))
00716             # projection statusbar info
00717             if mapTree.mapdisplay.statusbarWin['projection'].IsChecked() and \
00718                     UserSettings.Get(group='display', key='projection', subkey='proj4'):
00719                 self.indent += 4
00720                 file.write('%s<projection' % (' ' * self.indent))
00721                 epsg = UserSettings.Get(group='display', key='projection', subkey='epsg')
00722                 if epsg:
00723                     file.write(' epsg="%s"' % epsg)
00724                 file.write('>\n')
00725                 proj = UserSettings.Get(group='display', key='projection', subkey='proj4')
00726                 self.indent += 4 
00727                 file.write('%s<value>%s</value>\n' % (' ' * self.indent, proj))
00728                 self.indent -= 4
00729                 file.write('%s</projection>\n' % (' ' * self.indent))
00730                 self.indent -= 4
00731             
00732             # list of layers
00733             item = mapTree.GetFirstChild(mapTree.root)[0]
00734             self.__writeLayer(mapTree, item)
00735             file.write('%s</display>\n' % (' ' * self.indent))
00736         
00737         self.indent =- 4
00738         file.write('%s</gxw>\n' % (' ' * self.indent))
00739 
00740     def __filterValue(self, value):
00741         """!Make value XML-valid"""
00742         value = value.replace('<', '&lt;')
00743         value = value.replace('>', '&gt;')
00744         
00745         return value
00746     
00747     def __writeLayer(self, mapTree, item):
00748         """!Write bunch of layers to GRASS Workspace XML file"""
00749         self.indent += 4
00750         itemSelected = mapTree.GetSelections()
00751         while item and item.IsOk():
00752             type = mapTree.GetPyData(item)[0]['type']
00753             if type != 'group':
00754                 maplayer = mapTree.GetPyData(item)[0]['maplayer']
00755             else:
00756                 maplayer = None
00757 
00758             checked = int(item.IsChecked())
00759             if type == 'command':
00760                 cmd = mapTree.GetPyData(item)[0]['maplayer'].GetCmd(string=True)
00761                 self.file.write('%s<layer type="%s" name="%s" checked="%d">\n' % \
00762                                (' ' * self.indent, type, cmd, checked));
00763                 self.file.write('%s</layer>\n' % (' ' * self.indent));
00764             elif type == 'group':
00765                 name = mapTree.GetItemText(item)
00766                 self.file.write('%s<group name="%s" checked="%d">\n' % \
00767                                (' ' * self.indent, name.encode('utf8'), checked));
00768                 self.indent += 4
00769                 subItem = mapTree.GetFirstChild(item)[0]
00770                 self.__writeLayer(mapTree, subItem)
00771                 self.indent -= 4
00772                 self.file.write('%s</group>\n' % (' ' * self.indent));
00773             else:
00774                 cmd = mapTree.GetPyData(item)[0]['maplayer'].GetCmd(string=False)
00775                 name = mapTree.GetItemText(item)
00776                 opacity = maplayer.GetOpacity(float = True)
00777                 # remove 'opacity' part
00778                 if opacity < 1:
00779                     name = name.split('(', -1)[0].strip()
00780                 self.file.write('%s<layer type="%s" name="%s" checked="%d" opacity="%f">\n' % \
00781                                     (' ' * self.indent, type, name.encode('utf8'), checked, opacity));
00782                 
00783                 self.indent += 4
00784                 # selected ?
00785                 if item in itemSelected:
00786                     self.file.write('%s<selected />\n' % (' ' * self.indent))
00787                 # layer properties
00788                 self.file.write('%s<task name="%s">\n' % (' ' * self.indent, cmd[0]))
00789                 self.indent += 4
00790                 for key, val in cmd[1].iteritems():
00791                     if key == 'flags':
00792                         for f in val:
00793                             self.file.write('%s<flag name="%s" />\n' %
00794                                             (' ' * self.indent, f))
00795                     elif val in (True, False):
00796                         self.file.write('%s<flag name="%s" />\n' %
00797                                         (' ' * self.indent, key))
00798                     else: # parameter
00799                         self.file.write('%s<parameter name="%s">\n' %
00800                                         (' ' * self.indent, key))
00801                         self.indent += 4
00802                         self.file.write('%s<value>%s</value>\n' %
00803                                         (' ' * self.indent, self.__filterValue(val)))
00804                         self.indent -= 4
00805                         self.file.write('%s</parameter>\n' % (' ' * self.indent));
00806                 self.indent -= 4
00807                 self.file.write('%s</task>\n' % (' ' * self.indent));
00808                 # vector digitizer
00809                 vdigit = mapTree.GetPyData(item)[0]['vdigit']
00810                 if vdigit:
00811                     self.file.write('%s<vdigit>\n' % (' ' * self.indent))
00812                     if 'geomAttr' in vdigit:
00813                         self.indent += 4
00814                         for type, val in vdigit['geomAttr'].iteritems():
00815                             units = ''
00816                             if val['units'] != 'mu':
00817                                 units = ' units="%s"' % val['units']
00818                             self.file.write('%s<geometryAttribute type="%s" column="%s"%s />\n' % \
00819                                                 (' ' * self.indent, type, val['column'], units))
00820                         self.indent -= 4
00821                     self.file.write('%s</vdigit>\n' % (' ' * self.indent))
00822                 # nviz
00823                 nviz = mapTree.GetPyData(item)[0]['nviz']
00824                 if nviz:
00825                     self.file.write('%s<nviz>\n' % (' ' * self.indent))
00826                     if maplayer.type == 'raster':
00827                         self.__writeNvizSurface(nviz['surface'])
00828                     elif maplayer.type == 'vector':
00829                         self.__writeNvizVector(nviz['vector'])
00830                     self.file.write('%s</nviz>\n' % (' ' * self.indent))
00831                 self.indent -= 4
00832                 self.file.write('%s</layer>\n' % (' ' * self.indent))
00833             item = mapTree.GetNextSibling(item)
00834         self.indent -= 4
00835         
00836     def __writeNvizSurface(self, data):
00837         """!Save Nviz raster layer properties to workspace
00838 
00839         @param data Nviz layer properties
00840         """
00841         if 'object' not in data: # skip disabled
00842             return
00843 
00844         self.indent += 4
00845         self.file.write('%s<surface>\n' % (' ' * self.indent))
00846         self.indent += 4
00847         for attrb in data.iterkeys():
00848             if len(data[attrb]) < 1: # skip empty attributes
00849                 continue
00850             if attrb == 'object':
00851                 continue
00852             
00853             for name in data[attrb].iterkeys():
00854                 # surface attribute
00855                 if attrb == 'attribute':
00856                     self.file.write('%s<%s name="%s" map="%d">\n' % \
00857                                    (' ' * self.indent, attrb, name, data[attrb][name]['map']))
00858                     self.indent += 4
00859                     self.file.write('%s<value>%s</value>\n' % (' ' * self.indent, data[attrb][name]['value']))
00860                     self.indent -= 4
00861                     # end tag
00862                     self.file.write('%s</%s>\n' % (' ' * self.indent, attrb))
00863 
00864             # draw mode
00865             if attrb == 'draw':
00866                 self.file.write('%s<%s' %(' ' * self.indent, attrb))
00867                 if 'mode' in data[attrb]:
00868                     for tag, value in data[attrb]['mode']['desc'].iteritems():
00869                         self.file.write(' %s="%s"' % (tag, value))
00870                 self.file.write('>\n') # <draw ...>
00871 
00872                 if 'resolution' in data[attrb]:
00873                     self.indent += 4
00874                     for type in ('coarse', 'fine'):
00875                         self.file.write('%s<resolution type="%s">\n' % (' ' * self.indent, type))
00876                         self.indent += 4
00877                         self.file.write('%s<value>%d</value>\n' % (' ' * self.indent,
00878                                                                    data[attrb]['resolution'][type]))
00879                         self.indent -= 4
00880                         self.file.write('%s</resolution>\n' % (' ' * self.indent))
00881 
00882                 if 'wire-color' in data[attrb]:
00883                     self.file.write('%s<wire_color>\n' % (' ' * self.indent))
00884                     self.indent += 4
00885                     self.file.write('%s<value>%s</value>\n' % (' ' * self.indent,
00886                                                                data[attrb]['wire-color']['value']))
00887                     self.indent -= 4
00888                     self.file.write('%s</wire_color>\n' % (' ' * self.indent))
00889                 self.indent -= 4
00890             
00891             # position
00892             elif attrb == 'position':
00893                 self.file.write('%s<%s>\n' %(' ' * self.indent, attrb))
00894                 i = 0
00895                 for tag in ('x', 'y', 'z'):
00896                     self.indent += 4
00897                     self.file.write('%s<%s>%d</%s>\n' % (' ' * self.indent, tag,
00898                                                         data[attrb][tag], tag))
00899                     i += 1
00900                     self.indent -= 4
00901 
00902             if attrb != 'attribute':
00903                 # end tag
00904                 self.file.write('%s</%s>\n' % (' ' * self.indent, attrb))
00905 
00906         self.indent -= 4
00907         self.file.write('%s</surface>\n' % (' ' * self.indent))
00908         self.indent -= 4
00909 
00910     def __writeNvizVector(self, data):
00911         """!Save Nviz vector layer properties (lines/points) to workspace
00912 
00913         @param data Nviz layer properties
00914         """
00915         self.indent += 4
00916         for attrb in data.iterkeys():
00917             if len(data[attrb]) < 1: # skip empty attributes
00918                 continue
00919 
00920             if 'object' not in data[attrb]: # skip disabled
00921                 continue
00922             if attrb == 'lines':
00923                 self.file.write('%s<v%s>\n' % (' ' * self.indent, attrb))
00924             elif attrb == 'points':
00925                 markerId = data[attrb]['marker']['value']
00926                 marker = UserSettings.Get(group = 'nviz', key = 'vector',
00927                                           subkey = ['points', 'marker'], internal = True)[markerId]
00928                 self.file.write('%s<v%s marker="%s">\n' % (' ' * self.indent,
00929                                                            attrb,
00930                                                            marker))
00931             self.indent += 4
00932             for name in data[attrb].iterkeys():
00933                 if name in ('object', 'marker'):
00934                     continue
00935                 if name == 'mode':
00936                     self.file.write('%s<%s type="%s">\n' % (' ' * self.indent, name,
00937                                                           data[attrb][name]['type']))
00938                     if data[attrb][name]['type'] == 'surface':
00939                         self.indent += 4
00940                         self.file.write('%s<map>%s</map>\n' % (' ' * self.indent,
00941                                                                data[attrb][name]['surface']))
00942                         self.indent -= 4
00943                     self.file.write('%s</%s>\n' % ((' ' * self.indent, name)))
00944                 else:
00945                     self.file.write('%s<%s>\n' % (' ' * self.indent, name))
00946                     self.indent += 4
00947                     self.file.write('%s<value>%s</value>\n' % (' ' * self.indent, data[attrb][name]['value']))
00948                     self.indent -= 4
00949                     self.file.write('%s</%s>\n' % (' ' * self.indent, name))
00950             self.indent -= 4
00951             self.file.write('%s</v%s>\n' % (' ' * self.indent, attrb))
00952 
00953         self.indent -= 4
00954 
00955 class ProcessGrcFile(object):
00956     def __init__(self, filename):
00957         """!Process GRC file"""
00958         self.filename = filename
00959 
00960         # elements
00961         self.inGroup = False
00962         self.inRaster = False
00963         self.inVector = False
00964 
00965         # list of layers
00966         self.layers = []
00967 
00968         # error message
00969         self.error = ''
00970         self.num_error = 0
00971 
00972     def read(self, parent):
00973         """!Read GRC file
00974 
00975         @param parent parent window
00976 
00977         @return list of map layers
00978         """
00979         try:
00980             file = open(self.filename, "r")
00981         except IOError:
00982             wx.MessageBox(parent=parent,
00983                           message=_("Unable to open file <%s> for reading.") % self.filename,
00984                           caption=_("Error"), style=wx.OK | wx.ICON_ERROR)
00985             return []
00986 
00987         line_id = 1
00988         for line in file.readlines():
00989             self.process_line(line.rstrip('\n'), line_id)
00990             line_id +=1
00991 
00992         file.close()
00993 
00994         if self.num_error > 0:
00995             wx.MessageBox(parent=parent,
00996                           message=_("Some lines were skipped when reading settings "
00997                                     "from file <%(file)s>.\nSee 'Command output' window for details.\n\n"
00998                                     "Number of skipped lines: %(line)d") % \
00999                                         { 'file' : self.filename, 'line' : self.num_error },
01000                           caption=_("Warning"), style=wx.OK | wx.ICON_EXCLAMATION)
01001             parent.goutput.WriteLog('Map layers loaded from GRC file <%s>' % self.filename)
01002             parent.goutput.WriteLog('Skipped lines:\n%s' % self.error)
01003 
01004         return self.layers
01005 
01006     def process_line(self, line, line_id):
01007         """!Process line definition"""
01008         element = self._get_element(line)
01009         if element == 'Group':
01010             self.groupName = self._get_value(line)
01011             self.layers.append({
01012                     "type"    : 'group',
01013                     "name"    : self.groupName,
01014                     "checked" : None,
01015                     "opacity" : None,
01016                     "cmd"     : None,
01017                     "group"   : self.inGroup,
01018                     "display" : 0 })
01019             self.inGroup = True
01020 
01021         elif element == '_check':
01022             if int(self._get_value(line)) ==  1:
01023                 self.layers[-1]['checked'] = True
01024             else:
01025                 self.layers[-1]['checked'] = False
01026             
01027         elif element == 'End':
01028             if self.inRaster:
01029                 self.inRaster = False
01030             elif self.inVector:
01031                 self.inVector = False
01032             elif self.inGroup:
01033                 self.inGroup = False
01034             elif self.inGridline:
01035                 self.inGridline = False
01036         
01037         elif element == 'opacity':
01038             self.layers[-1]['opacity'] = float(self._get_value(line))
01039 
01040         # raster
01041         elif element == 'Raster':
01042             self.inRaster = True
01043             self.layers.append({
01044                     "type"    : 'raster',
01045                     "name"    : self._get_value(line),
01046                     "checked" : None,
01047                     "opacity" : None,
01048                     "cmd"     : ['d.rast'],
01049                     "group"   : self.inGroup,
01050                     "display" : 0})
01051 
01052         elif element == 'map' and self.inRaster:
01053             self.layers[-1]['cmd'].append('map=%s' % self._get_value(line))
01054             
01055         elif element == 'overlay' and self.inRaster:
01056             if int(self._get_value(line)) == 1:
01057                 self.layers[-1]['cmd'].append('-o')
01058             
01059         elif element == 'rastquery' and self.inRaster:
01060             value = self._get_value(line)
01061             if value != '':
01062                 self.layers[-1]['cmd'].append('catlist=%s' % value)
01063             
01064         elif element == 'bkcolor' and self.inRaster:
01065             value = self._get_value(line)
01066             if value != '':
01067                 self.layers[-1]['cmd'].append('bg=%s' % value)
01068 
01069         # vector
01070         elif element == 'Vector':
01071             self.inVector = True
01072             self.layers.append({
01073                     "type"    : 'vector',
01074                     "name"    : self._get_value(line),
01075                     "checked" : None,
01076                     "opacity" : None,
01077                     "cmd"     : ['d.vect'],
01078                     "group"   : self.inGroup,
01079                     "display" : 0})
01080 
01081         elif element == 'vect' and self.inVector:
01082             self.layers[-1]['cmd'].append('map=%s' % self._get_value(line))
01083                 
01084         elif element in ('display_shape',
01085                          'display_cat',
01086                          'display_topo',
01087                          'display_dir',
01088                          'display_attr',
01089                          'type_point',
01090                          'type_line',
01091                          'type_boundary',
01092                          'type_centroid',
01093                          'type_area',
01094                          'type_face') and self.inVector:
01095             
01096             if int(self._get_value(line)) == 1:
01097                 name = element.split('_')[0]
01098                 type = element.split('_')[1]
01099                 paramId = self._get_cmd_param_index(self.layers[-1]['cmd'], name)
01100                 if paramId == -1:
01101                     self.layers[-1]['cmd'].append('%s=%s' % (name, type))
01102                 else:
01103                     self.layers[-1]['cmd'][paramId] += ',%s' % type
01104 
01105         elif element in ('color',
01106                          'fcolor',
01107                          'lcolor') and self.inVector:
01108             value = self._get_value(line)
01109             if value != '':
01110                 self.layers[-1]['cmd'].append('%s=%s' % (element,
01111                                                          self._color_name_to_rgb(value)))
01112 
01113         elif element == 'rdmcolor' and self.inVector:
01114             if int(self._get_value(line)) == 1:
01115                 self.layers[-1]['cmd'].append('-c')
01116 
01117         elif element == 'sqlcolor' and self.inVector:
01118             if int(self._get_value(line)) == 1:
01119                 self.layers[-1]['cmd'].append('-a')
01120 
01121         elif element in ('icon',
01122                          'size',
01123                          'layer',
01124                          'xref',
01125                          'yref',
01126                          'lsize',
01127                          'where',
01128                          'minreg',
01129                          'maxreg') and self.inVector:
01130             value = self._get_value(line)
01131             if value != '':
01132                 self.layers[-1]['cmd'].append('%s=%s' % (element,
01133                                                          value))
01134         
01135         elif element == 'lwidth':
01136             value = self._get_value(line)
01137             if value != '':
01138                 self.layers[-1]['cmd'].append('width=%s' % value)
01139 
01140         elif element == 'lfield':
01141             value = self._get_value(line)
01142             if value != '':
01143                 self.layers[-1]['cmd'].append('llayer=%s' % value)
01144                                         
01145         elif element == 'attribute':
01146             value = self._get_value(line)
01147             if value != '':
01148                 self.layers[-1]['cmd'].append('attrcol=%s' % value)
01149 
01150         elif element == 'cat':
01151             value = self._get_value(line)
01152             if value != '':
01153                 self.layers[-1]['cmd'].append('cats=%s' % value)
01154 
01155         # gridline
01156         elif element == 'gridline':
01157             self.inGridline = True
01158             self.layers.append({
01159                     "type"    : 'grid',
01160                     "name"    : self._get_value(line),
01161                     "checked" : None,
01162                     "opacity" : None,
01163                     "cmd"     : ['d.grid'],
01164                     "group"   : self.inGroup,
01165                     "display" : 0})
01166 
01167         elif element == 'gridcolor':
01168             value = self._get_value(line)
01169             if value != '':
01170                 self.layers[-1]['cmd'].append('color=%s' % self._color_name_to_rgb(value))
01171 
01172         elif element == 'gridborder':
01173             value = self._get_value(line)
01174             if value != '':
01175                 self.layers[-1]['cmd'].append('bordercolor=%s' % self._color_name_to_rgb(value))
01176 
01177         elif element == 'textcolor':
01178             value = self._get_value(line)
01179             if value != '':
01180                 self.layers[-1]['cmd'].append('textcolor=%s' % self._color_name_to_rgb(value))
01181 
01182         elif element in ('gridsize',
01183                          'gridorigin'):
01184             value = self._get_value(line)
01185             if value != '':
01186                 self.layers[-1]['cmd'].append('%s=%s' % (element[4:], value))
01187 
01188         elif element in 'fontsize':
01189             value = self._get_value(line)
01190             if value != '':
01191                 self.layers[-1]['cmd'].append('%s=%s' % (element, value))
01192         
01193         elif element == 'griddraw':
01194             value = self._get_value(line)
01195             if value == '0':
01196                 self.layers[-1]['cmd'].append('-n')
01197                 
01198         elif element == 'gridgeo':
01199             value = self._get_value(line)
01200             if value == '1':
01201                 self.layers[-1]['cmd'].append('-g')
01202         
01203         elif element == 'borderdraw':
01204             value = self._get_value(line)
01205             if value == '0':
01206                 self.layers[-1]['cmd'].append('-b')
01207 
01208         elif element == 'textdraw':
01209             value = self._get_value(line)
01210             if value == '0':
01211                 self.layers[-1]['cmd'].append('-t')
01212         
01213         else:
01214             self.error += _(' row %d:') % line_id + line + os.linesep
01215             self.num_error += 1
01216 
01217     def _get_value(self, line):
01218         """!Get value of element"""
01219         try:
01220             return line.strip(' ').split(' ')[1].strip(' ')
01221         except:
01222             return ''
01223 
01224     def _get_element(self, line):
01225         """!Get element tag"""
01226         return line.strip(' ').split(' ')[0].strip(' ')
01227 
01228     def _get_cmd_param_index(self, cmd, name):
01229         """!Get index of parameter in cmd list
01230 
01231         @param cmd cmd list
01232         @param name parameter name
01233 
01234         @return index
01235         @return -1 if not found
01236         """
01237         i = 0
01238         for param in cmd:
01239             if '=' not in param:
01240                 i += 1
01241                 continue
01242             if param.split('=')[0] == name:
01243                 return i
01244 
01245             i += 1
01246 
01247         return -1
01248 
01249     def _color_name_to_rgb(self, value):
01250         """!Convert color name (#) to rgb values"""
01251         col = wx.NamedColour(value)
01252         return str(col.Red()) + ':' + \
01253             str(col.Green()) + ':' + \
01254             str(col.Blue())
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines