GRASS Programmer's Manual
6.4.2(2012)
|
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('<', '<') 00080 value = value.replace('>', '>') 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('<', '<') 00743 value = value.replace('>', '>') 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())