workspace.py 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913
  1. """!
  2. @package workspace.py
  3. @brief Open/save workspace definition file
  4. Classes:
  5. - ProcessWorkspaceFile
  6. - WriteWorkspaceFile
  7. - ProcessGrcFile
  8. (C) 2007-2009 by the GRASS Development Team
  9. This program is free software under the GNU General Public
  10. License (>=v2). Read the file COPYING that comes with GRASS
  11. for details.
  12. @author Martin Landa <landa.martin gmail.com>
  13. """
  14. import os
  15. import wx
  16. ### for gxw (workspace file) parsering
  17. # xmlproc not available on Mac OS
  18. # from xml.parsers.xmlproc import xmlproc
  19. # from xml.parsers.xmlproc import xmlval
  20. # from xml.parsers.xmlproc import xmldtd
  21. try:
  22. import xml.etree.ElementTree as etree
  23. except ImportError:
  24. import elementtree.ElementTree as etree # Python <= 2.4
  25. import utils
  26. from preferences import globalSettings as UserSettings
  27. class ProcessWorkspaceFile():
  28. def __init__(self, tree):
  29. """!A ElementTree handler for the GXW XML file, as defined in
  30. grass-gxw.dtd.
  31. """
  32. self.tree = tree
  33. self.root = self.tree.getroot()
  34. #
  35. # layer manager properties
  36. #
  37. self.layerManager = {}
  38. self.layerManager['pos'] = None # window position
  39. self.layerManager['size'] = None # window size
  40. #
  41. # list of mapdisplays
  42. #
  43. self.displays = []
  44. #
  45. # list of map layers
  46. #
  47. self.layers = []
  48. self.displayIndex = -1 # first display has index '0'
  49. self.__processFile()
  50. def __filterValue(self, value):
  51. """!Filter value
  52. @param value
  53. """
  54. value = value.replace('&lt;', '<')
  55. value = value.replace('&gt;', '>')
  56. return value
  57. def __getNodeText(self, node, tag, default = ''):
  58. """!Get node text"""
  59. p = node.find(tag)
  60. if p is not None:
  61. return utils.normalize_whitespace(p.text)
  62. return default
  63. def __processFile(self):
  64. """!Process workspace file"""
  65. #
  66. # layer manager
  67. #
  68. node_lm = self.root.find('layer_manager')
  69. if node_lm is not None:
  70. posAttr = node_lm.get('dim', '')
  71. if posAttr:
  72. posVal = map(int, posAttr.split(','))
  73. try:
  74. self.layerManager['pos'] = (posVal[0], posVal[1])
  75. self.layerManager['size'] = (posVal[2], posVal[3])
  76. except:
  77. pass
  78. #
  79. # displays
  80. #
  81. for display in self.root.findall('display'):
  82. self.displayIndex += 1
  83. # window position and size
  84. posAttr = display.get('dim', '')
  85. if posAttr:
  86. posVal = map(int, posAttr.split(','))
  87. try:
  88. pos = (posVal[0], posVal[1])
  89. size = (posVal[2], posVal[3])
  90. except:
  91. pos = None
  92. size = None
  93. else:
  94. pos = None
  95. size = None
  96. extentAttr = display.get('extent', '')
  97. if extentAttr:
  98. # w, s, e, n
  99. extent = map(float, extentAttr.split(','))
  100. else:
  101. extent = None
  102. self.displays.append( {
  103. "render" : bool(int(display.get('render', "0"))),
  104. "mode" : int(display.get('mode', 0)),
  105. "showCompExtent" : bool(int(display.get('showCompExtent', "0"))),
  106. "pos" : pos,
  107. "size" : size,
  108. "extent" : extent,
  109. "constrainRes" : bool(int(display.get('constrainRes', "0"))) } )
  110. self.__processLayers(display)
  111. def __processLayers(self, node):
  112. """!Process layers/groups of selected display
  113. @param node display tree node
  114. """
  115. for item in node.getchildren():
  116. if item.tag == 'group':
  117. # -> group
  118. self.layers.append( {
  119. "type" : 'group',
  120. "name" : item.get('name', ''),
  121. "checked" : bool(int(item.get('checked', "0"))),
  122. "opacity" : None,
  123. "cmd" : None,
  124. "group" : False, #### self.inTag['group'], # ???
  125. "display" : self.displayIndex,
  126. "nviz" : None})
  127. elif item.tag == 'layer':
  128. cmd, selected, nviz = self.__processLayer(item)
  129. self.layers.append( {
  130. "type" : item.get('type', None),
  131. "name" : item.get('name', None),
  132. "checked" : bool(int(item.get('checked', "0"))),
  133. "opacity" : float(item.get('opacity', '1.0')),
  134. "cmd" : cmd,
  135. "group" : False, #### self.inTag['group'], # ???
  136. "display" : self.displayIndex,
  137. "selected" : selected,
  138. "nviz" : nviz } )
  139. def __processLayer(self, layer):
  140. """!Process layer item
  141. @param layer tree node
  142. """
  143. cmd = list()
  144. #
  145. # layer attributes (task)
  146. #
  147. node_task = layer.find('task')
  148. cmd.append(node_task.get('name', "unknown"))
  149. # flags
  150. flags = ''
  151. for p in node_task.findall('flag'):
  152. flags += p.get('name', '')
  153. cmd.append('-' + flags)
  154. # parameters
  155. for p in node_task.findall('parameter'):
  156. cmd.append('%s=%s' % (p.get('name', ''),
  157. self.__filterValue(self.__getNodeText(p, 'value'))))
  158. if layer.find('selected') is not None:
  159. selected = True
  160. else:
  161. selected = False
  162. #
  163. # Nviz (3D settings)
  164. #
  165. node_nviz = layer.find('nviz')
  166. if node_nviz is not None:
  167. nviz = self.__processLayerNviz(node_nviz)
  168. else:
  169. nviz = None
  170. return (cmd, selected, nviz)
  171. def __processLayerNviz(self, node_nviz):
  172. """!Process 3D layer settings
  173. @param node_nviz nviz node
  174. """
  175. # init nviz layer properties
  176. nviz = {}
  177. node = node_nviz.find('surface')
  178. if node: # -> raster
  179. nviz['surface'] = {}
  180. for sec in ('attribute', 'draw', 'mask', 'position'):
  181. nviz['surface'][sec] = {}
  182. else:
  183. node = node_nviz.find('vector')
  184. if node: # -> vector
  185. nviz['vector'] = {}
  186. for sec in ('lines', 'points'):
  187. nviz['vector'][sec] = {}
  188. if nviz.has_key('surface'):
  189. # attributes
  190. for attrb in node.find_all('attributes'):
  191. tagName = str(attrb.tag)
  192. attrbName = attrb.get('name', '')
  193. self.nviz['surface'][tagName][attrbName] = {}
  194. if attrb.get('map', '0') == '0':
  195. self.nviz['surface'][tagName][attrbName]['map'] = False
  196. else:
  197. self.nviz['surface'][tagName][attrbName]['map'] = True
  198. self.refAttribute = self.nviz['surface'][tagName][attrbName]
  199. # draw
  200. node_draw = node.find('draw')
  201. if node_draw is not None:
  202. tagName = str(node_draw.tag)
  203. nviz['surface'][tagName]['all'] = False
  204. nviz['surface'][tagName]['mode'] = {}
  205. nviz['surface'][tagName]['mode']['value'] = -1 # to be calculated
  206. nviz['surface'][tagName]['mode']['desc'] = {}
  207. nviz['surface'][tagName]['mode']['desc']['shading'] = \
  208. str(attrs.get('shading', ''))
  209. nviz['surface'][tagName]['mode']['desc']['style'] = \
  210. str(attrs.get('style', ''))
  211. nviz['surface'][tagName]['mode']['desc']['mode'] = \
  212. str(attrs.get('mode', ''))
  213. for node_pos in node_draw.findall('resolution'):
  214. self.resolutionType = str(node_pos.get('type', ''))
  215. if not nviz['surface']['draw'].has_key('reaolution'):
  216. nviz['surface']['draw']['resolution'] = {}
  217. # position
  218. node_pos = node.find('position')
  219. if node_pos is not None:
  220. self.nviz['surface']['position'] = {}
  221. elif nviz.has_key('vector'):
  222. # vpoints
  223. node_vpoints = node.find('vpoints')
  224. if node_vpoints is not None:
  225. marker = str(node_vpoints.get('marker', ''))
  226. markerId = list(UserSettings.Get(group='nviz', key='vector',
  227. subkey=['points', 'marker'], internal=True)).index(marker)
  228. nviz['vector']['points']['marker'] = markerId
  229. node_mode = node.find('mode')
  230. if node_mode is not None:
  231. nviz['vector']['points']['mode'] = {}
  232. nviz['vector']['points']['mode']['type'] = str(node_mode.get('type', ''))
  233. nviz['vector']['points']['mode']['surface'] = ''
  234. # vlines
  235. node_vlines = node.find('vlines')
  236. if node_vlines is not None:
  237. node_mode = node.find('mode')
  238. if node_mode is not None:
  239. nviz['vector']['lines']['mode'] = {}
  240. nviz['vector']['lines']['mode']['type'] = str(node_mode.get('type', ''))
  241. nviz['vector']['lines']['mode']['surface'] = ''
  242. # elif name == 'attribute':
  243. # if self.inTag['nviz'] and self.inTag['surface']:
  244. # try:
  245. # self.refAttribute['value'] = int(self.value)
  246. # except ValueError:
  247. # try:
  248. # self.refAttribute['value'] = float(self.value)
  249. # except ValueError:
  250. # self.refAttribute['value'] = str(self.value)
  251. # elif name == 'resolution':
  252. # if self.inTag['nviz'] and self.inTag['surface']:
  253. # self.layerNviz['surface']['draw']['resolution'][self.resolutionType] = int(self.value)
  254. # del self.resolutionType
  255. # elif name == 'wire_color':
  256. # if self.inTag['nviz'] and self.inTag['surface']:
  257. # self.layerNviz['surface']['draw']['wire-color'] = {}
  258. # self.layerNviz['surface']['draw']['wire-color']['value'] = str(self.value)
  259. # elif name == 'x':
  260. # if self.inTag['nviz'] and self.inTag['surface']:
  261. # self.layerNviz['surface']['position']['x'] = int(self.value)
  262. # elif name == 'y':
  263. # if self.inTag['nviz'] and self.inTag['surface']:
  264. # self.layerNviz['surface']['position']['y'] = int(self.value)
  265. # elif name == 'z':
  266. # if self.inTag['nviz'] and self.inTag['surface']:
  267. # self.layerNviz['surface']['position']['z'] = int(self.value)
  268. # elif name == 'color':
  269. # if self.inTag['nviz']:
  270. # if self.inTag['vlines']:
  271. # self.layerNviz['vector']['lines']['color'] = str(self.value)
  272. # elif self.inTag['vpoints']:
  273. # self.layerNviz['vector']['points']['color'] = str(self.value)
  274. # elif name == 'width':
  275. # if self.inTag['nviz']:
  276. # if self.inTag['vlines']:
  277. # self.layerNviz['vector']['lines']['width'] = int(self.value)
  278. # elif self.inTag['vpoints']:
  279. # self.layerNviz['vector']['points']['width'] = int(self.value)
  280. # elif name == 'height':
  281. # if self.inTag['nviz']:
  282. # if self.inTag['vlines']:
  283. # self.layerNviz['vector']['lines']['height'] = int(self.value)
  284. # elif self.inTag['vpoints']:
  285. # self.layerNviz['vector']['points']['height'] = int(self.value)
  286. # elif name == 'size':
  287. # if self.inTag['nviz'] and self.inTag['vpoints']:
  288. # self.layerNviz['vector']['points']['size'] = int(self.value)
  289. # elif name == 'map':
  290. # if self.inTag['nviz']:
  291. # if self.inTag['vlines']:
  292. # self.layerNviz['vector']['lines']['mode']['surface'] = str(self.value)
  293. # elif self.inTag['vpoints']:
  294. # self.layerNviz['vector']['points']['mode']['surface'] = str(self.value)
  295. return nviz
  296. class WriteWorkspaceFile(object):
  297. """!Generic class for writing workspace file"""
  298. def __init__(self, lmgr, file):
  299. self.file = file
  300. self.lmgr = lmgr
  301. self.indent = 0
  302. # write header
  303. self.file.write('<?xml version="1.0" encoding="UTF-8"?>\n')
  304. self.file.write('<!DOCTYPE gxw SYSTEM "grass-gxw.dtd">\n')
  305. self.file.write('%s<gxw>\n' % (' ' * self.indent))
  306. self.indent =+ 4
  307. # layer manager
  308. windowPos = self.lmgr.GetPosition()
  309. windowSize = self.lmgr.GetSize()
  310. file.write('%s<layer_manager dim="%d,%d,%d,%d">\n' % (' ' * self.indent,
  311. windowPos[0],
  312. windowPos[1],
  313. windowSize[0],
  314. windowSize[1]
  315. ))
  316. file.write('%s</layer_manager>\n' % (' ' * self.indent))
  317. # list of displays
  318. for page in range(0, self.lmgr.gm_cb.GetPageCount()):
  319. mapTree = self.lmgr.gm_cb.GetPage(page).maptree
  320. region = mapTree.Map.region
  321. displayPos = mapTree.mapdisplay.GetPosition()
  322. displaySize = mapTree.mapdisplay.GetSize()
  323. file.write('%s<display render="%d" '
  324. 'mode="%d" showCompExtent="%d" '
  325. 'constrainRes="%d" '
  326. 'dim="%d,%d,%d,%d" '
  327. 'extent="%f,%f,%f,%f">\n' % (' ' * self.indent,
  328. int(mapTree.mapdisplay.autoRender.IsChecked()),
  329. mapTree.mapdisplay.toggleStatus.GetSelection(),
  330. int(mapTree.mapdisplay.showRegion.IsChecked()),
  331. int(mapTree.mapdisplay.compResolution.IsChecked()),
  332. displayPos[0],
  333. displayPos[1],
  334. displaySize[0],
  335. displaySize[1],
  336. region['w'],
  337. region['s'],
  338. region['e'],
  339. region['n']
  340. ))
  341. # list of layers
  342. item = mapTree.GetFirstChild(mapTree.root)[0]
  343. self.__writeLayer(mapTree, item)
  344. file.write('%s</display>\n' % (' ' * self.indent))
  345. self.indent =- 4
  346. file.write('%s</gxw>\n' % (' ' * self.indent))
  347. def __filterValue(self, value):
  348. """!Make value XML-valid"""
  349. value = value.replace('<', '&lt;')
  350. value = value.replace('>', '&gt;')
  351. return value
  352. def __writeLayer(self, mapTree, item):
  353. """!Write bunch of layers to GRASS Workspace XML file"""
  354. self.indent += 4
  355. itemSelected = mapTree.GetSelections()
  356. while item and item.IsOk():
  357. type = mapTree.GetPyData(item)[0]['type']
  358. if type != 'group':
  359. maplayer = mapTree.GetPyData(item)[0]['maplayer']
  360. else:
  361. maplayer = None
  362. checked = int(item.IsChecked())
  363. if type == 'command':
  364. cmd = mapTree.GetPyData(item)[0]['maplayer'].GetCmd(string=True)
  365. self.file.write('%s<layer type="%s" name="%s" checked="%d">\n' % \
  366. (' ' * self.indent, type, cmd, checked));
  367. self.file.write('%s</layer>\n' % (' ' * self.indent));
  368. elif type == 'group':
  369. name = mapTree.GetItemText(item)
  370. self.file.write('%s<group name="%s" checked="%d">\n' % \
  371. (' ' * self.indent, name, checked));
  372. self.indent += 4
  373. subItem = mapTree.GetFirstChild(item)[0]
  374. self.__writeLayer(mapTree, subItem)
  375. self.indent -= 4
  376. self.file.write('%s</group>\n' % (' ' * self.indent));
  377. else:
  378. cmd = mapTree.GetPyData(item)[0]['maplayer'].GetCmd(string=False)
  379. name = mapTree.GetItemText(item)
  380. # remove 'opacity' part
  381. if '(opacity' in name:
  382. name = name.split('(', -1)[0].strip()
  383. opacity = maplayer.GetOpacity(float=True)
  384. self.file.write('%s<layer type="%s" name="%s" checked="%d" opacity="%f">\n' % \
  385. (' ' * self.indent, type, name, checked, opacity));
  386. self.indent += 4
  387. # selected ?
  388. if item in itemSelected:
  389. self.file.write('%s<selected />\n' % (' ' * self.indent))
  390. # layer properties
  391. self.file.write('%s<task name="%s">\n' % (' ' * self.indent, cmd[0]))
  392. self.indent += 4
  393. for key, val in cmd[1].iteritems():
  394. if key == 'flags':
  395. for f in val:
  396. self.file.write('%s<flag name="%s" />\n' %
  397. (' ' * self.indent, f))
  398. else: # parameter
  399. self.file.write('%s<parameter name="%s">\n' %
  400. (' ' * self.indent, key))
  401. self.indent += 4
  402. self.file.write('%s<value>%s</value>\n' %
  403. (' ' * self.indent, self.__filterValue(val)))
  404. self.indent -= 4
  405. self.file.write('%s</parameter>\n' % (' ' * self.indent));
  406. self.indent -= 4
  407. self.file.write('%s</task>\n' % (' ' * self.indent));
  408. nviz = mapTree.GetPyData(item)[0]['nviz']
  409. if nviz:
  410. self.file.write('%s<nviz>\n' % (' ' * self.indent));
  411. if maplayer.type == 'raster':
  412. self.__writeNvizSurface(nviz['surface'])
  413. elif maplayer.type == 'vector':
  414. self.__writeNvizVector(nviz['vector'])
  415. self.file.write('%s</nviz>\n' % (' ' * self.indent));
  416. self.indent -= 4
  417. self.file.write('%s</layer>\n' % (' ' * self.indent));
  418. item = mapTree.GetNextSibling(item)
  419. self.indent -= 4
  420. def __writeNvizSurface(self, data):
  421. """!Save Nviz raster layer properties to workspace
  422. @param data Nviz layer properties
  423. """
  424. if not data.has_key('object'): # skip disabled
  425. return
  426. self.indent += 4
  427. self.file.write('%s<surface>\n' % (' ' * self.indent))
  428. self.indent += 4
  429. for attrb in data.iterkeys():
  430. if len(data[attrb]) < 1: # skip empty attributes
  431. continue
  432. if attrb == 'object':
  433. continue
  434. for name in data[attrb].iterkeys():
  435. # surface attribute
  436. if attrb == 'attribute':
  437. self.file.write('%s<%s name="%s" map="%d">\n' % \
  438. (' ' * self.indent, attrb, name, data[attrb][name]['map']))
  439. self.indent += 4
  440. self.file.write('%s<value>%s</value>\n' % (' ' * self.indent, data[attrb][name]['value']))
  441. self.indent -= 4
  442. # end tag
  443. self.file.write('%s</%s>\n' % (' ' * self.indent, attrb))
  444. # draw mode
  445. if attrb == 'draw':
  446. self.file.write('%s<%s' %(' ' * self.indent, attrb))
  447. if data[attrb].has_key('mode'):
  448. for tag, value in data[attrb]['mode']['desc'].iteritems():
  449. self.file.write(' %s="%s"' % (tag, value))
  450. self.file.write('>\n') # <draw ...>
  451. if data[attrb].has_key('resolution'):
  452. self.indent += 4
  453. for type in ('coarse', 'fine'):
  454. self.file.write('%s<resolution type="%s">\n' % (' ' * self.indent, type))
  455. self.indent += 4
  456. self.file.write('%s<value>%d</value>\n' % (' ' * self.indent,
  457. data[attrb]['resolution'][type]))
  458. self.indent -= 4
  459. self.file.write('%s</resolution>\n' % (' ' * self.indent))
  460. if data[attrb].has_key('wire-color'):
  461. self.file.write('%s<wire_color>\n' % (' ' * self.indent))
  462. self.indent += 4
  463. self.file.write('%s<value>%s</value>\n' % (' ' * self.indent,
  464. data[attrb]['wire-color']['value']))
  465. self.indent -= 4
  466. self.file.write('%s</wire_color>\n' % (' ' * self.indent))
  467. self.indent -= 4
  468. # position
  469. elif attrb == 'position':
  470. self.file.write('%s<%s>\n' %(' ' * self.indent, attrb))
  471. i = 0
  472. for tag in ('x', 'y', 'z'):
  473. self.indent += 4
  474. self.file.write('%s<%s>%d</%s>\n' % (' ' * self.indent, tag,
  475. data[attrb][tag], tag))
  476. i += 1
  477. self.indent -= 4
  478. if attrb != 'attribute':
  479. # end tag
  480. self.file.write('%s</%s>\n' % (' ' * self.indent, attrb))
  481. self.indent -= 4
  482. self.file.write('%s</surface>\n' % (' ' * self.indent))
  483. self.indent -= 4
  484. def __writeNvizVector(self, data):
  485. """!Save Nviz vector layer properties (lines/points) to workspace
  486. @param data Nviz layer properties
  487. """
  488. self.indent += 4
  489. for attrb in data.iterkeys():
  490. if len(data[attrb]) < 1: # skip empty attributes
  491. continue
  492. if not data[attrb].has_key('object'): # skip disabled
  493. continue
  494. if attrb == 'lines':
  495. self.file.write('%s<v%s>\n' % (' ' * self.indent, attrb))
  496. elif attrb == 'points':
  497. markerId = data[attrb]['marker']
  498. marker = UserSettings.Get(group='nviz', key='vector',
  499. subkey=['points', 'marker'], internal=True)[markerId]
  500. self.file.write('%s<v%s marker="%s">\n' % (' ' * self.indent,
  501. attrb,
  502. marker))
  503. self.indent += 4
  504. for name in data[attrb].iterkeys():
  505. if name in ('object', 'marker'):
  506. continue
  507. if name == 'mode':
  508. self.file.write('%s<%s type="%s">\n' % (' ' * self.indent, name,
  509. data[attrb][name]['type']))
  510. if data[attrb][name]['type'] == 'surface':
  511. self.indent += 4
  512. self.file.write('%s<map>%s</map>\n' % (' ' * self.indent,
  513. data[attrb][name]['surface']))
  514. self.indent -= 4
  515. self.file.write('%s</%s>\n' % ((' ' * self.indent, name)))
  516. else:
  517. self.file.write('%s<%s>\n' % (' ' * self.indent, name))
  518. self.indent += 4
  519. self.file.write('%s<value>%s</value>\n' % (' ' * self.indent, data[attrb][name]))
  520. self.indent -= 4
  521. self.file.write('%s</%s>\n' % (' ' * self.indent, name))
  522. self.indent -= 4
  523. self.file.write('%s</v%s>\n' % (' ' * self.indent, attrb))
  524. self.indent -= 4
  525. class ProcessGrcFile(object):
  526. def __init__(self, filename):
  527. """!Process GRC file"""
  528. self.filename = filename
  529. # elements
  530. self.inGroup = False
  531. self.inRaster = False
  532. self.inVector = False
  533. # list of layers
  534. self.layers = []
  535. # error message
  536. self.error = ''
  537. self.num_error = 0
  538. def read(self, parent):
  539. """!Read GRC file
  540. @param parent parent window
  541. @return list of map layers
  542. """
  543. try:
  544. file = open(self.filename, "r")
  545. except IOError:
  546. wx.MessageBox(parent=parent,
  547. message=_("Unable to open file <%s> for reading.") % self.filename,
  548. caption=_("Error"), style=wx.OK | wx.ICON_ERROR)
  549. return []
  550. line_id = 1
  551. for line in file.readlines():
  552. self.process_line(line.rstrip('\n'), line_id)
  553. line_id +=1
  554. file.close()
  555. if self.num_error > 0:
  556. wx.MessageBox(parent=parent,
  557. message=_("Some lines were skipped when reading settings "
  558. "from file <%(file)s>.\nSee 'Command output' window for details.\n\n"
  559. "Number of skipped lines: %(line)d") % \
  560. { 'file' : self.filename, 'line' : self.num_error },
  561. caption=_("Warning"), style=wx.OK | wx.ICON_EXCLAMATION)
  562. parent.goutput.WriteLog('Map layers loaded from GRC file <%s>' % self.filename)
  563. parent.goutput.WriteLog('Skipped lines:\n%s' % self.error)
  564. return self.layers
  565. def process_line(self, line, line_id):
  566. """!Process line definition"""
  567. element = self._get_element(line)
  568. if element == 'Group':
  569. self.groupName = self._get_value(line)
  570. self.layers.append({
  571. "type" : 'group',
  572. "name" : self.groupName,
  573. "checked" : None,
  574. "opacity" : None,
  575. "cmd" : None,
  576. "group" : self.inGroup,
  577. "display" : 0 })
  578. self.inGroup = True
  579. elif element == '_check':
  580. if int(self._get_value(line)) == 1:
  581. self.layers[-1]['checked'] = True
  582. else:
  583. self.layers[-1]['checked'] = False
  584. elif element == 'End':
  585. if self.inRaster:
  586. self.inRaster = False
  587. elif self.inVector:
  588. self.inVector = False
  589. elif self.inGroup:
  590. self.inGroup = False
  591. elif self.inGridline:
  592. self.inGridline = False
  593. elif element == 'opacity':
  594. self.layers[-1]['opacity'] = float(self._get_value(line))
  595. # raster
  596. elif element == 'Raster':
  597. self.inRaster = True
  598. self.layers.append({
  599. "type" : 'raster',
  600. "name" : self._get_value(line),
  601. "checked" : None,
  602. "opacity" : None,
  603. "cmd" : ['d.rast'],
  604. "group" : self.inGroup,
  605. "display" : 0})
  606. elif element == 'map' and self.inRaster:
  607. self.layers[-1]['cmd'].append('map=%s' % self._get_value(line))
  608. elif element == 'overlay' and self.inRaster:
  609. if int(self._get_value(line)) == 1:
  610. self.layers[-1]['cmd'].append('-o')
  611. elif element == 'rastquery' and self.inRaster:
  612. value = self._get_value(line)
  613. if value != '':
  614. self.layers[-1]['cmd'].append('catlist=%s' % value)
  615. elif element == 'bkcolor' and self.inRaster:
  616. value = self._get_value(line)
  617. if value != '':
  618. self.layers[-1]['cmd'].append('bg=%s' % value)
  619. # vector
  620. elif element == 'Vector':
  621. self.inVector = True
  622. self.layers.append({
  623. "type" : 'vector',
  624. "name" : self._get_value(line),
  625. "checked" : None,
  626. "opacity" : None,
  627. "cmd" : ['d.vect'],
  628. "group" : self.inGroup,
  629. "display" : 0})
  630. elif element == 'vect' and self.inVector:
  631. self.layers[-1]['cmd'].append('map=%s' % self._get_value(line))
  632. elif element in ('display_shape',
  633. 'display_cat',
  634. 'display_topo',
  635. 'display_dir',
  636. 'display_attr',
  637. 'type_point',
  638. 'type_line',
  639. 'type_boundary',
  640. 'type_centroid',
  641. 'type_area',
  642. 'type_face') and self.inVector:
  643. if int(self._get_value(line)) == 1:
  644. name = element.split('_')[0]
  645. type = element.split('_')[1]
  646. paramId = self._get_cmd_param_index(self.layers[-1]['cmd'], name)
  647. if paramId == -1:
  648. self.layers[-1]['cmd'].append('%s=%s' % (name, type))
  649. else:
  650. self.layers[-1]['cmd'][paramId] += ',%s' % type
  651. elif element in ('color',
  652. 'fcolor',
  653. 'lcolor') and self.inVector:
  654. value = self._get_value(line)
  655. if value != '':
  656. self.layers[-1]['cmd'].append('%s=%s' % (element,
  657. self._color_name_to_rgb(value)))
  658. elif element == 'rdmcolor' and self.inVector:
  659. if int(self._get_value(line)) == 1:
  660. self.layers[-1]['cmd'].append('-c')
  661. elif element == 'sqlcolor' and self.inVector:
  662. if int(self._get_value(line)) == 1:
  663. self.layers[-1]['cmd'].append('-a')
  664. elif element in ('icon',
  665. 'size',
  666. 'layer',
  667. 'xref',
  668. 'yref',
  669. 'lsize',
  670. 'where',
  671. 'minreg',
  672. 'maxreg') and self.inVector:
  673. value = self._get_value(line)
  674. if value != '':
  675. self.layers[-1]['cmd'].append('%s=%s' % (element,
  676. value))
  677. elif element == 'lwidth':
  678. value = self._get_value(line)
  679. if value != '':
  680. self.layers[-1]['cmd'].append('width=%s' % value)
  681. elif element == 'lfield':
  682. value = self._get_value(line)
  683. if value != '':
  684. self.layers[-1]['cmd'].append('llayer=%s' % value)
  685. elif element == 'attribute':
  686. value = self._get_value(line)
  687. if value != '':
  688. self.layers[-1]['cmd'].append('attrcol=%s' % value)
  689. elif element == 'cat':
  690. value = self._get_value(line)
  691. if value != '':
  692. self.layers[-1]['cmd'].append('cats=%s' % value)
  693. # gridline
  694. elif element == 'gridline':
  695. self.inGridline = True
  696. self.layers.append({
  697. "type" : 'grid',
  698. "name" : self._get_value(line),
  699. "checked" : None,
  700. "opacity" : None,
  701. "cmd" : ['d.grid'],
  702. "group" : self.inGroup,
  703. "display" : 0})
  704. elif element == 'gridcolor':
  705. value = self._get_value(line)
  706. if value != '':
  707. self.layers[-1]['cmd'].append('color=%s' % self._color_name_to_rgb(value))
  708. elif element == 'gridborder':
  709. value = self._get_value(line)
  710. if value != '':
  711. self.layers[-1]['cmd'].append('bordercolor=%s' % self._color_name_to_rgb(value))
  712. elif element == 'textcolor':
  713. value = self._get_value(line)
  714. if value != '':
  715. self.layers[-1]['cmd'].append('textcolor=%s' % self._color_name_to_rgb(value))
  716. elif element in ('gridsize',
  717. 'gridorigin'):
  718. value = self._get_value(line)
  719. if value != '':
  720. self.layers[-1]['cmd'].append('%s=%s' % (element[4:], value))
  721. elif element in 'fontsize':
  722. value = self._get_value(line)
  723. if value != '':
  724. self.layers[-1]['cmd'].append('%s=%s' % (element, value))
  725. elif element == 'griddraw':
  726. value = self._get_value(line)
  727. if value == '0':
  728. self.layers[-1]['cmd'].append('-n')
  729. elif element == 'gridgeo':
  730. value = self._get_value(line)
  731. if value == '1':
  732. self.layers[-1]['cmd'].append('-g')
  733. elif element == 'borderdraw':
  734. value = self._get_value(line)
  735. if value == '0':
  736. self.layers[-1]['cmd'].append('-b')
  737. elif element == 'textdraw':
  738. value = self._get_value(line)
  739. if value == '0':
  740. self.layers[-1]['cmd'].append('-t')
  741. else:
  742. self.error += _(' row %d:') % line_id + line + os.linesep
  743. self.num_error += 1
  744. def _get_value(self, line):
  745. """!Get value of element"""
  746. try:
  747. return line.strip(' ').split(' ')[1].strip(' ')
  748. except:
  749. return ''
  750. def _get_element(self, line):
  751. """!Get element tag"""
  752. return line.strip(' ').split(' ')[0].strip(' ')
  753. def _get_cmd_param_index(self, cmd, name):
  754. """!Get index of parameter in cmd list
  755. @param cmd cmd list
  756. @param name parameter name
  757. @return index
  758. @return -1 if not found
  759. """
  760. i = 0
  761. for param in cmd:
  762. if '=' not in param:
  763. i += 1
  764. continue
  765. if param.split('=')[0] == name:
  766. return i
  767. i += 1
  768. return -1
  769. def _color_name_to_rgb(self, value):
  770. """!Convert color name (#) to rgb values"""
  771. col = wx.NamedColour(value)
  772. return str(col.Red()) + ':' + \
  773. str(col.Green()) + ':' + \
  774. str(col.Blue())