workspace.py 67 KB

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