workspace.py 75 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015
  1. """
  2. @package core.workspace
  3. @brief Open/save workspace definition file
  4. Classes:
  5. - workspace::ProcessWorkspaceFile
  6. - workspace::WriteWorkspaceFile
  7. - workspace::ProcessGrcFile
  8. (C) 2007-2016 by the GRASS Development Team
  9. This program is free software under the GNU General Public License
  10. (>=v2). Read the file COPYING that comes with GRASS for details.
  11. @author Martin Landa <landa.martin gmail.com>
  12. """
  13. import os
  14. import wx
  15. import six
  16. try:
  17. from StringIO import StringIO
  18. except ImportError:
  19. from io import StringIO
  20. from core.utils import normalize_whitespace
  21. from core.settings import UserSettings
  22. from core.gcmd import EncodeString, GetDefaultEncoding
  23. from nviz.main import NvizSettings
  24. from grass.script import core as gcore
  25. def get_database_location_mapset():
  26. """Returns GRASS database, location, and mapset as a tuple"""
  27. gisenv = gcore.gisenv()
  28. return (gisenv["GISDBASE"], gisenv["LOCATION_NAME"], gisenv["MAPSET"])
  29. class ProcessWorkspaceFile:
  30. def __init__(self, tree):
  31. """A ElementTree handler for the GXW XML file, as defined in
  32. grass-gxw.dtd.
  33. """
  34. self.tree = tree
  35. self.root = self.tree.getroot()
  36. #
  37. # layer manager properties
  38. #
  39. self.layerManager = {
  40. "pos": None, # window position
  41. "size": None, # window size
  42. "cwd": None,
  43. } # current working directory
  44. #
  45. # list of mapdisplays
  46. #
  47. self.displays = []
  48. #
  49. # list of map layers
  50. #
  51. self.layers = []
  52. #
  53. # list of overlays
  54. self.overlays = []
  55. #
  56. # nviz state
  57. #
  58. self.nviz_state = {}
  59. self.displayIndex = -1 # first display has index '0'
  60. self.__processFile()
  61. if NvizSettings:
  62. self.nvizDefault = NvizSettings()
  63. else:
  64. self.nvizDefault = None
  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. # if empty text is inside tag,
  77. # etree returns None
  78. if p.text is None:
  79. return ""
  80. return normalize_whitespace(p.text)
  81. return default
  82. def __processFile(self):
  83. """Process workspace file"""
  84. self.__processSession()
  85. #
  86. # layer manager
  87. #
  88. node_lm = self.root.find("layer_manager")
  89. if node_lm is not None:
  90. posAttr = node_lm.get("dim", "")
  91. if posAttr:
  92. posVal = list(map(int, posAttr.split(",")))
  93. try:
  94. self.layerManager["pos"] = (posVal[0], posVal[1])
  95. self.layerManager["size"] = (posVal[2], posVal[3])
  96. except:
  97. pass
  98. # current working directory
  99. cwdPath = self.__getNodeText(node_lm, "cwd")
  100. if cwdPath:
  101. self.layerManager["cwd"] = cwdPath
  102. #
  103. # displays
  104. #
  105. for display in self.root.findall("display"):
  106. self.displayIndex += 1
  107. # window position and size
  108. posAttr = display.get("dim", "")
  109. if posAttr:
  110. posVal = list(map(int, posAttr.split(",")))
  111. try:
  112. pos = (posVal[0], posVal[1])
  113. size = (posVal[2], posVal[3])
  114. except:
  115. pos = None
  116. size = None
  117. # this happens on Windows when mapwindow is minimized when
  118. # saving workspace
  119. else:
  120. if posVal[0] == -32000:
  121. pos = None
  122. size = None
  123. else:
  124. pos = None
  125. size = None
  126. extentAttr = display.get("extent", "")
  127. if extentAttr:
  128. # w, s, e, n
  129. extent = map(float, extentAttr.split(","))
  130. else:
  131. extent = None
  132. # projection
  133. node_projection = display.find("projection")
  134. if node_projection is not None:
  135. projection = {
  136. "enabled": True,
  137. "epsg": node_projection.get("epsg", ""),
  138. "proj": self.__getNodeText(node_projection, "value"),
  139. }
  140. else:
  141. projection = {"enabled": False}
  142. self.displays.append(
  143. {
  144. "name": display.get("name"),
  145. "render": bool(int(display.get("render", "0"))),
  146. "mode": int(display.get("mode", 0)),
  147. "showCompExtent": bool(int(display.get("showCompExtent", "0"))),
  148. "showStatusbar": bool(int(display.get("showStatusbar", "0"))),
  149. "showToolbars": bool(int(display.get("showToolbars", "0"))),
  150. "pos": pos,
  151. "size": size,
  152. "extent": extent,
  153. "tbres": display.get("tbres", "0"),
  154. "alignExtent": bool(int(display.get("alignExtent", "0"))),
  155. "constrainRes": bool(int(display.get("constrainRes", "0"))),
  156. "projection": projection,
  157. "viewMode": display.get("viewMode", "2d"),
  158. }
  159. )
  160. # process all layers/groups in the display
  161. self.__processLayers(display)
  162. # process nviz_state
  163. self.__processNvizState(display)
  164. def __processSession(self):
  165. session = self.root.find("session")
  166. if session is None:
  167. self.database = None
  168. self.location = None
  169. self.mapset = None
  170. return
  171. self.database = self.__filterValue(self.__getNodeText(session, "database"))
  172. self.location = self.__filterValue(self.__getNodeText(session, "location"))
  173. self.mapset = self.__filterValue(self.__getNodeText(session, "mapset"))
  174. def __processLayers(self, node, inGroup=-1):
  175. """Process layers/groups of selected display
  176. :param node: display tree node
  177. :param inGroup: in group -> index of group item otherwise -1
  178. """
  179. for item in node:
  180. if item.tag == "group":
  181. # -> group
  182. self.layers.append(
  183. {
  184. "type": "group",
  185. "name": item.get("name", ""),
  186. "checked": bool(int(item.get("checked", "0"))),
  187. "opacity": None,
  188. "cmd": None,
  189. "group": inGroup,
  190. "display": self.displayIndex,
  191. "vdigit": None,
  192. "nviz": None,
  193. }
  194. )
  195. self.__processLayers(
  196. item, inGroup=len(self.layers) - 1
  197. ) # process items in group
  198. elif item.tag == "layer":
  199. cmd, selected, vdigit, nviz = self.__processLayer(item)
  200. lname = item.get("name", None)
  201. if lname and "\\n" in lname:
  202. lname = lname.replace("\\n", os.linesep)
  203. self.layers.append(
  204. {
  205. "type": item.get("type", None),
  206. "name": lname,
  207. "checked": bool(int(item.get("checked", "0"))),
  208. "opacity": float(item.get("opacity", "1.0")),
  209. "cmd": cmd,
  210. "group": inGroup,
  211. "display": self.displayIndex,
  212. "selected": selected,
  213. "vdigit": vdigit,
  214. "nviz": nviz,
  215. }
  216. )
  217. elif item.tag == "overlay":
  218. cmd = self.__processOverlay(item)
  219. self.overlays.append({"display": self.displayIndex, "cmd": cmd})
  220. def __processLayer(self, layer):
  221. """Process layer item
  222. :param layer: tree node
  223. """
  224. cmd = list()
  225. #
  226. # layer attributes (task) - 2D settings
  227. #
  228. node_task = layer.find("task")
  229. if node_task is None and layer.get("type") == "command":
  230. # TODO: perhaps the XML format should be changed and command
  231. # should be changed to contain task
  232. # TODO: where the command layer gets actually processed?
  233. pass
  234. else:
  235. cmd.append(node_task.get("name", "unknown"))
  236. # flags
  237. for p in node_task.findall("flag"):
  238. flag = p.get("name", "")
  239. if len(flag) > 1:
  240. cmd.append("--" + flag)
  241. else:
  242. cmd.append("-" + flag)
  243. # parameters
  244. for p in node_task.findall("parameter"):
  245. cmd.append(
  246. "%s=%s"
  247. % (
  248. p.get("name", ""),
  249. self.__filterValue(self.__getNodeText(p, "value")),
  250. )
  251. )
  252. if layer.find("selected") is not None:
  253. selected = True
  254. else:
  255. selected = False
  256. #
  257. # Vector digitizer settings
  258. #
  259. node_vdigit = layer.find("vdigit")
  260. if node_vdigit is not None:
  261. vdigit = self.__processLayerVdigit(node_vdigit)
  262. else:
  263. vdigit = None
  264. #
  265. # Nviz (3D settings)
  266. #
  267. node_nviz = layer.find("nviz")
  268. if node_nviz is not None:
  269. nviz = self.__processLayerNviz(node_nviz)
  270. else:
  271. nviz = None
  272. return (cmd, selected, vdigit, nviz)
  273. def __processOverlay(self, node_overlay):
  274. """
  275. Process overlay item
  276. :param overlay: tree node
  277. """
  278. cmd = list()
  279. cmd.append(node_overlay.get("name", "unknown"))
  280. # flags
  281. for f in node_overlay.findall("flag"):
  282. flag = f.get("name", "")
  283. if len(flag) > 1:
  284. cmd.append("--" + flag)
  285. else:
  286. cmd.append("-" + flag)
  287. # parameters
  288. for p in node_overlay.findall("parameter"):
  289. cmd.append(
  290. "%s=%s"
  291. % (
  292. p.get("name", ""),
  293. self.__filterValue(self.__getNodeText(p, "value")),
  294. )
  295. )
  296. return cmd
  297. def __processLayerVdigit(self, node_vdigit):
  298. """Process vector digitizer layer settings
  299. :param node_vdigit: vdigit node
  300. """
  301. # init nviz layer properties
  302. vdigit = dict()
  303. for node in node_vdigit.findall("geometryAttribute"):
  304. if "geomAttr" not in vdigit:
  305. vdigit["geomAttr"] = dict()
  306. type = node.get("type")
  307. vdigit["geomAttr"][type] = dict()
  308. vdigit["geomAttr"][type]["column"] = node.get("column") # required
  309. # default map units
  310. vdigit["geomAttr"][type]["units"] = node.get("units", "mu")
  311. return vdigit
  312. def __processLayerNviz(self, node_nviz):
  313. """Process 3D layer settings
  314. :param node_nviz: nviz node
  315. """
  316. # init nviz layer properties
  317. nviz = {}
  318. if node_nviz.find("surface") is not None: # -> raster
  319. nviz["surface"] = {}
  320. for sec in ("attribute", "draw", "position"):
  321. nviz["surface"][sec] = {}
  322. self.__processLayerNvizSurface(nviz, node_nviz.find("surface"))
  323. elif node_nviz.find("volume") is not None: # -> raster
  324. nviz["volume"] = {}
  325. for sec in ("attribute", "draw", "position"):
  326. nviz["volume"][sec] = {}
  327. self.__processLayerNvizVolume(nviz, node_nviz.find("volume"))
  328. elif (
  329. node_nviz.find("vlines") is not None
  330. or node_nviz.find("vpoints") is not None
  331. ): # -> vector
  332. nviz["vector"] = {}
  333. for sec in ("lines", "points"):
  334. nviz["vector"][sec] = {}
  335. if node_nviz.find("vlines"):
  336. self.__processLayerNvizVectorLines(nviz, node_nviz.find("vlines"))
  337. if node_nviz.find("vpoints"):
  338. self.__processLayerNvizVectorPoints(nviz, node_nviz.find("vpoints"))
  339. return nviz
  340. def __processLayerNvizSurface(self, nvizData, nodeSurface):
  341. """Process 3D layer settings - surface
  342. :param nodeData: nviz data dict
  343. :param nodeSurface: nviz surface node
  344. """
  345. # attributes
  346. for attrb in nodeSurface.findall("attribute"):
  347. tagName = str(attrb.tag)
  348. attrbName = attrb.get("name", "")
  349. dc = nvizData["surface"][tagName][attrbName] = {}
  350. if attrb.get("map", "0") == "0":
  351. dc["map"] = False
  352. else:
  353. dc["map"] = True
  354. value = self.__getNodeText(attrb, "value")
  355. try:
  356. dc["value"] = int(value)
  357. except ValueError:
  358. try:
  359. dc["value"] = float(value)
  360. except ValueError:
  361. dc["value"] = str(value)
  362. # draw
  363. node_draw = nodeSurface.find("draw")
  364. if node_draw is not None:
  365. tagName = str(node_draw.tag)
  366. nvizData["surface"][tagName]["all"] = False
  367. nvizData["surface"][tagName]["mode"] = {}
  368. nvizData["surface"][tagName]["mode"]["value"] = -1 # to be calculated
  369. nvizData["surface"][tagName]["mode"]["desc"] = {}
  370. nvizData["surface"][tagName]["mode"]["desc"]["shading"] = str(
  371. node_draw.get("shading", "")
  372. )
  373. nvizData["surface"][tagName]["mode"]["desc"]["style"] = str(
  374. node_draw.get("style", "")
  375. )
  376. nvizData["surface"][tagName]["mode"]["desc"]["mode"] = str(
  377. node_draw.get("mode", "")
  378. )
  379. # resolution
  380. for node_res in node_draw.findall("resolution"):
  381. resType = str(node_res.get("type", ""))
  382. if "resolution" not in nvizData["surface"]["draw"]:
  383. nvizData["surface"]["draw"]["resolution"] = {}
  384. value = int(self.__getNodeText(node_res, "value"))
  385. nvizData["surface"]["draw"]["resolution"][resType] = value
  386. # wire-color
  387. node_wire_color = node_draw.find("wire_color")
  388. if node_wire_color is not None:
  389. nvizData["surface"]["draw"]["wire-color"] = {}
  390. value = str(self.__getNodeText(node_wire_color, "value"))
  391. nvizData["surface"]["draw"]["wire-color"]["value"] = value
  392. # position
  393. node_pos = nodeSurface.find("position")
  394. if node_pos is not None:
  395. dc = nvizData["surface"]["position"]
  396. for coor in ["x", "y", "z"]:
  397. node = node_pos.find(coor)
  398. if node is None:
  399. continue
  400. value = int(self.__getNodeText(node_pos, coor))
  401. dc[coor] = value
  402. def __processLayerNvizVolume(self, nvizData, nodeVolume):
  403. """Process 3D layer settings - volume
  404. :param nodeData: nviz data dict
  405. :param nodeVolume: nviz volume node
  406. """
  407. # attributes
  408. for attrb in nodeVolume.findall("attribute"):
  409. tagName = str(attrb.tag)
  410. attrbName = attrb.get("name", "")
  411. dc = nvizData["volume"][tagName][attrbName] = {}
  412. if attrb.get("map") == "0":
  413. dc["map"] = False
  414. elif attrb.get("map") == "1":
  415. dc["map"] = True
  416. else:
  417. dc["map"] = None
  418. value = self.__getNodeText(attrb, "value")
  419. try:
  420. dc["value"] = int(value)
  421. except ValueError:
  422. try:
  423. dc["value"] = float(value)
  424. except ValueError:
  425. dc["value"] = str(value)
  426. # draw
  427. node_draw = nodeVolume.find("draw")
  428. if node_draw is not None:
  429. node_box = node_draw.find("box")
  430. if node_box is not None:
  431. nvizData["volume"]["draw"]["box"] = {}
  432. enabled = bool(int(self.__getNodeText(node_box, "enabled")))
  433. nvizData["volume"]["draw"]["box"]["enabled"] = enabled
  434. node_mode = node_draw.find("mode")
  435. if node_mode is not None:
  436. nvizData["volume"]["draw"]["mode"] = {}
  437. desc = self.__getNodeText(node_mode, "desc")
  438. value = int(self.__getNodeText(node_mode, "value"))
  439. nvizData["volume"]["draw"]["mode"]["desc"] = desc
  440. nvizData["volume"]["draw"]["mode"]["value"] = value
  441. node_res = node_draw.find("resolution")
  442. if node_res is not None:
  443. nvizData["volume"]["draw"]["resolution"] = {}
  444. for vol_type in ("isosurface", "slice"):
  445. nd = node_res.find(vol_type)
  446. value = int(self.__getNodeText(nd, "value"))
  447. nvizData["volume"]["draw"]["resolution"][vol_type] = {
  448. "value": value
  449. }
  450. node_shading = node_draw.find("shading")
  451. if node_shading is not None:
  452. nvizData["volume"]["draw"]["shading"] = {}
  453. for vol_type in ("isosurface", "slice"):
  454. nd = node_shading.find(vol_type)
  455. value = int(self.__getNodeText(nd, "value"))
  456. desc = self.__getNodeText(nd, "desc")
  457. nvizData["volume"]["draw"]["shading"][vol_type] = {
  458. "value": value,
  459. "desc": desc,
  460. }
  461. nvizData["volume"]["isosurface"] = []
  462. for isosurfaceNode in nodeVolume.findall("isosurface"):
  463. isoDict = {}
  464. for att in ("topo", "transp", "shine", "color"):
  465. attNode = isosurfaceNode.find(att)
  466. if attNode is not None:
  467. isMap = attNode.find("map").text
  468. value = attNode.find("value").text
  469. if not isMap:
  470. isoDict[att] = {"map": None}
  471. isoDict[att]["value"] = float(value)
  472. elif isMap == "1":
  473. isoDict[att] = {"map": True}
  474. isoDict[att]["value"] = value
  475. else:
  476. isoDict[att] = {"map": False}
  477. isoDict[att]["value"] = float(value)
  478. inout = isosurfaceNode.find("inout")
  479. if inout is not None:
  480. isoDict["inout"] = {"value": int(float(inout.find("value").text))}
  481. nvizData["volume"]["isosurface"].append(isoDict)
  482. nvizData["volume"]["slice"] = []
  483. for sliceNode in nodeVolume.findall("slice"):
  484. sliceDict = {}
  485. sliceDict["transp"] = {
  486. "value": int(sliceNode.find("transp").find("value").text)
  487. }
  488. sliceDict["position"] = {}
  489. for child in sliceNode.find("position"):
  490. if child.tag == "axis":
  491. sliceDict["position"][child.tag] = int(child.text)
  492. else:
  493. sliceDict["position"][child.tag] = float(child.text)
  494. nvizData["volume"]["slice"].append(sliceDict)
  495. # position
  496. node_pos = nodeVolume.find("position")
  497. if node_pos is not None:
  498. dc = nvizData["volume"]["position"]
  499. for coor in ["x", "y", "z"]:
  500. node = node_pos.find(coor)
  501. if node is None:
  502. continue
  503. value = int(self.__getNodeText(node_pos, coor))
  504. dc[coor] = value
  505. def __processLayerNvizVectorPoints(self, nvizData, nodePoints):
  506. """Process 3D layer settings - vector points
  507. :param nodeData: nviz data dict
  508. :param nodeVector: nviz vector points node
  509. """
  510. marker = str(nodePoints.get("marker", ""))
  511. markerId = list(
  512. UserSettings.Get(
  513. group="nviz",
  514. key="vector",
  515. subkey=["points", "marker"],
  516. settings_type="internal",
  517. )
  518. ).index(marker)
  519. nvizData["vector"]["points"]["marker"] = {"value": markerId}
  520. node_mode = nodePoints.find("mode")
  521. if node_mode is not None:
  522. nvizData["vector"]["points"]["mode"] = {}
  523. nvizData["vector"]["points"]["mode"]["type"] = str(
  524. node_mode.get("type", "surface")
  525. )
  526. nvizData["vector"]["points"]["mode"]["surface"] = {}
  527. nvizData["vector"]["points"]["mode"]["surface"]["value"] = []
  528. nvizData["vector"]["points"]["mode"]["surface"]["show"] = []
  529. # map
  530. for node_map in node_mode.findall("map"):
  531. nvizData["vector"]["points"]["mode"]["surface"]["value"].append(
  532. self.__processLayerNvizNode(node_map, "name", str)
  533. )
  534. nvizData["vector"]["points"]["mode"]["surface"]["show"].append(
  535. bool(self.__processLayerNvizNode(node_map, "checked", int))
  536. )
  537. # color
  538. self.__processLayerNvizNode(
  539. nodePoints, "color", str, nvizData["vector"]["points"]
  540. )
  541. # width
  542. self.__processLayerNvizNode(
  543. nodePoints, "width", int, nvizData["vector"]["points"]
  544. )
  545. # height
  546. self.__processLayerNvizNode(
  547. nodePoints, "height", float, nvizData["vector"]["points"]
  548. )
  549. # height
  550. self.__processLayerNvizNode(
  551. nodePoints, "size", float, nvizData["vector"]["points"]
  552. )
  553. # thematic
  554. node_thematic = nodePoints.find("thematic")
  555. thematic = nvizData["vector"]["points"]["thematic"] = {}
  556. thematic["rgbcolumn"] = self.__processLayerNvizNode(
  557. node_thematic, "rgbcolumn", str
  558. )
  559. thematic["sizecolumn"] = self.__processLayerNvizNode(
  560. node_thematic, "sizecolumn", str
  561. )
  562. for col in ("rgbcolumn", "sizecolumn"):
  563. if thematic[col] == "None":
  564. thematic[col] = None
  565. thematic["layer"] = self.__processLayerNvizNode(node_thematic, "layer", int)
  566. for use in ("usecolor", "usesize", "usewidth"):
  567. if node_thematic.get(use, ""):
  568. thematic[use] = int(node_thematic.get(use, "0"))
  569. def __processLayerNvizVectorLines(self, nvizData, nodeLines):
  570. """Process 3D layer settings - vector lines
  571. :param nodeData: nviz data dict
  572. :param nodeVector: nviz vector lines node
  573. """
  574. node_mode = nodeLines.find("mode")
  575. if node_mode is not None:
  576. nvizData["vector"]["lines"]["mode"] = {}
  577. nvizData["vector"]["lines"]["mode"]["type"] = str(node_mode.get("type", ""))
  578. nvizData["vector"]["lines"]["mode"]["surface"] = {}
  579. nvizData["vector"]["lines"]["mode"]["surface"]["value"] = []
  580. nvizData["vector"]["lines"]["mode"]["surface"]["show"] = []
  581. # map
  582. for node_map in node_mode.findall("map"):
  583. nvizData["vector"]["lines"]["mode"]["surface"]["value"].append(
  584. self.__processLayerNvizNode(node_map, "name", str)
  585. )
  586. nvizData["vector"]["lines"]["mode"]["surface"]["show"].append(
  587. bool(self.__processLayerNvizNode(node_map, "checked", int))
  588. )
  589. # color
  590. self.__processLayerNvizNode(
  591. nodeLines, "color", str, nvizData["vector"]["lines"]
  592. )
  593. # width
  594. self.__processLayerNvizNode(
  595. nodeLines, "width", int, nvizData["vector"]["lines"]
  596. )
  597. # height
  598. self.__processLayerNvizNode(
  599. nodeLines, "height", int, nvizData["vector"]["lines"]
  600. )
  601. # thematic
  602. node_thematic = nodeLines.find("thematic")
  603. thematic = nvizData["vector"]["lines"]["thematic"] = {}
  604. thematic["rgbcolumn"] = self.__processLayerNvizNode(
  605. node_thematic, "rgbcolumn", str
  606. )
  607. thematic["sizecolumn"] = self.__processLayerNvizNode(
  608. node_thematic, "sizecolumn", str
  609. )
  610. for col in ("rgbcolumn", "sizecolumn"):
  611. if thematic[col] == "None":
  612. thematic[col] = None
  613. thematic["layer"] = self.__processLayerNvizNode(node_thematic, "layer", int)
  614. for use in ("usecolor", "usesize", "usewidth"):
  615. if node_thematic.get(use, ""):
  616. thematic[use] = int(node_thematic.get(use, "0"))
  617. def __processLayerNvizNode(self, node, tag, cast, dc=None):
  618. """Process given tag nviz/vector"""
  619. node_tag = node.find(tag)
  620. if node_tag is not None:
  621. if node_tag.find("value") is not None:
  622. value = cast(self.__getNodeText(node_tag, "value"))
  623. else:
  624. try:
  625. value = cast(node_tag.text)
  626. except ValueError:
  627. if cast == str:
  628. value = ""
  629. else:
  630. value = None
  631. if dc:
  632. dc[tag] = dict()
  633. dc[tag]["value"] = value
  634. else:
  635. return value
  636. def __processNvizState(self, node):
  637. """Process tag nviz_state"""
  638. node_state = node.find("nviz_state")
  639. if node_state is None:
  640. return
  641. self.nviz_state["display"] = self.displayIndex
  642. #
  643. # view
  644. #
  645. node_view = node_state.find("view")
  646. view = {}
  647. iview = {}
  648. node_position = node_view.find("v_position")
  649. view["position"] = {}
  650. view["position"]["x"] = self.__processLayerNvizNode(node_position, "x", float)
  651. view["position"]["y"] = self.__processLayerNvizNode(node_position, "y", float)
  652. node_persp = node_view.find("persp")
  653. view["persp"] = {}
  654. iview["persp"] = {}
  655. view["persp"]["value"] = self.__processLayerNvizNode(node_persp, "value", int)
  656. view["persp"]["step"] = self.__processLayerNvizNode(node_persp, "step", int)
  657. iview["persp"]["min"] = self.__processLayerNvizNode(node_persp, "min", int)
  658. iview["persp"]["max"] = self.__processLayerNvizNode(node_persp, "max", int)
  659. node_height = node_view.find("v_height")
  660. iview["height"] = {}
  661. iview["height"]["value"] = self.__processLayerNvizNode(
  662. node_height, "value", int
  663. )
  664. iview["height"]["min"] = self.__processLayerNvizNode(node_height, "min", int)
  665. iview["height"]["max"] = self.__processLayerNvizNode(node_height, "max", int)
  666. node_twist = node_view.find("twist")
  667. view["twist"] = {}
  668. iview["twist"] = {}
  669. view["twist"]["value"] = self.__processLayerNvizNode(node_twist, "value", int)
  670. iview["twist"]["min"] = self.__processLayerNvizNode(node_twist, "min", int)
  671. iview["twist"]["max"] = self.__processLayerNvizNode(node_twist, "max", int)
  672. node_zexag = node_view.find("z-exag")
  673. view["z-exag"] = {}
  674. iview["z-exag"] = {}
  675. view["z-exag"]["value"] = self.__processLayerNvizNode(
  676. node_zexag, "value", float
  677. )
  678. view["z-exag"]["min"] = self.__processLayerNvizNode(node_zexag, "min", int)
  679. view["z-exag"]["max"] = self.__processLayerNvizNode(node_zexag, "max", int)
  680. iview["z-exag"]["llRatio"] = self.__processLayerNvizNode(
  681. node_zexag, "llRatio", float
  682. )
  683. node_focus = node_view.find("focus")
  684. iview["focus"] = {}
  685. iview["focus"]["x"] = self.__processLayerNvizNode(node_focus, "x", int)
  686. iview["focus"]["y"] = self.__processLayerNvizNode(node_focus, "y", int)
  687. iview["focus"]["z"] = self.__processLayerNvizNode(node_focus, "z", int)
  688. node_dir = node_view.find("dir")
  689. if node_dir:
  690. iview["dir"] = {}
  691. iview["dir"]["x"] = self.__processLayerNvizNode(node_dir, "x", int)
  692. iview["dir"]["y"] = self.__processLayerNvizNode(node_dir, "y", int)
  693. iview["dir"]["z"] = self.__processLayerNvizNode(node_dir, "z", int)
  694. iview["dir"]["use"] = True
  695. else:
  696. iview["dir"] = {}
  697. iview["dir"]["x"] = -1
  698. iview["dir"]["y"] = -1
  699. iview["dir"]["z"] = -1
  700. iview["dir"]["use"] = False
  701. node_rot = node_view.find("rotation")
  702. if node_rot is not None:
  703. rotation = node_rot.text
  704. if rotation:
  705. iview["rotation"] = [float(item) for item in rotation.split(",")]
  706. view["background"] = {}
  707. color = self.__processLayerNvizNode(node_view, "background_color", str)
  708. view["background"]["color"] = tuple(map(int, color.split(":")))
  709. self.nviz_state["view"] = view
  710. self.nviz_state["iview"] = iview
  711. #
  712. # light
  713. #
  714. node_light = node_state.find("light")
  715. light = {}
  716. node_position = node_light.find("l_position")
  717. light["position"] = {}
  718. light["position"]["x"] = self.__processLayerNvizNode(node_position, "x", float)
  719. light["position"]["y"] = self.__processLayerNvizNode(node_position, "y", float)
  720. light["position"]["z"] = self.__processLayerNvizNode(node_position, "z", int)
  721. light["bright"] = self.__processLayerNvizNode(node_light, "bright", int)
  722. light["ambient"] = self.__processLayerNvizNode(node_light, "ambient", int)
  723. color = self.__processLayerNvizNode(node_light, "color", str)
  724. light["color"] = tuple(map(int, color.split(":")))
  725. self.nviz_state["light"] = light
  726. node_constants = node_state.find("constant_planes")
  727. constants = []
  728. if node_constants:
  729. for node_plane in node_constants.findall("plane"):
  730. plane = {}
  731. plane["color"] = self.__processLayerNvizNode(node_plane, "color", str)
  732. plane["resolution"] = self.__processLayerNvizNode(
  733. node_plane, "fine_resolution", int
  734. )
  735. plane["value"] = self.__processLayerNvizNode(node_plane, "height", int)
  736. plane["object"] = {}
  737. constants.append({"constant": plane})
  738. self.nviz_state["constants"] = constants
  739. class WriteWorkspaceFile(object):
  740. """Generic class for writing workspace file"""
  741. def __init__(self, lmgr, file):
  742. self.outfile = file
  743. file = StringIO()
  744. self.file = file
  745. self.lmgr = lmgr
  746. self.indent = 0
  747. # write header
  748. self.file.write(
  749. '<?xml version="1.0" encoding="%s"?>\n' % GetDefaultEncoding(forceUTF8=True)
  750. )
  751. self.file.write('<!DOCTYPE gxw SYSTEM "grass-gxw.dtd">\n')
  752. self.file.write("%s<gxw>\n" % (" " * self.indent))
  753. self.indent = +4
  754. database, location, mapset = get_database_location_mapset()
  755. file.write("{indent}<session>\n".format(indent=" " * self.indent))
  756. self.indent += 4
  757. file.write(
  758. "{indent}<database>{database}</database>\n".format(
  759. indent=" " * self.indent, database=database
  760. )
  761. )
  762. file.write(
  763. "{indent}<location>{location}</location>\n".format(
  764. indent=" " * self.indent, location=location
  765. )
  766. )
  767. file.write(
  768. "{indent}<mapset>{mapset}</mapset>\n".format(
  769. indent=" " * self.indent, mapset=mapset
  770. )
  771. )
  772. self.indent -= 4
  773. file.write("{indent}</session>\n".format(indent=" " * self.indent))
  774. # layer manager
  775. windowPos = self.lmgr.GetPosition()
  776. windowSize = self.lmgr.GetSize()
  777. file.write(
  778. '%s<layer_manager dim="%d,%d,%d,%d">\n'
  779. % (
  780. " " * self.indent,
  781. windowPos[0],
  782. windowPos[1],
  783. windowSize[0],
  784. windowSize[1],
  785. )
  786. )
  787. self.indent += 4
  788. cwdPath = self.lmgr.GetCwdPath()
  789. if cwdPath:
  790. file.write("%s<cwd>%s</cwd>\n" % (" " * self.indent, cwdPath))
  791. self.indent -= 4
  792. file.write("%s</layer_manager>\n" % (" " * self.indent))
  793. # list of displays
  794. for page in range(0, self.lmgr.GetLayerNotebook().GetPageCount()):
  795. dispName = self.lmgr.GetLayerNotebook().GetPageText(page)
  796. mapTree = self.lmgr.GetLayerNotebook().GetPage(page).maptree
  797. region = mapTree.GetMap().GetCurrentRegion()
  798. compRegion = gcore.region(region3d=True)
  799. mapdisp = mapTree.GetMapDisplay()
  800. displayPos = mapdisp.GetPosition()
  801. displaySize = mapdisp.GetSize()
  802. if mapdisp.toolbars["map"].combo.GetSelection() == 1:
  803. viewmode = "3d"
  804. else:
  805. viewmode = "2d"
  806. file.write(
  807. "%s<display "
  808. 'name="%s" render="%d" '
  809. 'mode="%d" showCompExtent="%d" '
  810. 'alignExtent="%d" '
  811. 'constrainRes="%d" '
  812. 'showStatusbar="%d" '
  813. 'showToolbars="%d" '
  814. 'dim="%d,%d,%d,%d" '
  815. 'extent="%f,%f,%f,%f,%f,%f" '
  816. 'tbres="%f" ' # needed only for animation tool
  817. 'viewMode="%s" >\n'
  818. % (
  819. " " * self.indent,
  820. dispName,
  821. int(mapdisp.mapWindowProperties.autoRender),
  822. mapdisp.statusbarManager.GetMode(),
  823. int(mapdisp.mapWindowProperties.showRegion),
  824. int(mapdisp.mapWindowProperties.alignExtent),
  825. int(mapdisp.mapWindowProperties.resolution),
  826. int(mapdisp.IsStatusbarShown()),
  827. int(mapdisp.GetMapToolbar().IsShown()),
  828. displayPos[0],
  829. displayPos[1],
  830. displaySize[0],
  831. displaySize[1],
  832. region["w"],
  833. region["s"],
  834. region["e"],
  835. region["n"],
  836. compRegion["b"],
  837. compRegion["t"],
  838. compRegion["tbres"],
  839. viewmode,
  840. )
  841. )
  842. # projection statusbar info
  843. if mapdisp.GetProperty("projection") and UserSettings.Get(
  844. group="display", key="projection", subkey="proj4"
  845. ):
  846. self.indent += 4
  847. file.write("%s<projection" % (" " * self.indent))
  848. epsg = UserSettings.Get(
  849. group="display", key="projection", subkey="epsg"
  850. )
  851. if epsg:
  852. file.write(' epsg="%s"' % epsg)
  853. file.write(">\n")
  854. proj = UserSettings.Get(
  855. group="display", key="projection", subkey="proj4"
  856. )
  857. self.indent += 4
  858. file.write("%s<value>%s</value>\n" % (" " * self.indent, proj))
  859. self.indent -= 4
  860. file.write("%s</projection>\n" % (" " * self.indent))
  861. self.indent -= 4
  862. # list of layers
  863. item = mapTree.GetFirstChild(mapTree.root)[0]
  864. self.__writeLayer(mapTree, item)
  865. if mapdisp.MapWindow3D is not None:
  866. nvizDisp = mapdisp.MapWindow3D
  867. self.__writeNvizState(
  868. view=nvizDisp.view,
  869. iview=nvizDisp.iview,
  870. light=nvizDisp.light,
  871. constants=nvizDisp.constants,
  872. )
  873. # list of map elements
  874. item = mapTree.GetFirstChild(mapTree.root)[0]
  875. self.__writeOverlay(mapdisp)
  876. file.write("%s</display>\n" % (" " * self.indent))
  877. self.indent = -4
  878. file.write("%s</gxw>\n" % (" " * self.indent))
  879. self.outfile.write(EncodeString(file.getvalue()))
  880. file.close()
  881. def __filterValue(self, value):
  882. """Make value XML-valid"""
  883. value = value.replace("<", "&lt;")
  884. value = value.replace(">", "&gt;")
  885. value = value.replace("&", "&amp;")
  886. return value
  887. def __writeLayer(self, mapTree, item):
  888. """Write bunch of layers to GRASS Workspace XML file"""
  889. self.indent += 4
  890. itemSelected = mapTree.GetSelections()
  891. while item and item.IsOk():
  892. type = mapTree.GetLayerInfo(item, key="type")
  893. if type != "group":
  894. maplayer = mapTree.GetLayerInfo(item, key="maplayer")
  895. else:
  896. maplayer = None
  897. checked = int(item.IsChecked())
  898. if type == "command":
  899. cmd = mapTree.GetLayerInfo(item, key="maplayer").GetCmd(string=True)
  900. self.file.write(
  901. '%s<layer type="%s" name="%s" checked="%d">\n'
  902. % (" " * self.indent, type, cmd, checked)
  903. )
  904. self.file.write("%s</layer>\n" % (" " * self.indent))
  905. elif type == "group":
  906. name = mapTree.GetItemText(item)
  907. self.file.write(
  908. '%s<group name="%s" checked="%d">\n'
  909. % (" " * self.indent, name, checked)
  910. )
  911. self.indent += 4
  912. subItem = mapTree.GetFirstChild(item)[0]
  913. self.__writeLayer(mapTree, subItem)
  914. self.indent -= 4
  915. self.file.write("%s</group>\n" % (" " * self.indent))
  916. else:
  917. cmd = mapTree.GetLayerInfo(item, key="maplayer").GetCmd(string=False)
  918. name = mapTree.GetItemText(item).replace(os.linesep, "\\n")
  919. opacity = maplayer.GetOpacity()
  920. # remove 'opacity' part
  921. if opacity < 1:
  922. name = name.split("(", -1)[0].strip()
  923. self.file.write(
  924. '%s<layer type="%s" name="%s" checked="%d" opacity="%f">\n'
  925. % (" " * self.indent, type, name, checked, opacity)
  926. )
  927. self.indent += 4
  928. # selected ?
  929. if item in itemSelected:
  930. self.file.write("%s<selected />\n" % (" " * self.indent))
  931. # layer properties
  932. self.file.write('%s<task name="%s">\n' % (" " * self.indent, cmd[0]))
  933. self.indent += 4
  934. for key, val in six.iteritems(cmd[1]):
  935. if key == "flags":
  936. for f in val:
  937. self.file.write(
  938. '%s<flag name="%s" />\n' % (" " * self.indent, f)
  939. )
  940. elif val in (True, False):
  941. self.file.write(
  942. '%s<flag name="%s" />\n' % (" " * self.indent, key)
  943. )
  944. else: # parameter
  945. self.file.write(
  946. '%s<parameter name="%s">\n' % (" " * self.indent, key)
  947. )
  948. self.indent += 4
  949. self.file.write(
  950. "%s<value>%s</value>\n"
  951. % (" " * self.indent, self.__filterValue(val))
  952. )
  953. self.indent -= 4
  954. self.file.write("%s</parameter>\n" % (" " * self.indent))
  955. self.indent -= 4
  956. self.file.write("%s</task>\n" % (" " * self.indent))
  957. # vector digitizer
  958. vdigit = mapTree.GetLayerInfo(item, key="vdigit")
  959. if vdigit:
  960. self.file.write("%s<vdigit>\n" % (" " * self.indent))
  961. if "geomAttr" in vdigit:
  962. self.indent += 4
  963. for type, val in six.iteritems(vdigit["geomAttr"]):
  964. units = ""
  965. if val["units"] != "mu":
  966. units = ' units="%s"' % val["units"]
  967. self.file.write(
  968. '%s<geometryAttribute type="%s" column="%s"%s />\n'
  969. % (" " * self.indent, type, val["column"], units)
  970. )
  971. self.indent -= 4
  972. self.file.write("%s</vdigit>\n" % (" " * self.indent))
  973. # nviz
  974. nviz = mapTree.GetLayerInfo(item, key="nviz")
  975. if nviz:
  976. self.file.write("%s<nviz>\n" % (" " * self.indent))
  977. if maplayer.type == "raster":
  978. self.__writeNvizSurface(nviz["surface"])
  979. if maplayer.type == "raster_3d":
  980. self.__writeNvizVolume(nviz["volume"])
  981. elif maplayer.type == "vector":
  982. self.__writeNvizVector(nviz["vector"])
  983. self.file.write("%s</nviz>\n" % (" " * self.indent))
  984. self.indent -= 4
  985. self.file.write("%s</layer>\n" % (" " * self.indent))
  986. item = mapTree.GetNextSibling(item)
  987. self.indent -= 4
  988. def __writeNvizSurface(self, data):
  989. """Save Nviz raster layer properties to workspace
  990. :param data: Nviz layer properties
  991. """
  992. if "object" not in data: # skip disabled
  993. return
  994. self.indent += 4
  995. self.file.write("%s<surface>\n" % (" " * self.indent))
  996. self.indent += 4
  997. for attrb in six.iterkeys(data):
  998. if len(data[attrb]) < 1: # skip empty attributes
  999. continue
  1000. if attrb == "object":
  1001. continue
  1002. for name in six.iterkeys(data[attrb]):
  1003. # surface attribute
  1004. if attrb == "attribute":
  1005. if data[attrb][name]["map"] is None:
  1006. continue
  1007. self.file.write(
  1008. '%s<%s name="%s" map="%d">\n'
  1009. % (" " * self.indent, attrb, name, data[attrb][name]["map"])
  1010. )
  1011. self.indent += 4
  1012. self.file.write(
  1013. "%s<value>%s</value>\n"
  1014. % (" " * self.indent, data[attrb][name]["value"])
  1015. )
  1016. self.indent -= 4
  1017. # end tag
  1018. self.file.write("%s</%s>\n" % (" " * self.indent, attrb))
  1019. # draw mode
  1020. if attrb == "draw":
  1021. self.file.write("%s<%s" % (" " * self.indent, attrb))
  1022. if "mode" in data[attrb]:
  1023. for tag, value in six.iteritems(data[attrb]["mode"]["desc"]):
  1024. self.file.write(' %s="%s"' % (tag, value))
  1025. self.file.write(">\n") # <draw ...>
  1026. if "resolution" in data[attrb]:
  1027. self.indent += 4
  1028. for type in ("coarse", "fine"):
  1029. self.file.write(
  1030. '%s<resolution type="%s">\n' % (" " * self.indent, type)
  1031. )
  1032. self.indent += 4
  1033. self.file.write(
  1034. "%s<value>%d</value>\n"
  1035. % (" " * self.indent, data[attrb]["resolution"][type])
  1036. )
  1037. self.indent -= 4
  1038. self.file.write("%s</resolution>\n" % (" " * self.indent))
  1039. if "wire-color" in data[attrb]:
  1040. self.file.write("%s<wire_color>\n" % (" " * self.indent))
  1041. self.indent += 4
  1042. self.file.write(
  1043. "%s<value>%s</value>\n"
  1044. % (" " * self.indent, data[attrb]["wire-color"]["value"])
  1045. )
  1046. self.indent -= 4
  1047. self.file.write("%s</wire_color>\n" % (" " * self.indent))
  1048. self.indent -= 4
  1049. # position
  1050. elif attrb == "position":
  1051. self.file.write("%s<%s>\n" % (" " * self.indent, attrb))
  1052. for tag in ("x", "y", "z"):
  1053. self.indent += 4
  1054. self.file.write(
  1055. "%s<%s>%d</%s>\n"
  1056. % (" " * self.indent, tag, data[attrb][tag], tag)
  1057. )
  1058. self.indent -= 4
  1059. if attrb != "attribute":
  1060. # end tag
  1061. self.file.write("%s</%s>\n" % (" " * self.indent, attrb))
  1062. self.indent -= 4
  1063. self.file.write("%s</surface>\n" % (" " * self.indent))
  1064. self.indent -= 4
  1065. def __writeNvizVolume(self, data):
  1066. """Save Nviz volume layer properties to workspace
  1067. :param data: Nviz layer properties
  1068. """
  1069. if "object" not in data: # skip disabled
  1070. return
  1071. self.indent += 4
  1072. self.file.write("%s<volume>\n" % (" " * self.indent))
  1073. self.indent += 4
  1074. for attrb in six.iterkeys(data):
  1075. if len(data[attrb]) < 1: # skip empty attributes
  1076. continue
  1077. if attrb == "object":
  1078. continue
  1079. if attrb == "attribute":
  1080. for name in six.iterkeys(data[attrb]):
  1081. # surface attribute
  1082. if data[attrb][name]["map"] is None:
  1083. continue
  1084. self.file.write(
  1085. '%s<%s name="%s" map="%d">\n'
  1086. % (" " * self.indent, attrb, name, data[attrb][name]["map"])
  1087. )
  1088. self.indent += 4
  1089. self.file.write(
  1090. "%s<value>%s</value>\n"
  1091. % (" " * self.indent, data[attrb][name]["value"])
  1092. )
  1093. self.indent -= 4
  1094. # end tag
  1095. self.file.write("%s</%s>\n" % (" " * self.indent, attrb))
  1096. # draw mode
  1097. if attrb == "draw":
  1098. self.file.write("%s<%s>\n" % (" " * self.indent, attrb))
  1099. self.indent += 4
  1100. for att in ("resolution", "shading"):
  1101. if att in data[attrb]:
  1102. self.file.write("%s<%s>\n" % (" " * self.indent, att))
  1103. for type in ("isosurface", "slice"):
  1104. self.indent += 4
  1105. self.file.write("%s<%s>\n" % (" " * self.indent, type))
  1106. self.indent += 4
  1107. self.file.write(
  1108. "%s<value>%d</value>\n"
  1109. % (" " * self.indent, data[attrb][att][type]["value"])
  1110. )
  1111. if att == "shading":
  1112. self.file.write(
  1113. "%s<desc>%s</desc>\n"
  1114. % (
  1115. " " * self.indent,
  1116. data[attrb][att][type]["desc"],
  1117. )
  1118. )
  1119. self.indent -= 4
  1120. self.file.write("%s</%s>\n" % (" " * self.indent, type))
  1121. self.indent -= 4
  1122. self.file.write("%s</%s>\n" % (" " * self.indent, att))
  1123. if "box" in data[attrb]:
  1124. self.file.write("%s<box>\n" % (" " * self.indent))
  1125. self.indent += 4
  1126. self.file.write(
  1127. "%s<enabled>%d</enabled>\n"
  1128. % (" " * self.indent, data[attrb]["box"]["enabled"])
  1129. )
  1130. self.indent -= 4
  1131. self.file.write("%s</box>\n" % (" " * self.indent))
  1132. if "mode" in data[attrb]:
  1133. self.file.write("%s<mode>\n" % (" " * self.indent))
  1134. self.indent += 4
  1135. self.file.write(
  1136. "%s<desc>%s</desc>\n"
  1137. % (" " * self.indent, data[attrb]["mode"]["desc"])
  1138. )
  1139. self.file.write(
  1140. "%s<value>%d</value>\n"
  1141. % (" " * self.indent, data[attrb]["mode"]["value"])
  1142. )
  1143. self.indent -= 4
  1144. self.file.write("%s</mode>\n" % (" " * self.indent))
  1145. self.indent -= 4
  1146. # position
  1147. elif attrb == "position":
  1148. self.file.write("%s<%s>\n" % (" " * self.indent, attrb))
  1149. for tag in ("x", "y", "z"):
  1150. self.indent += 4
  1151. self.file.write(
  1152. "%s<%s>%d</%s>\n"
  1153. % (" " * self.indent, tag, data[attrb].get(tag, 0), tag)
  1154. )
  1155. self.indent -= 4
  1156. if attrb == "isosurface":
  1157. for isosurface in data[attrb]:
  1158. self.file.write("%s<%s>\n" % (" " * self.indent, attrb))
  1159. for name in six.iterkeys(isosurface):
  1160. self.indent += 4
  1161. self.file.write("%s<%s>\n" % (" " * self.indent, name))
  1162. for att in six.iterkeys(isosurface[name]):
  1163. if isosurface[name][att] is True:
  1164. val = "1"
  1165. elif isosurface[name][att] is False:
  1166. val = "0"
  1167. else:
  1168. try:
  1169. val = "%f" % float(isosurface[name][att])
  1170. except ValueError:
  1171. val = "%s" % isosurface[name][att]
  1172. except TypeError: # None
  1173. val = ""
  1174. self.indent += 4
  1175. self.file.write(("%s<%s>" % (" " * self.indent, att)) + val)
  1176. self.file.write("</%s>\n" % att)
  1177. self.indent -= 4
  1178. # end tag
  1179. self.file.write("%s</%s>\n" % (" " * self.indent, name))
  1180. self.indent -= 4
  1181. self.file.write("%s</%s>\n" % (" " * self.indent, attrb))
  1182. if attrb == "slice":
  1183. for slice_ in data[attrb]:
  1184. self.file.write("%s<%s>\n" % (" " * self.indent, attrb))
  1185. for name in six.iterkeys(slice_):
  1186. self.indent += 4
  1187. self.file.write("%s<%s>\n" % (" " * self.indent, name))
  1188. for att in six.iterkeys(slice_[name]):
  1189. if att in ("map", "update"):
  1190. continue
  1191. val = slice_[name][att]
  1192. self.indent += 4
  1193. self.file.write(
  1194. ("%s<%s>" % (" " * self.indent, att)) + str(val)
  1195. )
  1196. self.file.write("</%s>\n" % att)
  1197. self.indent -= 4
  1198. # end tag
  1199. self.file.write("%s</%s>\n" % (" " * self.indent, name))
  1200. self.indent -= 4
  1201. self.file.write("%s</%s>\n" % (" " * self.indent, attrb))
  1202. if attrb not in ("attribute", "isosurface", "slice"):
  1203. # end tag
  1204. self.file.write("%s</%s>\n" % (" " * self.indent, attrb))
  1205. self.indent -= 4
  1206. self.file.write("%s</volume>\n" % (" " * self.indent))
  1207. self.indent -= 4
  1208. def __writeNvizVector(self, data):
  1209. """Save Nviz vector layer properties (lines/points) to workspace
  1210. :param data: Nviz layer properties
  1211. """
  1212. self.indent += 4
  1213. for attrb in six.iterkeys(data):
  1214. if len(data[attrb]) < 1: # skip empty attributes
  1215. continue
  1216. if "object" not in data[attrb]: # skip disabled
  1217. continue
  1218. if attrb == "lines":
  1219. self.file.write("%s<v%s>\n" % (" " * self.indent, attrb))
  1220. elif attrb == "points":
  1221. markerId = data[attrb]["marker"]["value"]
  1222. marker = UserSettings.Get(
  1223. group="nviz",
  1224. key="vector",
  1225. subkey=["points", "marker"],
  1226. settings_type="internal",
  1227. )[markerId]
  1228. self.file.write(
  1229. '%s<v%s marker="%s">\n' % (" " * self.indent, attrb, marker)
  1230. )
  1231. self.indent += 4
  1232. for name in six.iterkeys(data[attrb]):
  1233. if name in ("object", "marker"):
  1234. continue
  1235. if name == "mode":
  1236. self.file.write(
  1237. '%s<%s type="%s">\n'
  1238. % (" " * self.indent, name, data[attrb][name]["type"])
  1239. )
  1240. if data[attrb][name]["type"] == "surface":
  1241. self.indent += 4
  1242. for idx, surface in enumerate(
  1243. data[attrb][name]["surface"]["value"]
  1244. ):
  1245. checked = data[attrb][name]["surface"]["show"][idx]
  1246. self.file.write("%s<map>\n" % (" " * self.indent))
  1247. self.indent += 4
  1248. self.file.write(
  1249. "%s<name>%s</name>\n" % (" " * self.indent, surface)
  1250. )
  1251. self.file.write(
  1252. "%s<checked>%s</checked>\n"
  1253. % (" " * self.indent, int(checked))
  1254. )
  1255. self.indent -= 4
  1256. self.file.write("%s</map>\n" % (" " * self.indent))
  1257. self.indent -= 4
  1258. self.file.write("%s</%s>\n" % ((" " * self.indent, name)))
  1259. elif name == "thematic":
  1260. self.file.write("%s<%s " % (" " * self.indent, name))
  1261. for key in six.iterkeys(data[attrb][name]):
  1262. if key.startswith("use"):
  1263. self.file.write(
  1264. '%s="%s" ' % (key, int(data[attrb][name][key]))
  1265. )
  1266. self.file.write(">\n")
  1267. self.indent += 4
  1268. for key, value in six.iteritems(data[attrb][name]):
  1269. if key.startswith("use"):
  1270. continue
  1271. if value is None:
  1272. value = ""
  1273. self.file.write(
  1274. "%s<%s>%s</%s>\n" % (" " * self.indent, key, value, key)
  1275. )
  1276. self.indent -= 4
  1277. self.file.write("%s</%s>\n" % (" " * self.indent, name))
  1278. else:
  1279. self.file.write("%s<%s>\n" % (" " * self.indent, name))
  1280. self.indent += 4
  1281. self.file.write(
  1282. "%s<value>%s</value>\n"
  1283. % (" " * self.indent, data[attrb][name]["value"])
  1284. )
  1285. self.indent -= 4
  1286. self.file.write("%s</%s>\n" % (" " * self.indent, name))
  1287. self.indent -= 4
  1288. self.file.write("%s</v%s>\n" % (" " * self.indent, attrb))
  1289. self.indent -= 4
  1290. def __writeNvizState(self, view, iview, light, constants):
  1291. """ "Save Nviz properties (view, light) to workspace
  1292. :param view: Nviz view properties
  1293. :param iview: Nviz internal view properties
  1294. :param light: Nviz light properties
  1295. """
  1296. self.indent += 4
  1297. self.file.write("%s<nviz_state>\n" % (" " * self.indent))
  1298. #
  1299. # view
  1300. #
  1301. self.indent += 4
  1302. self.file.write("%s<view>\n" % (" " * self.indent))
  1303. self.indent += 4
  1304. # position
  1305. self.file.write("%s<v_position>\n" % (" " * self.indent))
  1306. self.indent += 4
  1307. self.file.write("%s<x>%.2f</x>\n" % (" " * self.indent, view["position"]["x"]))
  1308. self.file.write("%s<y>%.2f</y>\n" % (" " * self.indent, view["position"]["y"]))
  1309. self.indent -= 4
  1310. self.file.write("%s</v_position>\n" % (" " * self.indent))
  1311. # perspective
  1312. self.file.write("%s<persp>\n" % (" " * self.indent))
  1313. self.indent += 4
  1314. self.file.write(
  1315. "%s<value>%d</value>\n" % (" " * self.indent, view["persp"]["value"])
  1316. )
  1317. self.file.write(
  1318. "%s<step>%d</step>\n" % (" " * self.indent, view["persp"]["step"])
  1319. )
  1320. self.file.write(
  1321. "%s<min>%d</min>\n" % (" " * self.indent, iview["persp"]["min"])
  1322. )
  1323. self.file.write(
  1324. "%s<max>%d</max>\n" % (" " * self.indent, iview["persp"]["max"])
  1325. )
  1326. self.indent -= 4
  1327. self.file.write("%s</persp>\n" % (" " * self.indent))
  1328. # height
  1329. self.file.write("%s<v_height>\n" % (" " * self.indent))
  1330. self.indent += 4
  1331. self.file.write(
  1332. "%s<value>%d</value>\n" % (" " * self.indent, iview["height"]["value"])
  1333. )
  1334. self.file.write(
  1335. "%s<min>%d</min>\n" % (" " * self.indent, iview["height"]["min"])
  1336. )
  1337. self.file.write(
  1338. "%s<max>%d</max>\n" % (" " * self.indent, iview["height"]["max"])
  1339. )
  1340. self.indent -= 4
  1341. self.file.write("%s</v_height>\n" % (" " * self.indent))
  1342. # twist
  1343. self.file.write("%s<twist>\n" % (" " * self.indent))
  1344. self.indent += 4
  1345. self.file.write(
  1346. "%s<value>%d</value>\n" % (" " * self.indent, view["twist"]["value"])
  1347. )
  1348. self.file.write(
  1349. "%s<min>%d</min>\n" % (" " * self.indent, iview["twist"]["min"])
  1350. )
  1351. self.file.write(
  1352. "%s<max>%d</max>\n" % (" " * self.indent, iview["twist"]["max"])
  1353. )
  1354. self.indent -= 4
  1355. self.file.write("%s</twist>\n" % (" " * self.indent))
  1356. # z-exag
  1357. self.file.write("%s<z-exag>\n" % (" " * self.indent))
  1358. self.indent += 4
  1359. self.file.write(
  1360. "%s<value>%.2f</value>\n" % (" " * self.indent, view["z-exag"]["value"])
  1361. )
  1362. self.file.write(
  1363. "%s<min>%d</min>\n" % (" " * self.indent, view["z-exag"]["min"])
  1364. )
  1365. self.file.write(
  1366. "%s<max>%d</max>\n" % (" " * self.indent, view["z-exag"]["max"])
  1367. )
  1368. self.file.write(
  1369. "%s<llRatio>%.2f</llRatio>\n"
  1370. % (" " * self.indent, iview["z-exag"]["llRatio"])
  1371. )
  1372. self.indent -= 4
  1373. self.file.write("%s</z-exag>\n" % (" " * self.indent))
  1374. # focus (look here)
  1375. self.file.write("%s<focus>\n" % (" " * self.indent))
  1376. self.indent += 4
  1377. self.file.write("%s<x>%d</x>\n" % (" " * self.indent, iview["focus"]["x"]))
  1378. self.file.write("%s<y>%d</y>\n" % (" " * self.indent, iview["focus"]["y"]))
  1379. self.file.write("%s<z>%d</z>\n" % (" " * self.indent, iview["focus"]["z"]))
  1380. self.indent -= 4
  1381. self.file.write("%s</focus>\n" % (" " * self.indent))
  1382. # rotation
  1383. rotation = (
  1384. ",".join([str(i) for i in iview["rotation"]])
  1385. if iview.get("rotation", "")
  1386. else ""
  1387. )
  1388. self.file.write("%s<rotation>%s</rotation>\n" % (" " * self.indent, rotation))
  1389. # background
  1390. self.__writeTagWithValue(
  1391. "background_color", view["background"]["color"][:3], format="d:%d:%d"
  1392. )
  1393. self.indent -= 4
  1394. self.file.write("%s</view>\n" % (" " * self.indent))
  1395. #
  1396. # light
  1397. #
  1398. self.file.write("%s<light>\n" % (" " * self.indent))
  1399. self.indent += 4
  1400. # position
  1401. self.file.write("%s<l_position>\n" % (" " * self.indent))
  1402. self.indent += 4
  1403. self.file.write("%s<x>%.2f</x>\n" % (" " * self.indent, light["position"]["x"]))
  1404. self.file.write("%s<y>%.2f</y>\n" % (" " * self.indent, light["position"]["y"]))
  1405. self.file.write("%s<z>%d</z>\n" % (" " * self.indent, light["position"]["z"]))
  1406. self.indent -= 4
  1407. self.file.write("%s</l_position>\n" % (" " * self.indent))
  1408. # bright
  1409. self.__writeTagWithValue("bright", light["bright"])
  1410. # ambient
  1411. self.__writeTagWithValue("ambient", light["ambient"])
  1412. # color
  1413. self.__writeTagWithValue("color", light["color"][:3], format="d:%d:%d")
  1414. self.indent -= 4
  1415. self.file.write("%s</light>\n" % (" " * self.indent))
  1416. #
  1417. # constant planes
  1418. #
  1419. if constants:
  1420. self.file.write("%s<constant_planes>\n" % (" " * self.indent))
  1421. self.indent += 4
  1422. for idx, plane in enumerate(constants):
  1423. self.file.write("%s<plane>\n" % (" " * self.indent))
  1424. self.indent += 4
  1425. self.__writeTagWithValue("height", constants[idx]["constant"]["value"])
  1426. self.__writeTagWithValue(
  1427. "fine_resolution", constants[idx]["constant"]["resolution"]
  1428. )
  1429. self.__writeTagWithValue(
  1430. "color", constants[idx]["constant"]["color"], format="s"
  1431. )
  1432. self.indent -= 4
  1433. self.file.write("%s</plane>\n" % (" " * self.indent))
  1434. self.indent -= 4
  1435. self.file.write("%s</constant_planes>\n" % (" " * self.indent))
  1436. self.indent -= 4
  1437. self.file.write("%s</nviz_state>\n" % (" " * self.indent))
  1438. self.indent -= 4
  1439. def __writeTagWithValue(self, tag, data, format="d"):
  1440. """Helper function for writing pair tag
  1441. :param tag: written tag
  1442. :param data: written data
  1443. :param format: conversion type
  1444. """
  1445. self.file.write("%s<%s>\n" % (" " * self.indent, tag))
  1446. self.indent += 4
  1447. self.file.write("%s" % (" " * self.indent))
  1448. self.file.write(("<value>%" + format + "</value>\n") % data)
  1449. self.indent -= 4
  1450. self.file.write("%s</%s>\n" % (" " * self.indent, tag))
  1451. def __writeOverlay(self, mapdisp):
  1452. """Function for writing map elements (barscale, northarrow etc.)"""
  1453. disp_size = mapdisp.GetMapWindow().GetClientSize()
  1454. for overlay in mapdisp.decorations.values():
  1455. self.__writeOverlayParams(disp_size, overlay.cmd, overlay.coords)
  1456. def __writeOverlayParams(self, disp_size, cmd, coord_px):
  1457. """
  1458. :param mapdisp: mapdisplay
  1459. :param cmd: d.* command with flags and parameters
  1460. """
  1461. # Canvas width = display width minus 1 px on both sides
  1462. cnvs_w = float(disp_size[0])
  1463. # Canvas height = display height minus 1 px on bottom and height of toolbar
  1464. cnvs_h = float(disp_size[1])
  1465. x_prcn = round(coord_px[0] / cnvs_w * 100, 1)
  1466. y_prcn = 100 - round(coord_px[1] / cnvs_h * 100, 1)
  1467. self.indent += 4
  1468. self.file.write('%s<overlay name="%s">\n' % (" " * self.indent, cmd[0]))
  1469. self.indent += 4
  1470. for prm in cmd[1:]:
  1471. if prm.startswith("-"):
  1472. flags = []
  1473. if prm.startswith("--"):
  1474. flags.append(prm[2:])
  1475. else:
  1476. flags = list(prm[1:])
  1477. for f in flags:
  1478. self.file.write('%s<flag name="%s" />\n' % (" " * self.indent, f))
  1479. elif prm.startswith("at="):
  1480. # legend "at" argument takes 4 numbers not 2
  1481. if cmd[0] == "d.legend":
  1482. leg_coord_prcn = prm.split("=", 1)[1].split(",")
  1483. leg_w = float(leg_coord_prcn[3]) - float(leg_coord_prcn[2])
  1484. leg_h = float(leg_coord_prcn[1]) - float(leg_coord_prcn[0])
  1485. self.file.write('%s<parameter name="at">\n' % (" " * self.indent))
  1486. self.indent += 4
  1487. self.file.write(
  1488. "%s<value>%.1f,%.1f,%.1f,%.1f</value>\n"
  1489. % (
  1490. " " * self.indent,
  1491. y_prcn - leg_h,
  1492. y_prcn,
  1493. x_prcn,
  1494. x_prcn + leg_w,
  1495. )
  1496. )
  1497. self.indent -= 4
  1498. self.file.write("%s</parameter>\n" % (" " * self.indent))
  1499. else:
  1500. self.file.write('%s<parameter name="at">\n' % (" " * self.indent))
  1501. self.indent += 4
  1502. self.file.write(
  1503. "%s<value>%.1f,%.1f</value>\n"
  1504. % (" " * self.indent, x_prcn, y_prcn)
  1505. )
  1506. self.indent -= 4
  1507. self.file.write("%s</parameter>\n" % (" " * self.indent))
  1508. else:
  1509. self.file.write(
  1510. '%s<parameter name="%s">\n'
  1511. % (" " * self.indent, prm.split("=", 1)[0])
  1512. )
  1513. self.indent += 4
  1514. self.file.write(
  1515. "%s<value>%s</value>\n" % (" " * self.indent, prm.split("=", 1)[1])
  1516. )
  1517. self.indent -= 4
  1518. self.file.write("%s</parameter>\n" % (" " * self.indent))
  1519. self.indent -= 4
  1520. self.file.write("%s</overlay>\n" % (" " * self.indent))
  1521. self.indent -= 4
  1522. class ProcessGrcFile(object):
  1523. def __init__(self, filename):
  1524. """Process GRC file"""
  1525. self.filename = filename
  1526. # elements
  1527. self.inGroup = False
  1528. self.inRaster = False
  1529. self.inVector = False
  1530. # list of layers
  1531. self.layers = []
  1532. # error message
  1533. self.error = ""
  1534. self.num_error = 0
  1535. def read(self, parent):
  1536. """Read GRC file
  1537. :param parent: parent window
  1538. :return: list of map layers
  1539. """
  1540. try:
  1541. file = open(self.filename, "r")
  1542. except IOError:
  1543. wx.MessageBox(
  1544. parent=parent,
  1545. message=_("Unable to open file <%s> for reading.") % self.filename,
  1546. caption=_("Error"),
  1547. style=wx.OK | wx.ICON_ERROR,
  1548. )
  1549. return []
  1550. line_id = 1
  1551. for line in file.readlines():
  1552. self.process_line(line.rstrip("\n"), line_id)
  1553. line_id += 1
  1554. file.close()
  1555. if self.num_error > 0:
  1556. wx.MessageBox(
  1557. parent=parent,
  1558. message=_(
  1559. "Some lines were skipped when reading settings "
  1560. "from file <%(file)s>.\nSee 'Command output' window for details.\n\n"
  1561. "Number of skipped lines: %(line)d"
  1562. )
  1563. % {"file": self.filename, "line": self.num_error},
  1564. caption=_("Warning"),
  1565. style=wx.OK | wx.ICON_EXCLAMATION,
  1566. )
  1567. parent._gconsole.WriteLog(
  1568. "Map layers loaded from GRC file <%s>" % self.filename
  1569. )
  1570. parent._gconsole.WriteLog("Skipped lines:\n%s" % self.error)
  1571. return self.layers
  1572. def process_line(self, line, line_id):
  1573. """Process line definition"""
  1574. element = self._get_element(line)
  1575. if element == "Group":
  1576. self.groupName = self._get_value(line)
  1577. self.layers.append(
  1578. {
  1579. "type": "group",
  1580. "name": self.groupName,
  1581. "checked": None,
  1582. "opacity": None,
  1583. "cmd": None,
  1584. "group": self.inGroup,
  1585. "display": 0,
  1586. }
  1587. )
  1588. self.inGroup = True
  1589. elif element == "_check":
  1590. if int(self._get_value(line)) == 1:
  1591. self.layers[-1]["checked"] = True
  1592. else:
  1593. self.layers[-1]["checked"] = False
  1594. elif element == "End":
  1595. if self.inRaster:
  1596. self.inRaster = False
  1597. elif self.inVector:
  1598. self.inVector = False
  1599. elif self.inGroup:
  1600. self.inGroup = False
  1601. elif self.inGridline:
  1602. self.inGridline = False
  1603. elif element == "opacity":
  1604. self.layers[-1]["opacity"] = float(self._get_value(line))
  1605. # raster
  1606. elif element == "Raster":
  1607. self.inRaster = True
  1608. self.layers.append(
  1609. {
  1610. "type": "raster",
  1611. "name": self._get_value(line),
  1612. "checked": None,
  1613. "opacity": None,
  1614. "cmd": ["d.rast"],
  1615. "group": self.inGroup,
  1616. "display": 0,
  1617. }
  1618. )
  1619. elif element == "map" and self.inRaster:
  1620. self.layers[-1]["cmd"].append("map=%s" % self._get_value(line))
  1621. elif element == "overlay" and self.inRaster:
  1622. if int(self._get_value(line)) == 1:
  1623. self.layers[-1]["cmd"].append("-o")
  1624. elif element == "rastquery" and self.inRaster:
  1625. value = self._get_value(line)
  1626. if value != "":
  1627. self.layers[-1]["cmd"].append("catlist=%s" % value)
  1628. elif element == "bkcolor" and self.inRaster:
  1629. value = self._get_value(line)
  1630. if value != "":
  1631. self.layers[-1]["cmd"].append("bg=%s" % value)
  1632. # vector
  1633. elif element == "Vector":
  1634. self.inVector = True
  1635. self.layers.append(
  1636. {
  1637. "type": "vector",
  1638. "name": self._get_value(line),
  1639. "checked": None,
  1640. "opacity": None,
  1641. "cmd": ["d.vect"],
  1642. "group": self.inGroup,
  1643. "display": 0,
  1644. }
  1645. )
  1646. elif element == "vector" and self.inVector:
  1647. self.layers[-1]["cmd"].append("map=%s" % self._get_value(line))
  1648. elif (
  1649. element
  1650. in (
  1651. "display_shape",
  1652. "display_cat",
  1653. "display_topo",
  1654. "display_dir",
  1655. "display_attr",
  1656. "type_point",
  1657. "type_line",
  1658. "type_boundary",
  1659. "type_centroid",
  1660. "type_area",
  1661. "type_face",
  1662. )
  1663. and self.inVector
  1664. ):
  1665. if int(self._get_value(line)) == 1:
  1666. name = element.split("_")[0]
  1667. type = element.split("_")[1]
  1668. paramId = self._get_cmd_param_index(self.layers[-1]["cmd"], name)
  1669. if paramId == -1:
  1670. self.layers[-1]["cmd"].append("%s=%s" % (name, type))
  1671. else:
  1672. self.layers[-1]["cmd"][paramId] += ",%s" % type
  1673. elif element in ("color", "fcolor", "lcolor") and self.inVector:
  1674. value = self._get_value(line)
  1675. if value != "":
  1676. self.layers[-1]["cmd"].append(
  1677. "%s=%s" % (element, self._color_name_to_rgb(value))
  1678. )
  1679. elif element == "rdmcolor" and self.inVector:
  1680. if int(self._get_value(line)) == 1:
  1681. self.layers[-1]["cmd"].append("-c")
  1682. elif element == "sqlcolor" and self.inVector:
  1683. if int(self._get_value(line)) == 1:
  1684. self.layers[-1]["cmd"].append("-a")
  1685. elif (
  1686. element
  1687. in (
  1688. "icon",
  1689. "size",
  1690. "layer",
  1691. "xref",
  1692. "yref",
  1693. "lsize",
  1694. "where",
  1695. "minreg",
  1696. "maxreg",
  1697. )
  1698. and self.inVector
  1699. ):
  1700. value = self._get_value(line)
  1701. if value != "":
  1702. self.layers[-1]["cmd"].append("%s=%s" % (element, value))
  1703. elif element == "lwidth":
  1704. value = self._get_value(line)
  1705. if value != "":
  1706. self.layers[-1]["cmd"].append("width=%s" % value)
  1707. elif element == "lfield":
  1708. value = self._get_value(line)
  1709. if value != "":
  1710. self.layers[-1]["cmd"].append("llayer=%s" % value)
  1711. elif element == "attribute":
  1712. value = self._get_value(line)
  1713. if value != "":
  1714. self.layers[-1]["cmd"].append("attrcol=%s" % value)
  1715. elif element == "cat":
  1716. value = self._get_value(line)
  1717. if value != "":
  1718. self.layers[-1]["cmd"].append("cats=%s" % value)
  1719. # gridline
  1720. elif element == "gridline":
  1721. self.inGridline = True
  1722. self.layers.append(
  1723. {
  1724. "type": "grid",
  1725. "name": self._get_value(line),
  1726. "checked": None,
  1727. "opacity": None,
  1728. "cmd": ["d.grid"],
  1729. "group": self.inGroup,
  1730. "display": 0,
  1731. }
  1732. )
  1733. elif element == "gridcolor":
  1734. value = self._get_value(line)
  1735. if value != "":
  1736. self.layers[-1]["cmd"].append(
  1737. "color=%s" % self._color_name_to_rgb(value)
  1738. )
  1739. elif element == "gridborder":
  1740. value = self._get_value(line)
  1741. if value != "":
  1742. self.layers[-1]["cmd"].append(
  1743. "bordercolor=%s" % self._color_name_to_rgb(value)
  1744. )
  1745. elif element == "textcolor":
  1746. value = self._get_value(line)
  1747. if value != "":
  1748. self.layers[-1]["cmd"].append(
  1749. "textcolor=%s" % self._color_name_to_rgb(value)
  1750. )
  1751. elif element in ("gridsize", "gridorigin"):
  1752. value = self._get_value(line)
  1753. if value != "":
  1754. self.layers[-1]["cmd"].append("%s=%s" % (element[4:], value))
  1755. elif element in "fontsize":
  1756. value = self._get_value(line)
  1757. if value != "":
  1758. self.layers[-1]["cmd"].append("%s=%s" % (element, value))
  1759. elif element == "griddraw":
  1760. value = self._get_value(line)
  1761. if value == "0":
  1762. self.layers[-1]["cmd"].append("-n")
  1763. elif element == "gridgeo":
  1764. value = self._get_value(line)
  1765. if value == "1":
  1766. self.layers[-1]["cmd"].append("-g")
  1767. elif element == "borderdraw":
  1768. value = self._get_value(line)
  1769. if value == "0":
  1770. self.layers[-1]["cmd"].append("-b")
  1771. elif element == "textdraw":
  1772. value = self._get_value(line)
  1773. if value == "0":
  1774. self.layers[-1]["cmd"].append("-t")
  1775. else:
  1776. self.error += _(" row %d:") % line_id + line + os.linesep
  1777. self.num_error += 1
  1778. def _get_value(self, line):
  1779. """Get value of element"""
  1780. try:
  1781. return line.strip(" ").split(" ")[1].strip(" ")
  1782. except:
  1783. return ""
  1784. def _get_element(self, line):
  1785. """Get element tag"""
  1786. return line.strip(" ").split(" ")[0].strip(" ")
  1787. def _get_cmd_param_index(self, cmd, name):
  1788. """Get index of parameter in cmd list
  1789. :param cmd: cmd list
  1790. :param name: parameter name
  1791. :return: index
  1792. :return: -1 if not found
  1793. """
  1794. i = 0
  1795. for param in cmd:
  1796. if "=" not in param:
  1797. i += 1
  1798. continue
  1799. if param.split("=")[0] == name:
  1800. return i
  1801. i += 1
  1802. return -1
  1803. def _color_name_to_rgb(self, value):
  1804. """Convert color name (#) to rgb values"""
  1805. col = wx.NamedColour(value)
  1806. return str(col.Red()) + ":" + str(col.Green()) + ":" + str(col.Blue())