nviz.py 101 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621
  1. """
  2. @package nviz.py
  3. @brief 2.5/3D visialization mode for Map Display Window
  4. List of classes:
  5. - GLWindow
  6. - NvizToolWindow
  7. - ViewPositionWindow
  8. (C) 2008 by the GRASS Development Team
  9. This program is free software under the GNU General Public
  10. License (>=v2). Read the file COPYING that comes with GRASS
  11. for details.
  12. @author Martin Landa <landa.martin gmail.com> (Google SoC 2008)
  13. """
  14. import os
  15. import sys
  16. import time
  17. import copy
  18. from threading import Thread
  19. import wx
  20. import wx.lib.colourselect as csel
  21. import wx.lib.scrolledpanel as scrolled
  22. errorMsg = ''
  23. try:
  24. from wx import glcanvas
  25. haveGLCanvas = True
  26. except ImportError, e:
  27. haveGLCanvas = False
  28. errorMsg = e
  29. try:
  30. from OpenGL.GL import *
  31. from OpenGL.GLUT import *
  32. haveOpenGL = True
  33. except ImportError, e:
  34. haveOpenGL = False
  35. errorMsg = e
  36. import globalvar
  37. import gcmd
  38. import gselect
  39. from debug import Debug as Debug
  40. from mapdisp import MapWindow as MapWindow
  41. from preferences import globalSettings as UserSettings
  42. try:
  43. nvizPath = os.path.join(globalvar.ETCWXDIR, "nviz")
  44. sys.path.append(nvizPath)
  45. import grass7_wxnviz as wxnviz
  46. haveNviz = True
  47. except ImportError, e:
  48. haveNviz = False
  49. errorMsg = e
  50. class GLWindow(MapWindow, glcanvas.GLCanvas):
  51. """OpenGL canvas for Map Display Window"""
  52. def __init__(self, parent, id,
  53. pos=wx.DefaultPosition,
  54. size=wx.DefaultSize,
  55. style=wx.NO_FULL_REPAINT_ON_RESIZE,
  56. Map=None, tree=None, gismgr=None):
  57. self.parent = parent # MapFrame
  58. self.Map = Map
  59. self.tree = tree
  60. self.gismgr = gismgr
  61. glcanvas.GLCanvas.__init__(self, parent, id)
  62. MapWindow.__init__(self, parent, id, pos, size, style,
  63. Map, tree, gismgr)
  64. self.parent = parent # MapFrame
  65. self.init = False
  66. self.render = True # render in full resolution
  67. # list of loaded map layers
  68. self.layers = {}
  69. for type in ('raster', 'vector'):
  70. self.layers[type] = {}
  71. self.layers[type]['name'] = []
  72. self.layers[type]['id'] = []
  73. #
  74. # create nviz instance
  75. #
  76. self.nvizClass = wxnviz.Nviz()
  77. #
  78. # set current display
  79. #
  80. self.nvizClass.SetDisplay(self)
  81. #
  82. # initialize mouse position
  83. #
  84. self.lastX = self.x = 30
  85. self.lastY = self.y = 30
  86. #
  87. # default values
  88. #
  89. self.view = copy.deepcopy(UserSettings.Get(group='nviz', key='view')) # copy
  90. self.iview = UserSettings.Get(group='nviz', key='view', internal=True)
  91. self.update = [] # list of properties to be updated
  92. self.size = None
  93. self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
  94. self.Bind(wx.EVT_SIZE, self.OnSize)
  95. self.Bind(wx.EVT_PAINT, self.OnPaint)
  96. self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
  97. self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
  98. self.Bind(wx.EVT_MOTION, self.OnMouseAction)
  99. self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseAction)
  100. def OnEraseBackground(self, event):
  101. pass # do nothing, to avoid flashing on MSW
  102. def OnSize(self, event):
  103. self.size = self.parent.GetClientSize()
  104. if self.GetContext():
  105. Debug.msg(3, "GLCanvas.OnPaint(): w=%d, h=%d" % \
  106. (self.size.width, self.size.height))
  107. self.SetCurrent()
  108. self.nvizClass.ResizeWindow(self.size.width,
  109. self.size.height)
  110. event.Skip()
  111. def OnPaint(self, event):
  112. Debug.msg(3, "GLCanvas.OnPaint()")
  113. dc = wx.PaintDC(self)
  114. self.SetCurrent()
  115. if not self.init:
  116. self.nvizClass.InitView()
  117. self.LoadDataLayers()
  118. self.ResetView()
  119. if hasattr(self.parent, "nvizToolWin"):
  120. self.parent.nvizToolWin.UpdatePage('view')
  121. layer = self.GetSelectedLayer()
  122. if layer:
  123. if layer.type == 'raster':
  124. self.parent.nvizToolWin.UpdatePage('surface')
  125. elif layer.type == 'vector':
  126. self.parent.nvizToolWin.UpdatePage('vector')
  127. self.parent.nvizToolWin.UpdateSettings()
  128. # update widgets
  129. win = self.parent.nvizToolWin.FindWindowById( \
  130. self.parent.nvizToolWin.win['vector']['lines']['surface'])
  131. win.SetItems(self.layers['raster']['name'])
  132. self.init = True
  133. self.UpdateMap()
  134. def OnMouseAction(self, event):
  135. # change position
  136. if event.Dragging() and event.LeftIsDown():
  137. self.lastX = self.lastY = self.x = self.y
  138. self.x, self.y = event.GetPosition()
  139. self.Refresh(False)
  140. # change perspective with mouse wheel
  141. wheel = event.GetWheelRotation()
  142. if wheel != 0:
  143. current = event.GetPositionTuple()[:]
  144. Debug.msg (5, "GLWindow.OnMouseMotion(): wheel=%d" % wheel)
  145. prev_value = self.view['persp']['value']
  146. if wheel > 0:
  147. value = -1 * self.view['persp']['step']
  148. else:
  149. value = self.view['persp']['step']
  150. self.view['persp']['value'] += value
  151. if self.view['persp']['value'] < 1:
  152. self.view['persp']['value'] = 1
  153. elif self.view['persp']['value'] > 100:
  154. self.view['persp']['value'] = 100
  155. if prev_value != self.view['persp']['value']:
  156. if hasattr(self.parent, "nvizToolWin"):
  157. self.parent.nvizToolWin.UpdateSettings()
  158. self.nvizClass.SetView(self.view['pos']['x'], self.view['pos']['y'],
  159. self.iview['height']['value'],
  160. self.view['persp']['value'],
  161. self.view['twist']['value'])
  162. # redraw map
  163. self.OnPaint(None)
  164. # update statusbar
  165. ### self.parent.StatusbarUpdate()
  166. def OnLeftDown(self, event):
  167. self.CaptureMouse()
  168. self.x, self.y = self.lastX, self.lastY = event.GetPosition()
  169. def OnLeftUp(self, event):
  170. self.ReleaseMouse()
  171. def UpdateMap(self, render=True):
  172. """
  173. Updates the canvas anytime there is a change to the
  174. underlaying images or to the geometry of the canvas.
  175. @param render re-render map composition
  176. """
  177. start = time.clock()
  178. self.resize = False
  179. # if self.size is None:
  180. # self.size = self.GetClientSize()
  181. # w, h = self.size
  182. # w = float(max(w, 1.0))
  183. # h = float(max(h, 1.0))
  184. # d = float(min(w, h))
  185. # xScale = d / w
  186. # yScale = d / h
  187. # print w, h, d, xScale, yScale
  188. # print self.y, self.lastY, self.x, self.lastX
  189. # print (self.y - self.lastY) * yScale, (self.x - self.lastX) * xScale
  190. # print self.x * xScale
  191. #glRotatef((self.y - self.lastY) * yScale, 1.0, 0.0, 0.0);
  192. #glRotatef((self.x - self.lastX) * xScale, 0.0, 1.0, 0.0);
  193. if self.render:
  194. self.parent.onRenderGauge.Show()
  195. self.parent.onRenderGauge.SetRange(2)
  196. self.parent.onRenderGauge.SetValue(0)
  197. if 'view' in self.update:
  198. if 'z-exag' in self.update:
  199. self.nvizClass.SetZExag(self.view['z-exag']['value'])
  200. self.update.remove('z-exag')
  201. self.nvizClass.SetView(self.view['pos']['x'], self.view['pos']['y'],
  202. self.iview['height']['value'],
  203. self.view['persp']['value'],
  204. self.view['twist']['value'])
  205. self.update.remove('view')
  206. if self.render is True:
  207. self.parent.onRenderGauge.SetValue(1)
  208. wx.Yield()
  209. self.nvizClass.Draw(False)
  210. elif render is False:
  211. self.nvizClass.Draw(True) # quick
  212. else: # None -> reuse last rendered image
  213. pass # TODO
  214. self.SwapBuffers()
  215. stop = time.clock()
  216. if self.render:
  217. self.parent.onRenderGauge.SetValue(2)
  218. # hide process bar
  219. self.parent.onRenderGauge.Hide()
  220. #
  221. # update statusbar
  222. #
  223. # self.parent.StatusbarUpdate()
  224. Debug.msg(3, "GLWindow.UpdateMap(): render=%s, -> time=%g" % \
  225. (self.render, (stop-start)))
  226. # print stop-start
  227. def EraseMap(self):
  228. """
  229. Erase the canvas
  230. """
  231. self.nvizClass.EraseMap()
  232. self.SwapBuffers()
  233. def IsLoaded(self, layer):
  234. """Check if layer (item) is already loaded"""
  235. data = self.tree.GetPyData(layer)[0]['nviz']
  236. if not data or not data.has_key('object'):
  237. return 0
  238. return 1
  239. def LoadDataLayers(self):
  240. """Load raster/vector from current layer tree
  241. @todo volumes
  242. """
  243. listOfItems = []
  244. # load raster & vector maps
  245. item = self.tree.GetFirstChild(self.tree.root)[0]
  246. while item and item.IsOk():
  247. type = self.tree.GetPyData(item)[0]['type']
  248. if not item.IsChecked() or \
  249. type not in ('raster', 'vector'):
  250. item = self.tree.GetNextSibling(item)
  251. continue
  252. listOfItems.append(item)
  253. item = self.tree.GetNextSibling(item)
  254. start = time.time()
  255. while(len(listOfItems) > 0):
  256. item = listOfItems.pop()
  257. type = self.tree.GetPyData(item)[0]['type']
  258. mapLayer = self.tree.GetPyData(item)[0]['maplayer']
  259. if type == 'raster':
  260. id = self.LoadRaster(mapLayer)
  261. elif type == 'vector':
  262. id = self.LoadVector(mapLayer)
  263. if type == 'raster' or type == 'vector':
  264. self.SetLayerData(item, id)
  265. self.UpdateLayerProperties(item)
  266. stop = time.time()
  267. Debug.msg(3, "GLWindow.LoadDataLayers(): time=%f" % (stop-start))
  268. # print stop - start
  269. def SetLayerData(self, item, id):
  270. """Set map object properties"""
  271. type = self.tree.GetPyData(item)[0]['maplayer'].type
  272. data = self.tree.GetPyData(item)[0]['nviz']
  273. # init layer data properties
  274. if data is None:
  275. self.tree.GetPyData(item)[0]['nviz'] = {}
  276. data = self.tree.GetPyData(item)[0]['nviz']
  277. if type == 'raster':
  278. data['surface'] = {}
  279. for sec in ('attribute', 'draw', 'mask', 'position'):
  280. data['surface'][sec] = {}
  281. self.SetSurfaceDefaultProp(data['surface'])
  282. elif type == 'vector':
  283. data['vector'] = {}
  284. for sec in ('lines', ):
  285. data['vector'][sec] = {}
  286. self.SetVectorDefaultProp(data['vector'])
  287. # set updates
  288. else:
  289. for sec in data.keys():
  290. for sec1 in data[sec].keys():
  291. for sec2 in data[sec][sec1].keys():
  292. self.update.append('%s:%s:%s' % (sec, sec1, sec2))
  293. # associate with map object id
  294. if not data.has_key('object'):
  295. data['object'] = { 'id' : id,
  296. 'init' : False }
  297. if not data.has_key('view'):
  298. data['view'] = None
  299. def LoadRaster(self, layer):
  300. """Load raster map -> surface"""
  301. if layer.type != 'raster':
  302. return
  303. id = self.nvizClass.LoadSurface(str(layer.name), None, None)
  304. if id < 0:
  305. raise gcmd.NvizError(parent=self.parent,
  306. message=_("Unable to load raster map <%s>" % layer.name))
  307. self.layers['raster']['name'].append(layer.name)
  308. self.layers['raster']['id'].append(id)
  309. # update tools window
  310. if hasattr(self.parent, "nvizToolWin"):
  311. toolWin = self.parent.nvizToolWin
  312. win = toolWin.FindWindowById( \
  313. toolWin.win['vector']['lines']['surface'])
  314. win.SetItems(self.layers['raster']['name'])
  315. return id
  316. def UnloadRaster(self, id):
  317. """Unload raster map"""
  318. idx = self.layers['raster']['id'].index(id)
  319. layerName = self.layers['raster']['name']
  320. if self.nvizClass.UnloadSurface(id) == 0:
  321. raise gcmd.NvizError(parent=self.parent,
  322. message=_("Unable to unload raster map <%s>" % layerName))
  323. del self.layers['raster']['name'][idx]
  324. del self.layers['raster']['id'][idx]
  325. # update tools window
  326. if hasattr(self.parent, "nvizToolWin"):
  327. toolWin = self.parent.nvizToolWin
  328. win = toolWin.FindWindowById( \
  329. toolWin.win['vector']['lines']['surface'])
  330. win.SetItems(self.layers['raster']['name'])
  331. # remove surface page
  332. if toolWin.notebook.GetSelection() == toolWin.page['surface']['id']:
  333. toolWin.notebook.RemovePage(toolWin.page['surface']['id'])
  334. toolWin.page['surface']['id'] = -1
  335. toolWin.page['settings']['id'] = 1
  336. def GetSurfaceMode(self, mode, style, shade, string=False):
  337. """Determine surface draw mode"""
  338. value = 0
  339. desc = {}
  340. if string:
  341. if mode == 'coarse':
  342. value |= wxnviz.DM_WIRE
  343. elif mode == 'fine':
  344. value |= wxnviz.DM_POLY
  345. else: # both
  346. value |= wxnviz.DM_WIRE_POLY
  347. if style == 'wire':
  348. value |= wxnviz.DM_GRID_WIRE
  349. else: # surface
  350. value |= wxnviz.DM_GRID_SURF
  351. if shade == 'flat':
  352. value |= wxnviz.DM_FLAT
  353. else: # surface
  354. value |= wxnviz.DM_GOURAUD
  355. return value
  356. # -> string is False
  357. if mode == 0: # coarse
  358. value |= wxnviz.DM_WIRE
  359. desc['mode'] = 'coarse'
  360. elif mode == 1: # fine
  361. value |= wxnviz.DM_POLY
  362. desc['mode'] = 'fine'
  363. else: # both
  364. value |= wxnviz.DM_WIRE_POLY
  365. desc['mode'] = 'both'
  366. if style == 0: # wire
  367. value |= wxnviz.DM_GRID_WIRE
  368. desc['style'] = 'wire'
  369. else: # surface
  370. value |= wxnviz.DM_GRID_SURF
  371. desc['style'] = 'surface'
  372. if shade == 0:
  373. value |= wxnviz.DM_FLAT
  374. desc['shading'] = 'flat'
  375. else: # surface
  376. value |= wxnviz.DM_GOURAUD
  377. desc['shading'] = 'gouraud'
  378. return (value, desc)
  379. def SetSurfaceDefaultProp(self, data):
  380. """Set default surface properties"""
  381. #
  382. # attributes
  383. #
  384. data['attribute']['shine'] = {}
  385. data['attribute']['shine']['map'] = \
  386. UserSettings.Get(group='nviz', key='surface', subkey=['shine', 'map'])
  387. data['attribute']['shine']['value'] = \
  388. UserSettings.Get(group='nviz', key='surface', subkey=['shine', 'value'])
  389. self.update.append('surface:attribute:shine')
  390. #
  391. # draw
  392. #
  393. for control, value in UserSettings.Get(group='nviz', key='surface', subkey='draw').iteritems():
  394. if control[:3] == 'res':
  395. if 'surface:draw:%s' % 'resolution' not in self.update:
  396. self.update.append('surface:draw:%s' % 'resolution')
  397. data['draw']['resolution'] = { 'all' : False,
  398. control[4:] : value }
  399. else:
  400. data['draw']['resolution'][control[4:]] = value
  401. continue
  402. elif control not in ('style', 'shading'):
  403. self.update.append('surface:draw:%s' % control)
  404. if control == 'wire-color':
  405. value = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
  406. elif control in ('mode', 'style', 'shading'):
  407. if not data['draw'].has_key('mode'):
  408. data['draw']['mode'] = {}
  409. continue
  410. data['draw'][control] = { 'value' : value,
  411. 'all' : False }
  412. value, desc = self.GetSurfaceMode(UserSettings.Get(group='nviz', key='surface', subkey=['draw', 'mode']),
  413. UserSettings.Get(group='nviz', key='surface', subkey=['draw', 'style']),
  414. UserSettings.Get(group='nviz', key='surface', subkey=['draw', 'shading']))
  415. data['draw']['mode'] = { 'value' : value,
  416. 'desc' : desc,
  417. 'all' : False }
  418. def LoadVector(self, layer, points=False):
  419. """Load vector map overlay
  420. @param layer map layer instance
  421. @param points if True load points instead of lines
  422. """
  423. if layer.type != 'vector':
  424. return
  425. id = self.nvizClass.LoadVector(str(layer.name), points)
  426. print id, points
  427. if id < 0:
  428. raise gcmd.NvizError(parent=self.parent,
  429. message=_("Unable to load vector map <%s>" % layer.name))
  430. self.layers['vector']['name'].append(layer.name)
  431. self.layers['vector']['id'].append(id)
  432. return id
  433. def UnloadVector(self, id, points=False):
  434. """Unload vector map overlay
  435. @param id data layer id
  436. @param points if True unload points layer instead of lines layer
  437. """
  438. ret = self.nvizClass.UnloadVector(id, points)
  439. idx = self.layers['vector']['id'].index(id)
  440. layerName = self.layers['vector']['name'][idx]
  441. if ret == 0:
  442. raise gcmd.NvizError(parent=self.parent,
  443. message=_("Unable to unload vector map <%s>" % layerName))
  444. del self.layers['vector']['name'][idx]
  445. del self.layers['vector']['id'][idx]
  446. def SetVectorDefaultProp(self, data):
  447. """Set default vector properties"""
  448. if UserSettings.Get(group='nviz', key='vector',
  449. subkey=['lines', 'show']):
  450. self.SetVectorLinesDefaultProp(data)
  451. if UserSettings.Get(group='nviz', key='vector',
  452. subkey=['points', 'show']):
  453. self.SetVectorPointsDefaultProp(data)
  454. def SetVectorLinesDefaultProp(self, data):
  455. """Set default vector properties -- lines"""
  456. # width
  457. data['lines']['width'] = \
  458. UserSettings.Get(group='nviz', key='vector',
  459. subkey=['lines', 'width'])
  460. self.update.append('vector:lines:width')
  461. # color
  462. value = UserSettings.Get(group='nviz', key='vector',
  463. subkey=['lines', 'color'])
  464. color = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
  465. data['lines']['color'] = color
  466. self.update.append('vector:lines:color')
  467. # mode
  468. if UserSettings.Get(group='nviz', key='vector',
  469. subkey=['lines', 'flat']):
  470. type = 'flat'
  471. map = None
  472. else:
  473. if len(self.layers['raster']['name']) > 1:
  474. type = 'surface'
  475. map = self.layers['raster']['name']
  476. else:
  477. type = 'flat'
  478. map = None
  479. data['lines']['mode'] = {}
  480. data['lines']['mode']['type'] = type
  481. if map:
  482. data['lines']['mode']['surface'] = map
  483. self.update.append('vector:lines:mode')
  484. # height
  485. data['lines']['height'] = UserSettings.Get(group='nviz', key='vector',
  486. subkey=['lines', 'height'])
  487. self.update.append('vector:lines:height')
  488. def SetVectorPointsDefaultProp(self, data):
  489. """Set default vector properties -- points"""
  490. # size
  491. # symbol
  492. # color
  493. pass
  494. def Reset(self):
  495. """Reset (unload data)"""
  496. self.nvizClass.Reset()
  497. self.init = False
  498. def OnZoomToMap(self, event):
  499. """
  500. Set display extents to match selected raster
  501. or vector map or volume.
  502. @todo vector, volume
  503. """
  504. layer = self.GetSelectedLayer()
  505. if layer is None:
  506. return
  507. Debug.msg (3, "GLWindow.OnZoomToMap(): layer=%s, type=%s" % \
  508. (layer.name, layer.type))
  509. self.nvizClass.SetViewportDefault()
  510. def ResetView(self):
  511. """Reset to default view"""
  512. self.view['z-exag']['value'], \
  513. self.iview['height']['value'] = self.nvizClass.SetViewDefault()
  514. self.view['pos']['x'] = UserSettings.Get(group='nviz', key='view',
  515. subkey=('pos', 'x'))
  516. self.view['pos']['y'] = UserSettings.Get(group='nviz', key='view',
  517. subkey=('pos', 'x'))
  518. self.view['persp']['value'] = UserSettings.Get(group='nviz', key='view',
  519. subkey=('persp', 'value'))
  520. self.view['twist']['value'] = UserSettings.Get(group='nviz', key='view',
  521. subkey=('twist', 'value'))
  522. self.update.append('view')
  523. def UpdateLayerProperties(self, layer=None):
  524. """Update data layer properties
  525. @param layer layer item or None (for selected item)
  526. """
  527. if not layer:
  528. mapLayer = self.GetSelectedLayer()
  529. data = self.GetSelectedLayer(nviz=True)
  530. else:
  531. mapLayer = self.tree.GetPyData(layer)[0]['maplayer']
  532. data = self.tree.GetPyData(layer)[0]['nviz']
  533. id = data['object']['id']
  534. if mapLayer.type == 'raster':
  535. self.UpdateRasterProperties(id, data['surface'])
  536. elif mapLayer.type == 'vector':
  537. self.UpdateVectorProperties(id, data['vector'])
  538. # -> initialized
  539. data['object']['init'] = True
  540. def UpdateRasterProperties(self, id, data):
  541. """Apply changes for surfaces"""
  542. # surface attributes
  543. for attrb in ('topo', 'color', 'mask',
  544. 'transp', 'shine', 'emit'):
  545. if 'surface:attribute:%s' % attrb in self.update:
  546. map = data['attribute'][attrb]['map']
  547. value = data['attribute'][attrb]['value']
  548. if map is None: # unset
  549. # only optional attributes
  550. if attrb == 'mask':
  551. # TODO: invert mask
  552. # TODO: broken in NVIZ
  553. self.nvizClass.UnsetSurfaceMask(id)
  554. elif attrb == 'transp':
  555. self.nvizClass.UnsetSurfaceTransp(id)
  556. elif attrb == 'emit':
  557. self.nvizClass.UnsetSurfaceEmit(id)
  558. else:
  559. if type(value) == type('') and \
  560. len(value) <= 0: # ignore empty values (TODO: warning)
  561. continue
  562. if attrb == 'topo':
  563. self.nvizClass.SetSurfaceTopo(id, map, str(value))
  564. elif attrb == 'color':
  565. self.nvizClass.SetSurfaceColor(id, map, str(value))
  566. elif attrb == 'mask':
  567. # TODO: invert mask
  568. # TODO: broken in NVIZ
  569. self.nvizClass.SetSurfaceMask(id, False, str(value))
  570. elif attrb == 'transp':
  571. self.nvizClass.SetSurfaceTransp(id, map, str(value))
  572. elif attrb == 'shine':
  573. self.nvizClass.SetSurfaceShine(id, map, str(value))
  574. elif attrb == 'emit':
  575. self.nvizClass.SetSurfaceEmit(id, map, str(value))
  576. self.update.remove('surface:attribute:%s' % attrb)
  577. # draw res
  578. if 'surface:draw:resolution' in self.update:
  579. coarse = data['draw']['resolution']['coarse']
  580. fine = data['draw']['resolution']['fine']
  581. if data['draw']['resolution']['all']:
  582. self.nvizClass.SetSurfaceRes(-1, fine, coarse)
  583. else:
  584. self.nvizClass.SetSurfaceRes(id, fine, coarse)
  585. self.update.remove('surface:draw:resolution')
  586. # draw style
  587. if 'surface:draw:mode' in self.update:
  588. if data['draw']['mode']['value'] < 0: # need to calculate
  589. data['draw']['mode']['value'] = \
  590. self.GetSurfaceMode(mode=data['draw']['mode']['desc']['mode'],
  591. style=data['draw']['mode']['desc']['style'],
  592. shade=data['draw']['mode']['desc']['shading'],
  593. string=True)
  594. style = data['draw']['mode']['value']
  595. if data['draw']['mode']['all']:
  596. self.nvizClass.SetSurfaceStyle(-1, style)
  597. else:
  598. self.nvizClass.SetSurfaceStyle(id, style)
  599. self.update.remove('surface:draw:mode')
  600. # wire color
  601. if 'surface:draw:wire-color' in self.update:
  602. color = data['draw']['wire-color']['value']
  603. if data['draw']['wire-color']['all']:
  604. self.nvizClass.SetWireColor(-1, str(color))
  605. else:
  606. self.nvizClass.SetWireColor(id, str(color))
  607. self.update.remove('surface:draw:wire-color')
  608. # position
  609. if 'surface:position' in self.update:
  610. x = data['position']['x']
  611. y = data['position']['y']
  612. z = data['position']['z']
  613. self.nvizClass.SetSurfacePosition(id, x, y, z)
  614. self.update.remove('surface:position')
  615. def UpdateVectorProperties(self, id, data):
  616. """Apply changes for vector"""
  617. #
  618. # lines
  619. #
  620. # mode
  621. if 'vector:lines:color' in self.update or \
  622. 'vector:lines:width' in self.update or \
  623. 'vector:lines:mode' in self.update:
  624. width = data['lines']['width']
  625. color = data['lines']['color']
  626. if data['lines']['mode']['type'] == 'flat':
  627. flat = True
  628. if data['lines'].has_key('surface'):
  629. data['lines'].pop('surface')
  630. else:
  631. flat = False
  632. if not 'vector:lines:surface' in self.update:
  633. self.update.append('vector:lines:surface')
  634. self.nvizClass.SetVectorLineMode(id, color,
  635. width, flat)
  636. if 'vector:lines:color' in self.update:
  637. self.update.remove('vector:lines:color')
  638. if 'vector:lines:width' in self.update:
  639. self.update.remove('vector:lines:width')
  640. if 'vector:lines:mode' in self.update:
  641. self.update.remove('vector:lines:mode')
  642. # height
  643. if 'vector:lines:height' in self.update:
  644. self.nvizClass.SetVectorHeight(id,
  645. data['lines']['height'])
  646. self.update.remove('vector:lines:height')
  647. # surface
  648. if 'vector:lines:surface' in self.update:
  649. idx = self.layers['raster']['name'].index(data['lines']['mode']['surface'])
  650. if idx > -1:
  651. self.nvizClass.SetVectorSurface(id,
  652. self.layers['raster']['id'][idx])
  653. self.update.remove('vector:lines:surface')
  654. class NvizToolWindow(wx.Frame):
  655. """Experimental window for Nviz tools
  656. @todo integrate with Map display
  657. """
  658. def __init__(self, parent=None, id=wx.ID_ANY, title=_("Nviz tools"),
  659. pos=wx.DefaultPosition, size=wx.DefaultSize,
  660. style=wx.DEFAULT_FRAME_STYLE, mapWindow=None):
  661. self.parent = parent # MapFrame
  662. self.lmgr = self.parent.gismanager # GMFrame
  663. self.mapWindow = mapWindow
  664. wx.Frame.__init__(self, parent, id, title, pos, size, style)
  665. #
  666. # icon
  667. #
  668. self.SetIcon(wx.Icon(os.path.join(globalvar.ETCDIR, 'grass_nviz.ico'), wx.BITMAP_TYPE_ICO))
  669. #
  670. # dialog body
  671. #
  672. mainSizer = wx.BoxSizer(wx.VERTICAL)
  673. self.win = {} # window ids
  674. #
  675. # notebook
  676. #
  677. self.notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
  678. self.page = {}
  679. # view page
  680. self.__createViewPage()
  681. self.page['view'] = { 'id' : 0 }
  682. # surface page
  683. size = self.__createSurfacePage()
  684. size = (size[0] + 25, size[0] + 20)
  685. # vector page
  686. self.__createVectorPage()
  687. # settings page
  688. self.__createSettingsPage()
  689. self.page['settings'] = { 'id' : 1 }
  690. self.UpdatePage('settings')
  691. self.pageChanging = False
  692. mainSizer.Add(item=self.notebook, proportion=1,
  693. flag=wx.EXPAND | wx.ALL, border=5)
  694. #
  695. # bindings
  696. #
  697. self.Bind(wx.EVT_CLOSE, self.OnClose)
  698. #
  699. # layout
  700. #
  701. self.SetSizer(mainSizer)
  702. mainSizer.Fit(self)
  703. self.SetSize(size)
  704. def __createViewPage(self):
  705. """Create view settings page"""
  706. panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
  707. self.notebook.AddPage(page=panel,
  708. text=" %s " % _("View"))
  709. pageSizer = wx.BoxSizer(wx.VERTICAL)
  710. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  711. self.win['view'] = {}
  712. # position
  713. posSizer = wx.GridBagSizer(vgap=3, hgap=3)
  714. posSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("W")),
  715. pos=(1, 0), flag=wx.ALIGN_CENTER)
  716. posSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("N")),
  717. pos=(0, 1), flag=wx.ALIGN_CENTER | wx.ALIGN_BOTTOM)
  718. viewPos = ViewPositionWindow(panel, id=wx.ID_ANY, size=(175, 175),
  719. mapwindow=self.mapWindow)
  720. self.win['view']['pos'] = viewPos.GetId()
  721. posSizer.Add(item=viewPos,
  722. pos=(1, 1), flag=wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL)
  723. posSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("S")),
  724. pos=(2, 1), flag=wx.ALIGN_CENTER | wx.ALIGN_TOP)
  725. posSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("E")),
  726. pos=(1, 2), flag=wx.ALIGN_CENTER)
  727. gridSizer.Add(item=posSizer, pos=(0, 0))
  728. # perspective
  729. range = UserSettings.Get(group='nviz', key='view', subkey='persp', internal=True)
  730. self.CreateControl(panel, dict=self.win['view'], name='persp',
  731. range=(range['min'], range['max']),
  732. bind=(self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
  733. gridSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("Perspective:")),
  734. pos=(1, 0), flag=wx.ALIGN_CENTER)
  735. gridSizer.Add(item=self.FindWindowById(self.win['view']['persp']['slider']), pos=(2, 0))
  736. gridSizer.Add(item=self.FindWindowById(self.win['view']['persp']['spin']), pos=(3, 0),
  737. flag=wx.ALIGN_CENTER)
  738. # twist
  739. range = UserSettings.Get(group='nviz', key='view', subkey='twist', internal=True)
  740. self.CreateControl(panel, dict=self.win['view'], name='twist',
  741. range=(range['min'], range['max']),
  742. bind=(self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
  743. gridSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("Twist:")),
  744. pos=(1, 1), flag=wx.ALIGN_CENTER)
  745. gridSizer.Add(item=self.FindWindowById(self.win['view']['twist']['slider']), pos=(2, 1))
  746. gridSizer.Add(item=self.FindWindowById(self.win['view']['twist']['spin']), pos=(3, 1),
  747. flag=wx.ALIGN_CENTER)
  748. # height + z-exag
  749. self.CreateControl(panel, dict=self.win['view'], name='height', sliderHor=False,
  750. range=(self.mapWindow.view['height']['min'], self.mapWindow.view['height']['max']),
  751. bind=(self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
  752. self.CreateControl(panel, dict=self.win['view'], name='z-exag', sliderHor=False,
  753. range=(0, 1),
  754. bind=(self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
  755. heightSizer = wx.GridBagSizer(vgap=3, hgap=3)
  756. heightSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("Height:")),
  757. pos=(0, 0), flag=wx.ALIGN_LEFT, span=(1, 2))
  758. heightSizer.Add(item=self.FindWindowById(self.win['view']['height']['slider']),
  759. flag=wx.ALIGN_RIGHT, pos=(1, 0))
  760. heightSizer.Add(item=self.FindWindowById(self.win['view']['height']['spin']),
  761. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.TOP |
  762. wx.BOTTOM | wx.RIGHT, pos=(1, 1))
  763. heightSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("Z-exag:")),
  764. pos=(0, 2), flag=wx.ALIGN_LEFT, span=(1, 2))
  765. heightSizer.Add(item=self.FindWindowById(self.win['view']['z-exag']['slider']),
  766. flag=wx.ALIGN_RIGHT, pos=(1, 2))
  767. heightSizer.Add(item=self.FindWindowById(self.win['view']['z-exag']['spin']),
  768. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.TOP |
  769. wx.BOTTOM | wx.RIGHT, pos=(1, 3))
  770. gridSizer.Add(item=heightSizer, pos=(0, 1), flag=wx.ALIGN_RIGHT)
  771. # view setup + reset
  772. viewSizer = wx.BoxSizer(wx.HORIZONTAL)
  773. viewSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY,
  774. label=_("Look at:")),
  775. flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5)
  776. viewType = wx.Choice (parent=panel, id=wx.ID_ANY, size=(125, -1),
  777. choices = [_("top"),
  778. _("north"),
  779. _("south"),
  780. _("east"),
  781. _("west"),
  782. _("north-west"),
  783. _("north-east"),
  784. _("south-east"),
  785. _("south-west")])
  786. viewType.SetSelection(0)
  787. viewType.Bind(wx.EVT_CHOICE, self.OnLookAt)
  788. # self.win['lookAt'] = viewType.GetId()
  789. viewSizer.Add(item=viewType, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL,
  790. border=5)
  791. reset = wx.Button(panel, id=wx.ID_ANY, label=_("Reset"))
  792. reset.SetToolTipString(_("Reset to default view"))
  793. # self.win['reset'] = reset.GetId()
  794. reset.Bind(wx.EVT_BUTTON, self.OnResetView)
  795. viewSizer.Add(item=reset, proportion=1,
  796. flag=wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT,
  797. border=5)
  798. gridSizer.AddGrowableCol(3)
  799. gridSizer.Add(item=viewSizer, pos=(4, 0), span=(1, 2),
  800. flag=wx.EXPAND)
  801. # body
  802. pageSizer.Add(item=gridSizer, proportion=1,
  803. flag=wx.EXPAND | wx.ALL,
  804. border=5)
  805. panel.SetSizer(pageSizer)
  806. return panel.GetBestSize()
  807. def __createSurfacePage(self):
  808. """Create view settings page"""
  809. panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
  810. self.page['surface'] = {}
  811. self.page['surface']['id'] = -1
  812. self.page['surface']['panel'] = panel.GetId()
  813. # panel = scrolled.ScrolledPanel(parent=self.notebook, id=wx.ID_ANY)
  814. # panel.SetupScrolling(scroll_x=True, scroll_y=True)
  815. pageSizer = wx.BoxSizer(wx.VERTICAL)
  816. self.win['surface'] = {}
  817. #
  818. # surface attributes
  819. #
  820. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  821. label=" %s " % (_("Surface attributes")))
  822. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  823. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  824. # labels
  825. # col = 0
  826. # for type in (_("Attribute"),
  827. # _("Use"),
  828. # _("Map"),
  829. # _("Constant")):
  830. # gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  831. # label=type),
  832. # pos=(0, col))
  833. # col += 1
  834. # type
  835. self.win['surface']['attr'] = {}
  836. row = 0
  837. for code, attrb in (('topo', _("Topography")),
  838. ('color', _("Color")),
  839. ('mask', _("Mask")),
  840. ('transp', _("Transparency")),
  841. ('shine', _("Shininess")),
  842. ('emit', _("Emission"))):
  843. self.win['surface'][code] = {}
  844. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  845. label=attrb + ':'),
  846. pos=(row, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  847. use = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1),
  848. choices = [_("map")])
  849. if code not in ('topo', 'color', 'shine'):
  850. use.Insert(item=_("unset"), pos=0)
  851. self.win['surface'][code]['required'] = False
  852. else:
  853. self.win['surface'][code]['required'] = True
  854. if code != 'mask':
  855. use.Append(item=_('constant'))
  856. self.win['surface'][code]['use'] = use.GetId()
  857. use.Bind(wx.EVT_CHOICE, self.OnSurfaceUse)
  858. gridSizer.Add(item=use, flag=wx.ALIGN_CENTER_VERTICAL,
  859. pos=(row, 1))
  860. map = gselect.Select(parent=panel, id=wx.ID_ANY,
  861. # size=globalvar.DIALOG_GSELECT_SIZE,
  862. size=(200, -1),
  863. type="raster")
  864. self.win['surface'][code]['map'] = map.GetId() - 1 # FIXME
  865. map.Bind(wx.EVT_TEXT, self.OnSurfaceMap)
  866. # changing map topography not allowed
  867. if code == 'topo':
  868. map.Enable(False)
  869. gridSizer.Add(item=map, flag=wx.ALIGN_CENTER_VERTICAL,
  870. pos=(row, 2))
  871. if code == 'color':
  872. value = csel.ColourSelect(panel, id=wx.ID_ANY,
  873. colour=UserSettings.Get(group='nviz', key='surface',
  874. subkey=['color', 'value']))
  875. value.Bind(csel.EVT_COLOURSELECT, self.OnSurfaceMap)
  876. elif code == 'mask':
  877. value = None
  878. else:
  879. value = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  880. initial=0)
  881. if code == 'topo':
  882. value.SetRange(minVal=-1e9, maxVal=1e9)
  883. elif code in ('shine', 'transp', 'emit'):
  884. value.SetRange(minVal=0, maxVal=255)
  885. else:
  886. value.SetRange(minVal=0, maxVal=100)
  887. value.Bind(wx.EVT_TEXT, self.OnSurfaceMap)
  888. if value:
  889. self.win['surface'][code]['const'] = value.GetId()
  890. value.Enable(False)
  891. gridSizer.Add(item=value, flag=wx.ALIGN_CENTER_VERTICAL,
  892. pos=(row, 3))
  893. else:
  894. self.win['surface'][code]['const'] = None
  895. self.SetSurfaceUseMap(code) # -> enable map / disable constant
  896. row += 1
  897. boxSizer.Add(item=gridSizer, proportion=1,
  898. flag=wx.ALL | wx.EXPAND, border=3)
  899. pageSizer.Add(item=boxSizer, proportion=0,
  900. flag=wx.EXPAND | wx.ALL,
  901. border=5)
  902. #
  903. # draw
  904. #
  905. self.win['surface']['draw'] = {}
  906. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  907. label=" %s " % (_("Draw")))
  908. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  909. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  910. gridSizer.AddGrowableCol(4)
  911. # mode
  912. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  913. label=_("Mode:")),
  914. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  915. mode = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1),
  916. choices = [_("coarse"),
  917. _("fine"),
  918. _("both")])
  919. mode.SetSelection(0)
  920. mode.SetName("selection")
  921. mode.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
  922. self.win['surface']['draw']['mode'] = mode.GetId()
  923. gridSizer.Add(item=mode, flag=wx.ALIGN_CENTER_VERTICAL,
  924. pos=(0, 1))
  925. # resolution (mode)
  926. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  927. label=_("Resolution:")),
  928. pos=(0, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  929. resSizer = wx.BoxSizer(wx.HORIZONTAL)
  930. resSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  931. label=_("coarse:")),
  932. flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3)
  933. resC = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  934. initial=1,
  935. min=1,
  936. max=100)
  937. resC.SetName("value")
  938. self.win['surface']['draw']['res-coarse'] = resC.GetId()
  939. resC.Bind(wx.EVT_SPINCTRL, self.OnSurfaceResolution)
  940. resSizer.Add(item=resC, flag=wx.ALL, border=3)
  941. resSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  942. label=_("fine:")),
  943. flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3)
  944. resF = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  945. initial=1,
  946. min=1,
  947. max=100)
  948. resF.SetName("value")
  949. self.win['surface']['draw']['res-fine'] = resF.GetId()
  950. resF.Bind(wx.EVT_SPINCTRL, self.OnSurfaceResolution)
  951. resSizer.Add(item=resF, flag=wx.ALL, border=3)
  952. gridSizer.Add(item=resSizer, pos=(0, 3), span=(1, 2))
  953. # style
  954. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  955. label=_("Coarse style:")),
  956. pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  957. style = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1),
  958. choices = [_("wire"),
  959. _("surface")])
  960. style.SetName("selection")
  961. self.win['surface']['draw']['style'] = style.GetId()
  962. style.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
  963. gridSizer.Add(item=style, flag=wx.ALIGN_CENTER_VERTICAL,
  964. pos=(1, 1))
  965. # shading
  966. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  967. label=_("Shading:")),
  968. pos=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  969. shade = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1),
  970. choices = [_("flat"),
  971. _("gouraud")])
  972. shade.SetName("selection")
  973. self.win['surface']['draw']['shading'] = shade.GetId()
  974. shade.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
  975. gridSizer.Add(item=shade, flag=wx.ALIGN_CENTER_VERTICAL,
  976. pos=(1, 3))
  977. # color
  978. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  979. label=_("Wire color:")),
  980. pos=(2, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  981. color = csel.ColourSelect(panel, id=wx.ID_ANY)
  982. color.SetName("colour")
  983. color.Bind(csel.EVT_COLOURSELECT, self.OnSurfaceWireColor)
  984. self.win['surface']['draw']['wire-color'] = color.GetId()
  985. gridSizer.Add(item=color, flag=wx.ALIGN_CENTER_VERTICAL,
  986. pos=(2, 1))
  987. boxSizer.Add(item=gridSizer, proportion=1,
  988. flag=wx.ALL | wx.EXPAND, border=3)
  989. pageSizer.Add(item=boxSizer, proportion=0,
  990. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  991. border=5)
  992. all = wx.Button(panel, id=wx.ID_ANY, label=_("All"))
  993. all.SetToolTipString(_("Use for all loaded surfaces"))
  994. # self.win['reset'] = reset.GetId()
  995. all.Bind(wx.EVT_BUTTON, self.OnSurfaceModeAll)
  996. gridSizer.Add(item=all, flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  997. pos=(2, 4))
  998. #
  999. # mask
  1000. #
  1001. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  1002. label=" %s " % (_("Mask")))
  1003. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1004. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  1005. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1006. label=_("Mask zeros:")),
  1007. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1008. elev = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1009. label=_("by elevation"))
  1010. elev.Enable(False) # TODO: not implemented yet
  1011. gridSizer.Add(item=elev, pos=(0, 1))
  1012. color = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1013. label=_("by color"))
  1014. color.Enable(False) # TODO: not implemented yet
  1015. gridSizer.Add(item=color, pos=(0, 2))
  1016. boxSizer.Add(item=gridSizer, proportion=1,
  1017. flag=wx.ALL | wx.EXPAND, border=3)
  1018. pageSizer.Add(item=boxSizer, proportion=0,
  1019. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1020. border=5)
  1021. #
  1022. # position
  1023. #
  1024. self.win['surface']['position'] = {}
  1025. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  1026. label=" %s " % (_("Position")))
  1027. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1028. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  1029. # position
  1030. axis = wx.Choice (parent=panel, id=wx.ID_ANY, size=(75, -1),
  1031. choices = ["X",
  1032. "Y",
  1033. "Z"])
  1034. axis.SetSelection(0)
  1035. self.win['surface']['position']['axis'] = axis.GetId()
  1036. axis.Bind(wx.EVT_CHOICE, self.OnSurfaceAxis)
  1037. gridSizer.Add(item=axis, flag=wx.ALIGN_CENTER_VERTICAL,
  1038. pos=(0, 0))
  1039. value = wx.Slider(parent=panel, id=wx.ID_ANY,
  1040. value=0,
  1041. minValue=-1e4,
  1042. maxValue=1e4,
  1043. style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | \
  1044. wx.SL_TOP | wx.SL_LABELS,
  1045. size=(350, -1))
  1046. self.win['surface']['position']['pos'] = value.GetId()
  1047. value.Bind(wx.EVT_SCROLL, self.OnSurfacePosition)
  1048. gridSizer.Add(item=value, flag=wx.ALIGN_CENTER_VERTICAL,
  1049. pos=(0, 1))
  1050. boxSizer.Add(item=gridSizer, proportion=1,
  1051. flag=wx.ALL | wx.EXPAND, border=3)
  1052. pageSizer.Add(item=boxSizer, proportion=0,
  1053. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1054. border=5)
  1055. panel.SetSizer(pageSizer)
  1056. return panel.GetBestSize()
  1057. def __createVectorPage(self):
  1058. """Create view settings page"""
  1059. panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
  1060. self.page['vector'] = {}
  1061. self.page['vector']['id'] = -1
  1062. self.page['vector']['panel'] = panel.GetId()
  1063. pageSizer = wx.BoxSizer(wx.VERTICAL)
  1064. self.win['vector'] = {}
  1065. #
  1066. # vector lines
  1067. #
  1068. self.win['vector']['lines'] = {}
  1069. showLines = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1070. label=_("Show vector lines"))
  1071. self.win['vector']['lines']['show'] = showLines.GetId()
  1072. showLines.SetValue(UserSettings.Get(group='nviz', key='vector',
  1073. subkey=['lines', 'show']))
  1074. self.UpdateVectorShow(showLines.GetId(),
  1075. showLines.IsChecked())
  1076. showLines.Bind(wx.EVT_CHECKBOX, self.OnVectorShow)
  1077. pageSizer.Add(item=showLines, proportion=0,
  1078. flag=wx.ALL | wx.EXPAND, border=5)
  1079. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  1080. label=" %s " % (_("Vector lines")))
  1081. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1082. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  1083. # width
  1084. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1085. label=_("Width:")),
  1086. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1087. width = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1088. initial=1,
  1089. min=1,
  1090. max=100)
  1091. self.win['vector']['lines']['width'] = width.GetId()
  1092. width.Bind(wx.EVT_SPINCTRL, self.OnVectorLines)
  1093. gridSizer.Add(item=width, pos=(0, 1),
  1094. flag=wx.ALIGN_CENTER_VERTICAL)
  1095. gridSizer.AddGrowableCol(2)
  1096. # color
  1097. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1098. label=_("Color:")),
  1099. pos=(0, 3), flag=wx.ALIGN_CENTER_VERTICAL)
  1100. color = csel.ColourSelect(panel, id=wx.ID_ANY,
  1101. colour=UserSettings.Get(group='nviz', key='vector',
  1102. subkey=['lines', 'color']))
  1103. self.win['vector']['lines']['color'] = color.GetId()
  1104. color.Bind(csel.EVT_COLOURSELECT, self.OnVectorLines)
  1105. gridSizer.Add(item=color, pos=(0, 4))
  1106. gridSizer.AddGrowableCol(5)
  1107. # display
  1108. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1109. label=_("Display:")),
  1110. pos=(0, 6), flag=wx.ALIGN_CENTER_VERTICAL)
  1111. display = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1),
  1112. choices = [_("on surface"),
  1113. _("flat")])
  1114. self.win['vector']['lines']['flat'] = display.GetId()
  1115. display.Bind(wx.EVT_CHOICE, self.OnVectorDisplay)
  1116. gridSizer.Add(item=display, flag=wx.ALIGN_CENTER_VERTICAL,
  1117. pos=(0, 7))
  1118. surface = wx.ComboBox(parent=panel, id=wx.ID_ANY, size=(250, -1),
  1119. style=wx.CB_SIMPLE | wx.CB_READONLY,
  1120. choices=[])
  1121. surface.Bind(wx.EVT_COMBOBOX, self.OnVectorSurface)
  1122. self.win['vector']['lines']['surface'] = surface.GetId()
  1123. gridSizer.Add(item=surface,
  1124. pos=(1, 0), span=(1, 8),
  1125. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
  1126. # high
  1127. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1128. label=_("Hight above surface:")),
  1129. pos=(2, 0), flag=wx.ALIGN_CENTER_VERTICAL,
  1130. span=(1, 2))
  1131. self.CreateControl(panel, dict=self.win['vector']['lines'], name='height', size=300,
  1132. range=(0, 1000),
  1133. bind=(self.OnVectorHeight, self.OnVectorHeight, self.OnVectorHeight))
  1134. gridSizer.Add(item=self.FindWindowById(self.win['vector']['lines']['height']['slider']),
  1135. pos=(2, 2), span=(1, 6))
  1136. gridSizer.Add(item=self.FindWindowById(self.win['vector']['lines']['height']['spin']),
  1137. pos=(3, 4),
  1138. flag=wx.ALIGN_CENTER)
  1139. boxSizer.Add(item=gridSizer, proportion=1,
  1140. flag=wx.ALL | wx.EXPAND, border=3)
  1141. pageSizer.Add(item=boxSizer, proportion=0,
  1142. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1143. border=5)
  1144. #
  1145. # vector points
  1146. #
  1147. self.win['vector']['points'] = {}
  1148. showPoints = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1149. label=_("Show vector points"))
  1150. self.win['vector']['points']['show'] = showPoints.GetId()
  1151. showPoints.SetValue(UserSettings.Get(group='nviz', key='vector',
  1152. subkey=['points', 'show']))
  1153. self.UpdateVectorShow(showPoints.GetId(),
  1154. showPoints.IsChecked())
  1155. showPoints.Bind(wx.EVT_CHECKBOX, self.OnVectorShow)
  1156. pageSizer.Add(item=showPoints, proportion=0,
  1157. flag=wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, border=5)
  1158. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  1159. label=" %s " % (_("Vector points")))
  1160. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1161. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  1162. # icon size
  1163. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1164. label=_("Icon size:")),
  1165. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1166. isize = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1167. initial=100,
  1168. min=1,
  1169. max=1e6)
  1170. self.win['vector']['points']['size'] = isize.GetId()
  1171. gridSizer.Add(item=isize, pos=(0, 1),
  1172. flag=wx.ALIGN_CENTER_VERTICAL)
  1173. # icon symbol
  1174. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1175. label=_("symbol:")),
  1176. pos=(0, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  1177. isym = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1),
  1178. choices = [_("coarse"),
  1179. _("fine"),
  1180. _("both")])
  1181. isym.SetName("selection")
  1182. self.win['vector']['points']['symbol'] = isym.GetId()
  1183. gridSizer.Add(item=isym, flag=wx.ALIGN_CENTER_VERTICAL,
  1184. pos=(0, 3))
  1185. # icon symbol
  1186. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1187. label=_("color:")),
  1188. pos=(0, 4), flag=wx.ALIGN_CENTER_VERTICAL)
  1189. icolor = csel.ColourSelect(panel, id=wx.ID_ANY)
  1190. icolor.SetName("color")
  1191. self.win['vector']['points']['color'] = icolor.GetId()
  1192. gridSizer.Add(item=icolor, flag=wx.ALIGN_CENTER_VERTICAL,
  1193. pos=(0, 5))
  1194. boxSizer.Add(item=gridSizer, proportion=1,
  1195. flag=wx.ALL | wx.EXPAND, border=3)
  1196. pageSizer.Add(item=boxSizer, proportion=0,
  1197. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1198. border=5)
  1199. panel.SetSizer(pageSizer)
  1200. return panel.GetBestSize()
  1201. def __createSettingsPage(self):
  1202. """Create settings page"""
  1203. panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
  1204. self.notebook.AddPage(page=panel,
  1205. text=" %s " % _("Settings"))
  1206. pageSizer = wx.BoxSizer(wx.VERTICAL)
  1207. self.win['settings'] = {}
  1208. #
  1209. # general
  1210. #
  1211. self.win['settings']['general'] = {}
  1212. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  1213. label=" %s " % (_("General")))
  1214. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1215. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  1216. # background color
  1217. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1218. label=_("Background color:")),
  1219. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1220. color = csel.ColourSelect(panel, id=wx.ID_ANY,
  1221. colour=UserSettings.Get(group='nviz', key='settings',
  1222. subkey=['general', 'bgcolor']))
  1223. self.win['settings']['general']['bgcolor'] = color.GetId()
  1224. color.Bind(csel.EVT_COLOURSELECT, self.OnBgColor)
  1225. gridSizer.Add(item=color, pos=(0, 1))
  1226. boxSizer.Add(item=gridSizer, proportion=1,
  1227. flag=wx.ALL | wx.EXPAND, border=3)
  1228. pageSizer.Add(item=boxSizer, proportion=0,
  1229. flag=wx.EXPAND | wx.ALL,
  1230. border=5)
  1231. #
  1232. # view
  1233. #
  1234. self.win['settings']['view'] = {}
  1235. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  1236. label=" %s " % (_("View")))
  1237. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1238. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  1239. # perspective
  1240. self.win['settings']['view']['persp'] = {}
  1241. pvals = UserSettings.Get(group='nviz', key='view', subkey='persp')
  1242. ipvals = UserSettings.Get(group='nviz', key='view', subkey='persp', internal=True)
  1243. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1244. label=_("Perspective (value):")),
  1245. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1246. pval = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1247. initial=pvals['value'],
  1248. min=ipvals['min'],
  1249. max=ipvals['max'])
  1250. self.win['settings']['view']['persp']['value'] = pval.GetId()
  1251. gridSizer.Add(item=pval, pos=(0, 1),
  1252. flag=wx.ALIGN_CENTER_VERTICAL)
  1253. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1254. label=_("(step):")),
  1255. pos=(0, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  1256. pstep = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1257. initial=pvals['step'],
  1258. min=ipvals['min'],
  1259. max=ipvals['max']-1)
  1260. self.win['settings']['view']['persp']['step'] = pstep.GetId()
  1261. gridSizer.Add(item=pstep, pos=(0, 3),
  1262. flag=wx.ALIGN_CENTER_VERTICAL)
  1263. # position
  1264. self.win['settings']['view']['pos'] = {}
  1265. posvals = UserSettings.Get(group='nviz', key='view', subkey='pos')
  1266. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1267. label=_("Position") + " (x):"),
  1268. pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1269. px = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1270. initial=posvals['x'] * 100,
  1271. min=0,
  1272. max=100)
  1273. self.win['settings']['view']['pos']['x'] = px.GetId()
  1274. gridSizer.Add(item=px, pos=(1, 1),
  1275. flag=wx.ALIGN_CENTER_VERTICAL)
  1276. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1277. label="(y):"),
  1278. pos=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  1279. py = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1280. initial=posvals['y'] * 100,
  1281. min=0,
  1282. max=100)
  1283. self.win['settings']['view']['pos']['y'] = py.GetId()
  1284. gridSizer.Add(item=py, pos=(1, 3),
  1285. flag=wx.ALIGN_CENTER_VERTICAL)
  1286. # height
  1287. self.win['settings']['view']['height'] = {}
  1288. hvals = UserSettings.Get(group='nviz', key='view', subkey='height')
  1289. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1290. label=_("Height") + " (min):"),
  1291. pos=(2, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1292. hmin = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1293. initial=hvals['min'],
  1294. min=-1e6,
  1295. max=1e6)
  1296. self.win['settings']['view']['height']['min'] = hmin.GetId()
  1297. gridSizer.Add(item=hmin, pos=(2, 1),
  1298. flag=wx.ALIGN_CENTER_VERTICAL)
  1299. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1300. label="(max):"),
  1301. pos=(2, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  1302. hmax = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1303. initial=hvals['max'],
  1304. min=-1e6,
  1305. max=1e6)
  1306. self.win['settings']['view']['height']['max'] = hmax.GetId()
  1307. gridSizer.Add(item=hmax, pos=(2, 3),
  1308. flag=wx.ALIGN_CENTER_VERTICAL)
  1309. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1310. label="(step):"),
  1311. pos=(2, 4), flag=wx.ALIGN_CENTER_VERTICAL)
  1312. hstep = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1313. initial=hvals['step'],
  1314. min=1,
  1315. max=hvals['max']-1)
  1316. self.win['settings']['view']['height']['step'] = hstep.GetId()
  1317. gridSizer.Add(item=hstep, pos=(2, 5),
  1318. flag=wx.ALIGN_CENTER_VERTICAL)
  1319. # twist
  1320. self.win['settings']['view']['twist'] = {}
  1321. tvals = UserSettings.Get(group='nviz', key='view', subkey='twist')
  1322. itvals = UserSettings.Get(group='nviz', key='view', subkey='twist', internal=True)
  1323. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1324. label=_("Twist (value):")),
  1325. pos=(3, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1326. tval = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1327. initial=tvals['value'],
  1328. min=itvals['min'],
  1329. max=itvals['max'])
  1330. self.win['settings']['view']['twist']['value'] = tval.GetId()
  1331. gridSizer.Add(item=tval, pos=(3, 1),
  1332. flag=wx.ALIGN_CENTER_VERTICAL)
  1333. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1334. label=_("(step):")),
  1335. pos=(3, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  1336. tstep = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1337. initial=tvals['step'],
  1338. min=itvals['min'],
  1339. max=itvals['max']-1)
  1340. self.win['settings']['view']['twist']['step'] = tstep.GetId()
  1341. gridSizer.Add(item=tstep, pos=(3, 3),
  1342. flag=wx.ALIGN_CENTER_VERTICAL)
  1343. # z-exag
  1344. self.win['settings']['view']['z-exag'] = {}
  1345. zvals = UserSettings.Get(group='nviz', key='view', subkey='z-exag')
  1346. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1347. label=_("Z-exag (value):")),
  1348. pos=(4, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1349. zval = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1350. initial=zvals['value'],
  1351. min=-1e6,
  1352. max=1e6)
  1353. self.win['settings']['view']['z-exag']['value'] = zval.GetId()
  1354. gridSizer.Add(item=zval, pos=(4, 1),
  1355. flag=wx.ALIGN_CENTER_VERTICAL)
  1356. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1357. label=_("(step):")),
  1358. pos=(4, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  1359. zstep = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1360. initial=zvals['step'],
  1361. min=-1e6,
  1362. max=1e6)
  1363. self.win['settings']['view']['z-exag']['step'] = zstep.GetId()
  1364. gridSizer.Add(item=zstep, pos=(4, 3),
  1365. flag=wx.ALIGN_CENTER_VERTICAL)
  1366. boxSizer.Add(item=gridSizer, proportion=1,
  1367. flag=wx.ALL | wx.EXPAND, border=3)
  1368. pageSizer.Add(item=boxSizer, proportion=0,
  1369. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1370. border=5)
  1371. #
  1372. # surface
  1373. #
  1374. self.win['settings']['surface'] = {}
  1375. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  1376. label=" %s " % (_("Surface")))
  1377. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1378. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  1379. boxSizer.Add(item=gridSizer, proportion=1,
  1380. flag=wx.ALL | wx.EXPAND, border=3)
  1381. pageSizer.Add(item=boxSizer, proportion=0,
  1382. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1383. border=5)
  1384. #
  1385. # vector lines
  1386. #
  1387. self.win['settings']['vector'] = {}
  1388. self.win['settings']['vector']['lines'] = {}
  1389. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  1390. label=" %s " % (_("Vector lines")))
  1391. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1392. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  1393. # show
  1394. row = 0
  1395. showLines = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1396. label=_("Show lines"))
  1397. showLines.SetValue(UserSettings.Get(group='nviz', key='vector',
  1398. subkey=['lines', 'show']))
  1399. gridSizer.Add(item=showLines, pos=(row, 0))
  1400. boxSizer.Add(item=gridSizer, proportion=1,
  1401. flag=wx.ALL | wx.EXPAND, border=3)
  1402. pageSizer.Add(item=boxSizer, proportion=0,
  1403. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1404. border=5)
  1405. #
  1406. # vector points
  1407. #
  1408. self.win['settings']['vector']['points'] = {}
  1409. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  1410. label=" %s " % (_("Vector points")))
  1411. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  1412. gridSizer = wx.GridBagSizer(vgap=3, hgap=5)
  1413. # show
  1414. row = 0
  1415. showPoints = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  1416. label=_("Show points"))
  1417. showPoints.SetValue(UserSettings.Get(group='nviz', key='vector',
  1418. subkey=['points', 'show']))
  1419. self.win['settings']['vector']['points']['show'] = showPoints.GetId()
  1420. gridSizer.Add(item=showPoints, pos=(row, 0))
  1421. # icon size
  1422. row += 1
  1423. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1424. label=_("Icon size:")),
  1425. pos=(row, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  1426. isize = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  1427. initial=100,
  1428. min=1,
  1429. max=1e6)
  1430. self.win['settings']['vector']['points']['size'] = isize.GetId()
  1431. isize.SetValue(UserSettings.Get(group='nviz', key='vector',
  1432. subkey=['points', 'size']))
  1433. gridSizer.Add(item=isize, pos=(row, 1),
  1434. flag=wx.ALIGN_CENTER_VERTICAL)
  1435. # icon symbol
  1436. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1437. label=_("symbol:")),
  1438. pos=(row, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  1439. isym = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1),
  1440. choices=UserSettings.Get(group='nviz', key='vector',
  1441. subkey=['points', 'icon'], internal=True))
  1442. isym.SetName("selection")
  1443. self.win['settings']['vector']['points']['symbol'] = isym.GetId()
  1444. isym.SetSelection(UserSettings.Get(group='nviz', key='vector',
  1445. subkey=['points', 'symbol']))
  1446. gridSizer.Add(item=isym, flag=wx.ALIGN_CENTER_VERTICAL,
  1447. pos=(row, 3))
  1448. # icon color
  1449. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  1450. label=_("color:")),
  1451. pos=(row, 4), flag=wx.ALIGN_CENTER_VERTICAL)
  1452. icolor = csel.ColourSelect(panel, id=wx.ID_ANY)
  1453. icolor.SetName("color")
  1454. self.win['settings']['vector']['points']['color'] = icolor.GetId()
  1455. icolor.SetColour(UserSettings.Get(group='nviz', key='vector',
  1456. subkey=['points', 'color']))
  1457. gridSizer.Add(item=icolor, flag=wx.ALIGN_CENTER_VERTICAL,
  1458. pos=(row, 5))
  1459. boxSizer.Add(item=gridSizer, proportion=1,
  1460. flag=wx.ALL | wx.EXPAND, border=3)
  1461. pageSizer.Add(item=boxSizer, proportion=0,
  1462. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1463. border=5)
  1464. #
  1465. # buttons
  1466. #
  1467. btnDefault = wx.Button(panel, wx.ID_CANCEL, label=_("Default"))
  1468. btnSave = wx.Button(panel, wx.ID_SAVE)
  1469. btnApply = wx.Button(panel, wx.ID_APPLY)
  1470. btnDefault.Bind(wx.EVT_BUTTON, self.OnDefault)
  1471. btnDefault.SetToolTipString(_("Restore default settings"))
  1472. btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
  1473. btnApply.SetToolTipString(_("Apply changes for the current session"))
  1474. btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
  1475. btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
  1476. btnSave.SetDefault()
  1477. btnSizer = wx.StdDialogButtonSizer()
  1478. btnSizer.AddButton(btnDefault)
  1479. btnSizer.AddButton(btnApply)
  1480. btnSizer.AddButton(btnSave)
  1481. btnSizer.Realize()
  1482. pageSizer.Add(item=btnSizer, proportion=1,
  1483. flag=wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_BOTTOM,
  1484. border=5)
  1485. panel.SetSizer(pageSizer)
  1486. return panel.GetBestSize()
  1487. def CreateControl(self, parent, dict, name, range, bind, sliderHor=True, size=200):
  1488. """Add control (Slider + SpinCtrl)"""
  1489. dict[name] = {}
  1490. if sliderHor:
  1491. style = wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | \
  1492. wx.SL_BOTTOM
  1493. sizeW = (size, -1)
  1494. else:
  1495. style = wx.SL_VERTICAL | wx.SL_AUTOTICKS | \
  1496. wx.SL_BOTTOM | wx.SL_INVERSE
  1497. sizeW = (-1, size)
  1498. try:
  1499. val = self.mapWindow.view[name]['value']
  1500. except KeyError:
  1501. val=-1
  1502. slider = wx.Slider(parent=parent, id=wx.ID_ANY,
  1503. value=val,
  1504. minValue=range[0],
  1505. maxValue=range[1],
  1506. style=style,
  1507. size=sizeW)
  1508. slider.SetName('slider')
  1509. slider.Bind(wx.EVT_SCROLL, bind[0])
  1510. slider.Bind(wx.EVT_SCROLL_CHANGED, bind[1])
  1511. dict[name]['slider'] = slider.GetId()
  1512. spin = wx.SpinCtrl(parent=parent, id=wx.ID_ANY, size=(65, -1),
  1513. initial=val,
  1514. min=range[0],
  1515. max=range[1])
  1516. # spin = wx.SpinButton(parent=parent, id=wx.ID_ANY)
  1517. # spin.SetValue (self.mapWindow.view[name]['value'])
  1518. # spin.SetRange(self.mapWindow.view[name]['min'],
  1519. # self.mapWindow.view[name]['max'])
  1520. # no 'changed' event ... (FIXME)
  1521. spin.SetName('spin')
  1522. spin.Bind(wx.EVT_SPINCTRL, bind[2])
  1523. dict[name]['spin'] = spin.GetId()
  1524. def UpdateSettings(self):
  1525. """Update dialog settings"""
  1526. for control in ('height',
  1527. 'persp',
  1528. 'twist',
  1529. 'z-exag'):
  1530. for win in self.win['view'][control].itervalues():
  1531. if control == 'height':
  1532. value = UserSettings.Get(group='nviz', key='view',
  1533. subkey=['height', 'value'], internal=True)
  1534. else:
  1535. value = self.mapWindow.view[control]['value']
  1536. self.FindWindowById(win).SetValue(value)
  1537. self.FindWindowById(self.win['view']['pos']).Draw()
  1538. self.FindWindowById(self.win['view']['pos']).Refresh(False)
  1539. self.Refresh(False)
  1540. def __GetWindowName(self, dict, id):
  1541. for name in dict.iterkeys():
  1542. if type(dict[name]) is type({}):
  1543. for win in dict[name].itervalues():
  1544. if win == id:
  1545. return name
  1546. else:
  1547. if dict[name] == id:
  1548. return name
  1549. return None
  1550. def OnViewChange(self, event):
  1551. """Change view, render in quick mode"""
  1552. # find control
  1553. winName = self.__GetWindowName(self.win['view'], event.GetId())
  1554. if not winName:
  1555. return
  1556. if winName == 'height':
  1557. view = self.mapWindow.iview # internal
  1558. else:
  1559. view = self.mapWindow.view
  1560. view[winName]['value'] = event.GetInt()
  1561. for win in self.win['view'][winName].itervalues():
  1562. self.FindWindowById(win).SetValue(view[winName]['value'])
  1563. self.mapWindow.update.append('view')
  1564. if winName == 'z-exag':
  1565. self.mapWindow.update.append('z-exag')
  1566. self.mapWindow.render = False
  1567. self.mapWindow.Refresh(False)
  1568. def OnViewChanged(self, event):
  1569. """View changed, render in full resolution"""
  1570. self.mapWindow.render = True
  1571. self.mapWindow.Refresh(False)
  1572. def OnViewChangedSpin(self, event):
  1573. """View changed, render in full resolution"""
  1574. # TODO: use step value instead
  1575. self.OnViewChange(event)
  1576. self.OnViewChanged(None)
  1577. def OnResetView(self, event):
  1578. """Reset to default view (view page)"""
  1579. self.mapWindow.ResetView()
  1580. self.UpdateSettings()
  1581. self.mapWindow.Refresh(False)
  1582. def OnLookAt(self, event):
  1583. """Look at (view page)"""
  1584. sel = event.GetSelection()
  1585. if sel == 0: # top
  1586. self.mapWindow.view['pos']['x'] = 0.5
  1587. self.mapWindow.view['pos']['y'] = 0.5
  1588. elif sel == 1: # north
  1589. self.mapWindow.view['pos']['x'] = 0.5
  1590. self.mapWindow.view['pos']['y'] = 0.0
  1591. elif sel == 2: # south
  1592. self.mapWindow.view['pos']['x'] = 0.5
  1593. self.mapWindow.view['pos']['y'] = 1.0
  1594. elif sel == 3: # east
  1595. self.mapWindow.view['pos']['x'] = 1.0
  1596. self.mapWindow.view['pos']['y'] = 0.5
  1597. elif sel == 4: # west
  1598. self.mapWindow.view['pos']['x'] = 0.0
  1599. self.mapWindow.view['pos']['y'] = 0.5
  1600. elif sel == 5: # north-west
  1601. self.mapWindow.view['pos']['x'] = 0.0
  1602. self.mapWindow.view['pos']['y'] = 0.0
  1603. elif sel == 6: # north-east
  1604. self.mapWindow.view['pos']['x'] = 1.0
  1605. self.mapWindow.view['pos']['y'] = 0.0
  1606. elif sel == 7: # south-east
  1607. self.mapWindow.view['pos']['x'] = 1.0
  1608. self.mapWindow.view['pos']['y'] = 1.0
  1609. elif sel == 8: # south-west
  1610. self.mapWindow.view['pos']['x'] = 0.0
  1611. self.mapWindow.view['pos']['y'] = 1.0
  1612. self.mapWindow.update.append('view')
  1613. self.UpdateSettings()
  1614. self.mapWindow.Refresh(False)
  1615. def OnDefault(self, event):
  1616. """Restore default settings"""
  1617. settings = copy.deepcopy(UserSettings.GetDefaultSettings()['nviz'])
  1618. UserSettings.Set(group='nviz',
  1619. value=settings)
  1620. for subgroup, key in settings.iteritems(): # view, surface, vector...
  1621. if subgroup != 'view':
  1622. continue
  1623. for subkey, value in key.iteritems():
  1624. for subvalue in value.keys():
  1625. win = self.FindWindowById(self.win['settings'][subgroup][subkey][subvalue])
  1626. val = settings[subgroup][subkey][subvalue]
  1627. if subkey == 'pos':
  1628. val = int(val * 100)
  1629. win.SetValue(val)
  1630. event.Skip()
  1631. def OnApply(self, event):
  1632. """Apply button pressed"""
  1633. if self.notebook.GetSelection() == self.page['settings']['id']:
  1634. self.ApplySettings()
  1635. if event:
  1636. event.Skip()
  1637. def ApplySettings(self):
  1638. """Apply Nviz settings for current session"""
  1639. settings = UserSettings.Get(group='nviz')
  1640. for subgroup, key in settings.iteritems(): # view, surface, vector...
  1641. for subkey, value in key.iteritems():
  1642. for subvalue in value.keys():
  1643. # print subgroup, subkey, subvalue
  1644. try: # TODO
  1645. win = self.FindWindowById(self.win['settings'][subgroup][subkey][subvalue])
  1646. except:
  1647. continue
  1648. if win.GetName() == "selection":
  1649. value = win.GetSelection()
  1650. elif win.GetName() == "color":
  1651. value = win.GetColour()
  1652. else:
  1653. value = win.GetValue()
  1654. if subkey == 'pos':
  1655. value = float(value) / 100
  1656. settings[subgroup][subkey][subvalue] = value
  1657. def OnSave(self, event):
  1658. """OK button pressed
  1659. Apply changes, update map and save settings of selected layer
  1660. """
  1661. #
  1662. # apply changes
  1663. #
  1664. self.OnApply(None)
  1665. if self.notebook.GetSelection() == self.page['settings']['id']:
  1666. fileSettings = {}
  1667. UserSettings.ReadSettingsFile(settings=fileSettings)
  1668. fileSettings['nviz'] = UserSettings.Get(group='nviz')
  1669. file = UserSettings.SaveToFile(fileSettings)
  1670. self.lmgr.goutput.WriteLog(_('Nviz settings saved to file <%s>.') % file)
  1671. def OnBgColor(self, event):
  1672. """Background color changed"""
  1673. color = event.GetValue()
  1674. color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  1675. self.mapWindow.nvizClass.SetBgColor(str(color))
  1676. if self.parent.autoRender.IsChecked():
  1677. self.mapWindow.Refresh(False)
  1678. def OnClose(self, event):
  1679. """Close button pressed
  1680. Close dialog
  1681. """
  1682. self.Hide()
  1683. def OnSurfaceUse(self, event):
  1684. """Surface attribute -- use -- map/constant"""
  1685. if not self.mapWindow.init:
  1686. return
  1687. wx.Yield()
  1688. # find attribute row
  1689. attrb = self.__GetWindowName(self.win['surface'], event.GetId())
  1690. if not attrb:
  1691. return
  1692. selection = event.GetSelection()
  1693. if self.win['surface'][attrb]['required']: # no 'unset'
  1694. selection += 1
  1695. if selection == 0: # unset
  1696. useMap = None
  1697. value = ''
  1698. elif selection == 1: # map
  1699. useMap = True
  1700. value = self.FindWindowById(self.win['surface'][attrb]['map']).GetValue()
  1701. elif selection == 2: # constant
  1702. useMap = False
  1703. if attrb == 'color':
  1704. value = self.FindWindowById(self.win['surface'][attrb]['const']).GetColour()
  1705. value = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
  1706. else:
  1707. value = self.FindWindowById(self.win['surface'][attrb]['const']).GetValue()
  1708. self.SetSurfaceUseMap(attrb, useMap)
  1709. self.mapWindow.update.append('surface:attribute:%s' % attrb)
  1710. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1711. data['surface']['attribute'][attrb] = { 'map' : useMap,
  1712. 'value' : str(value),
  1713. }
  1714. self.mapWindow.UpdateLayerProperties()
  1715. if self.parent.autoRender.IsChecked():
  1716. self.mapWindow.Refresh(False)
  1717. def SetSurfaceUseMap(self, attrb, map=None):
  1718. if attrb in ('topo', 'color', 'shine'):
  1719. incSel = -1 # decrement selection (no 'unset')
  1720. else:
  1721. incSel = 0
  1722. if map is True: # map
  1723. if attrb != 'topo': # changing map topography not allowed
  1724. self.FindWindowById(self.win['surface'][attrb]['map'] + 1).Enable(True) # FIXME
  1725. if self.win['surface'][attrb]['const']:
  1726. self.FindWindowById(self.win['surface'][attrb]['const']).Enable(False)
  1727. self.FindWindowById(self.win['surface'][attrb]['use']).SetSelection(1 + incSel)
  1728. elif map is False: # const
  1729. self.FindWindowById(self.win['surface'][attrb]['map'] + 1).Enable(False)
  1730. if self.win['surface'][attrb]['const']:
  1731. self.FindWindowById(self.win['surface'][attrb]['const']).Enable(True)
  1732. self.FindWindowById(self.win['surface'][attrb]['use']).SetSelection(2 + incSel)
  1733. else: # unset
  1734. self.FindWindowById(self.win['surface'][attrb]['map'] + 1).Enable(False)
  1735. if self.win['surface'][attrb]['const']:
  1736. self.FindWindowById(self.win['surface'][attrb]['const']).Enable(False)
  1737. self.FindWindowById(self.win['surface'][attrb]['use']).SetSelection(0)
  1738. def OnSurfaceMap(self, event):
  1739. """Set surface attribute"""
  1740. if not self.mapWindow.init:
  1741. return
  1742. attrb = self.__GetWindowName(self.win['surface'], event.GetId())
  1743. if not attrb:
  1744. return
  1745. selection = self.FindWindowById(self.win['surface'][attrb]['use']).GetSelection()
  1746. if self.win['surface'][attrb]['required']:
  1747. selection += 1
  1748. if selection == 0: # unset
  1749. map = None
  1750. value = ''
  1751. elif selection == 1: # map
  1752. value = self.FindWindowById(self.win['surface'][attrb]['map']).GetValue()
  1753. map = True
  1754. else: # constant
  1755. if attrb == 'color':
  1756. value = self.FindWindowById(self.win['surface'][attrb]['const']).GetColour()
  1757. # tuple to string
  1758. value = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
  1759. else:
  1760. value = self.FindWindowById(self.win['surface'][attrb]['const']).GetValue()
  1761. map = False
  1762. if not self.pageChanging:
  1763. self.mapWindow.update.append('surface:attribute:%s' % attrb)
  1764. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1765. data['surface']['attribute'][attrb] = { 'map' : map,
  1766. 'value' : str(value),
  1767. }
  1768. self.mapWindow.UpdateLayerProperties()
  1769. if self.parent.autoRender.IsChecked():
  1770. self.mapWindow.Refresh(False)
  1771. def OnSurfaceResolution(self, event):
  1772. """Draw resolution changed"""
  1773. self.SetSurfaceResolution()
  1774. if apply and self.parent.autoRender.IsChecked():
  1775. self.mapWindow.Refresh(False)
  1776. def SetSurfaceResolution(self, all=False):
  1777. """Set draw resolution"""
  1778. coarse = self.FindWindowById(self.win['surface']['draw']['res-coarse']).GetValue()
  1779. fine = self.FindWindowById(self.win['surface']['draw']['res-fine']).GetValue()
  1780. self.mapWindow.update.append('surface:draw:resolution')
  1781. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1782. data['surface']['draw']['resolution'] = { 'coarse' : coarse,
  1783. 'fine' : fine,
  1784. 'all' : all }
  1785. self.mapWindow.UpdateLayerProperties()
  1786. def SetSurfaceMode(self, all=False):
  1787. """Set draw mode
  1788. @param apply allow auto-rendering
  1789. """
  1790. mode = self.FindWindowById(self.win['surface']['draw']['mode']).GetSelection()
  1791. if mode == 0: # coarse
  1792. self.FindWindowById(self.win['surface']['draw']['res-coarse']).Enable(True)
  1793. self.FindWindowById(self.win['surface']['draw']['res-fine']).Enable(False)
  1794. elif mode == 1: # fine
  1795. self.FindWindowById(self.win['surface']['draw']['res-coarse']).Enable(False)
  1796. self.FindWindowById(self.win['surface']['draw']['res-fine']).Enable(True)
  1797. else: # both
  1798. self.FindWindowById(self.win['surface']['draw']['res-coarse']).Enable(True)
  1799. self.FindWindowById(self.win['surface']['draw']['res-fine']).Enable(True)
  1800. style = self.FindWindowById(self.win['surface']['draw']['style']).GetSelection()
  1801. shade = self.FindWindowById(self.win['surface']['draw']['shading']).GetSelection()
  1802. value, desc = self.mapWindow.GetSurfaceMode(mode, style, shade)
  1803. return value, desc
  1804. def OnSurfaceMode(self, event):
  1805. """Set draw mode"""
  1806. value, desc = self.SetSurfaceMode()
  1807. self.mapWindow.update.append('surface:draw:mode')
  1808. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1809. data['surface']['draw']['mode'] = { 'value' : value,
  1810. 'all' : False,
  1811. 'desc' : desc }
  1812. self.mapWindow.UpdateLayerProperties()
  1813. if apply and self.parent.autoRender.IsChecked():
  1814. self.mapWindow.Refresh(False)
  1815. def OnSurfaceModeAll(self, event):
  1816. """Set draw mode (including wire color) for all loaded surfaces"""
  1817. self.SetSurfaceMode(all=True)
  1818. self.SetSurfaceResolution(all=True)
  1819. color = self.FindWindowById(self.win['surface']['draw']['wire-color']).GetColour()
  1820. self.SetSurfaceWireColor(color, all=True)
  1821. if apply and self.parent.autoRender.IsChecked():
  1822. self.mapWindow.Refresh(False)
  1823. def SetSurfaceWireColor(self, color, all=False, apply=True):
  1824. """Set wire color"""
  1825. value = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  1826. def OnSurfaceWireColor(self, event):
  1827. """Set wire color"""
  1828. self.SetSurfaceWireColor(event.GetValue())
  1829. self.mapWindow.update.append('surface:draw:wire-color')
  1830. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1831. data['surface']['draw']['wire-color'] = { 'value' : value,
  1832. 'all' : all }
  1833. self.mapWindow.UpdateLayerProperties()
  1834. if self.parent.autoRender.IsChecked():
  1835. self.mapWindow.Refresh(False)
  1836. def OnSurfaceAxis(self, event):
  1837. """Surface position, axis changed"""
  1838. mapLayer = self.mapWindow.GetSelectedLayer()
  1839. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1840. id = data['object']['id']
  1841. axis = self.FindWindowById(self.win['surface']['position']['axis']).GetSelection()
  1842. win = self.FindWindowById(self.win['surface']['position']['pos'])
  1843. x, y, z = self.mapWindow.nvizClass.GetSurfacePosition(id)
  1844. if axis == 0: # x
  1845. win.SetRange(-1e4, 1e4)
  1846. win.SetValue(x)
  1847. elif axis == 1: # y
  1848. win.SetRange(-1e4, 1e4)
  1849. win.SetValue(y)
  1850. else: # z
  1851. win.SetRange(-1e3, 1e3)
  1852. win.SetValue(z)
  1853. def OnSurfacePosition(self, event):
  1854. """Surface position"""
  1855. axis = self.FindWindowById(self.win['surface']['position']['axis']).GetSelection()
  1856. value = event.GetInt()
  1857. mapLayer = self.mapWindow.GetSelectedLayer()
  1858. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1859. id = data['object']['id']
  1860. x, y, z = self.mapWindow.nvizClass.GetSurfacePosition(id)
  1861. if axis == 0: # x
  1862. x = value
  1863. elif axis == 1: # y
  1864. y = value
  1865. else: # z
  1866. z = value
  1867. self.mapWindow.update.append('surface:position')
  1868. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1869. data['surface']['position']['x'] = x
  1870. data['surface']['position']['y'] = y
  1871. data['surface']['position']['z'] = z
  1872. self.mapWindow.UpdateLayerProperties()
  1873. if self.parent.autoRender.IsChecked():
  1874. self.mapWindow.Refresh(False)
  1875. def UpdateVectorShow(self, vecType, enabled):
  1876. """Enable/disable lines/points widgets
  1877. @param vecType vector type (lines, points)
  1878. """
  1879. if vecType != 'lines' and vecType != 'points':
  1880. return False
  1881. for win in self.win['vector'][vecType].keys():
  1882. if win == 'show':
  1883. continue
  1884. if type(self.win['vector'][vecType][win]) == type({}):
  1885. for swin in self.win['vector'][vecType][win].keys():
  1886. if enabled:
  1887. self.FindWindowById(self.win['vector'][vecType][win][swin]).Enable(True)
  1888. else:
  1889. self.FindWindowById(self.win['vector'][vecType][win][swin]).Enable(False)
  1890. else:
  1891. if enabled:
  1892. self.FindWindowById(self.win['vector'][vecType][win]).Enable(True)
  1893. else:
  1894. self.FindWindowById(self.win['vector'][vecType][win]).Enable(False)
  1895. return True
  1896. def OnVectorShow(self, event):
  1897. """Show vector lines/points"""
  1898. winId = event.GetId()
  1899. vecType = None
  1900. if winId == self.win['vector']['lines']['show']:
  1901. vecType = 'lines'
  1902. elif winId == self.win['vector']['points']['show']:
  1903. vecType = 'points'
  1904. if vecType is None:
  1905. return
  1906. checked = event.IsChecked()
  1907. mapLayer = self.mapWindow.GetSelectedLayer()
  1908. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1909. id = data['object']['id']
  1910. if vecType == 'lines':
  1911. if checked:
  1912. self.mapWindow.LoadVector(mapLayer)
  1913. else:
  1914. self.mapWindow.UnloadVector(id)
  1915. else: # points
  1916. if checked:
  1917. self.mapWindow.LoadVector(mapLayer, points=True)
  1918. else:
  1919. self.mapWindow.UnloadVector(id, points=True)
  1920. self.UpdateVectorShow(vecType, checked)
  1921. if self.parent.autoRender.IsChecked():
  1922. self.mapWindow.Refresh(False)
  1923. event.Skip()
  1924. def OnVectorDisplay(self, event):
  1925. """Display vector lines on surface/flat"""
  1926. if event.GetSelection() == 0: # surface
  1927. if len(self.mapWindow.layers['raster']['name']) < 1:
  1928. event.Veto()
  1929. return
  1930. self.FindWindowById(self.win['vector']['lines']['surface']).Enable(True)
  1931. # set first found surface
  1932. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1933. data['vector']['lines']['mode']['surface'] = self.mapWindow.layers['raster']['name'][0]
  1934. self.FindWindowById(self.win['vector']['lines']['surface']).SetStringSelection( \
  1935. self.mapWindow.layers['raster']['name'][0])
  1936. else: # flat
  1937. self.FindWindowById(self.win['vector']['lines']['surface']).Enable(False)
  1938. self.OnVectorLines(event)
  1939. event.Skip()
  1940. def OnVectorLines(self, event):
  1941. """Set vector lines mode, apply changes if auto-rendering is enabled"""
  1942. width = self.FindWindowById(self.win['vector']['lines']['width']).GetValue()
  1943. color = self.FindWindowById(self.win['vector']['lines']['color']).GetColour()
  1944. color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  1945. mode = {}
  1946. if self.FindWindowById(self.win['vector']['lines']['flat']).GetSelection() == 0:
  1947. mode['type'] = 'surface'
  1948. mode['surface'] = self.FindWindowById(self.win['vector']['lines']['surface']).GetValue()
  1949. self.mapWindow.update.append('vector:lines:surface')
  1950. else:
  1951. mode['type'] = 'flat'
  1952. self.mapWindow.update.append('vector:lines:width')
  1953. self.mapWindow.update.append('vector:lines:color')
  1954. self.mapWindow.update.append('vector:lines:mode')
  1955. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1956. data['vector']['lines']['width'] = width
  1957. data['vector']['lines']['color'] = color
  1958. data['vector']['lines']['mode'] = mode
  1959. self.mapWindow.UpdateLayerProperties()
  1960. if self.parent.autoRender.IsChecked():
  1961. self.mapWindow.Refresh(False)
  1962. def OnVectorHeight(self, event):
  1963. value = event.GetInt()
  1964. if type(event) == type(wx.ScrollEvent()):
  1965. # slider
  1966. win = self.FindWindowById(self.win['vector']['lines']['height']['spin'])
  1967. else:
  1968. # spin
  1969. win = self.FindWindowById(self.win['vector']['lines']['height']['slider'])
  1970. win.SetValue(value)
  1971. self.mapWindow.update.append('vector:lines:height')
  1972. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1973. data['vector']['lines']['height'] = value
  1974. self.mapWindow.UpdateLayerProperties()
  1975. if self.parent.autoRender.IsChecked():
  1976. self.mapWindow.Refresh(False)
  1977. def OnVectorSurface(self, event):
  1978. """Reference surface for vector map"""
  1979. self.mapWindow.update.append('vector:lines:surface')
  1980. data['vector']['lines']['mode']['surface'] = event.GetValue()
  1981. self.mapWindow.UpdateLayerProperties()
  1982. if self.parent.autoRender.IsChecked():
  1983. self.mapWindow.Refresh(False)
  1984. def UpdatePage(self, pageId):
  1985. """Update dialog (selected page)"""
  1986. self.pageChanging = True
  1987. layer = self.mapWindow.GetSelectedLayer()
  1988. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1989. if pageId == 'view':
  1990. max = self.mapWindow.view['z-exag']['value'] * 10
  1991. for control in ('spin', 'slider'):
  1992. self.FindWindowById(self.win['view']['z-exag'][control]).SetRange(0,
  1993. max)
  1994. elif pageId == 'surface' and \
  1995. self.notebook.GetSelection() != self.page['surface']['id']:
  1996. if self.page['vector']['id'] > -1:
  1997. self.notebook.RemovePage(self.page['vector']['id'])
  1998. self.page['vector']['id'] = -1
  1999. self.page['surface']['id'] = 1
  2000. self.page['settings']['id'] = 2
  2001. panel = wx.FindWindowById(self.page['surface']['panel'])
  2002. self.notebook.InsertPage(n=self.page['surface']['id'],
  2003. page=panel,
  2004. text=" %s " % _("Layer properties"),
  2005. select=True)
  2006. self.UpdateSurfacePage(layer, data['surface'])
  2007. elif pageId == 'vector' and \
  2008. self.notebook.GetSelection() != self.page['vector']['id']:
  2009. if self.page['surface']['id'] > -1:
  2010. self.notebook.RemovePage(self.page['surface']['id'])
  2011. self.page['surface']['id'] = -1
  2012. self.page['vector']['id'] = 1
  2013. self.page['settings']['id'] = 2
  2014. panel = wx.FindWindowById(self.page['vector']['panel'])
  2015. self.notebook.InsertPage(n=self.page['vector']['id'],
  2016. page=panel,
  2017. text=" %s " % _("Layer properties"),
  2018. select=True)
  2019. self.UpdateVectorPage(layer, data['vector'])
  2020. self.pageChanging = False
  2021. def UpdateSurfacePage(self, layer, data):
  2022. #
  2023. # attributes
  2024. #
  2025. for attr in ('topo', 'color'): # required
  2026. if layer and layer.type == 'raster':
  2027. self.FindWindowById(self.win['surface'][attr]['map']).SetValue(layer.name)
  2028. else:
  2029. self.FindWindowById(self.win['surface'][attr]['map']).SetValue('')
  2030. self.SetSurfaceUseMap(attr, True) # -> map
  2031. if data['attribute'].has_key('color'):
  2032. value = data['attribute']['color']['value']
  2033. if data['attribute']['color']['map']:
  2034. self.FindWindowById(self.win['surface']['color']['map']).SetValue(value)
  2035. else: # constant
  2036. color = map(int, value.split(':'))
  2037. self.FindWindowById(self.win['surface']['color']['const']).SetColour(color)
  2038. self.SetSurfaceUseMap(attr, data['attribute']['color']['map'])
  2039. self.SetSurfaceUseMap('shine', data['attribute']['shine']['map'])
  2040. value = data['attribute']['shine']['value']
  2041. if data['attribute']['shine']['map']:
  2042. self.FindWindowById(self.win['surface']['shine']['map']).SetValue(value)
  2043. else:
  2044. self.FindWindowById(self.win['surface']['shine']['const']).SetValue(value)
  2045. #
  2046. # draw
  2047. #
  2048. for control, dict in data['draw'].iteritems():
  2049. if control == 'resolution':
  2050. self.FindWindowById(self.win['surface']['draw']['res-coarse']).SetValue(dict['coarse'])
  2051. self.FindWindowById(self.win['surface']['draw']['res-fine']).SetValue(dict['fine'])
  2052. continue
  2053. if control == 'mode':
  2054. if dict['desc']['mode'] == 'coarse':
  2055. self.FindWindowById(self.win['surface']['draw']['mode']).SetSelection(0)
  2056. elif dict['desc']['mode'] == 'fine':
  2057. self.FindWindowById(self.win['surface']['draw']['mode']).SetSelection(1)
  2058. else: # both
  2059. self.FindWindowById(self.win['surface']['draw']['mode']).SetSelection(2)
  2060. if dict['desc']['style'] == 'wire':
  2061. self.FindWindowById(self.win['surface']['draw']['style']).SetSelection(0)
  2062. else: # surface
  2063. self.FindWindowById(self.win['surface']['draw']['style']).SetSelection(1)
  2064. if dict['desc']['shading'] == 'flat':
  2065. self.FindWindowById(self.win['surface']['draw']['shading']).SetSelection(0)
  2066. else: # gouraud
  2067. self.FindWindowById(self.win['surface']['draw']['shading']).SetSelection(1)
  2068. continue
  2069. value = dict['value']
  2070. win = self.FindWindowById(self.win['surface']['draw'][control])
  2071. name = win.GetName()
  2072. if name == "selection":
  2073. win.SetSelection(value)
  2074. elif name == "colour":
  2075. color = map(int, value.split(':'))
  2076. win.SetColour(color)
  2077. else:
  2078. win.SetValue(value)
  2079. # enable/disable res widget + set draw mode
  2080. self.SetSurfaceMode()
  2081. color = self.FindWindowById(self.win['surface']['draw']['wire-color'])
  2082. self.SetSurfaceWireColor(color.GetColour())
  2083. def UpdateVectorPage(self, layer, data):
  2084. #
  2085. # lines
  2086. #
  2087. width = self.FindWindowById(self.win['vector']['lines']['width'])
  2088. width.SetValue(data['lines']['width'])
  2089. color = self.FindWindowById(self.win['vector']['lines']['color'])
  2090. color.SetValue(map(int, data['lines']['color'].split(':')))
  2091. display = self.FindWindowById(self.win['vector']['lines']['flat'])
  2092. if data['lines']['mode']['type'] == 'flat':
  2093. display.SetSelection(1)
  2094. else:
  2095. display.SetSelection(0)
  2096. surface = self.FindWindowById(self.win['vector']['lines']['surface'])
  2097. if len(surface.GetItems()) > 0:
  2098. surface.SetSelection(0)
  2099. for type in ('slider', 'spin'):
  2100. win = self.FindWindowById(self.win['vector']['lines']['height'][type])
  2101. win.SetValue(data['lines']['height'])
  2102. def SetPage(self, name):
  2103. """Get named page"""
  2104. self.notebook.SetSelection(self.page[name]['id'])
  2105. class ViewPositionWindow(wx.Window):
  2106. """Position control window (for NvizToolWindow)"""
  2107. def __init__(self, parent, id, mapwindow,
  2108. pos=wx.DefaultPosition,
  2109. size=wx.DefaultSize):
  2110. self.mapWindow = mapwindow
  2111. wx.Window.__init__(self, parent, id, pos, size)
  2112. self.SetBackgroundColour("WHITE")
  2113. self.pdc = wx.PseudoDC()
  2114. self.pdc.SetBrush(wx.Brush(colour='dark green', style=wx.SOLID))
  2115. self.pdc.SetPen(wx.Pen(colour='dark green', width=2, style=wx.SOLID))
  2116. self.Draw()
  2117. self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x: None)
  2118. self.Bind(wx.EVT_PAINT, self.OnPaint)
  2119. # self.Bind(wx.EVT_MOTION, self.OnMouse)
  2120. self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse)
  2121. def Draw(self, pos=None):
  2122. w, h = self.GetClientSize()
  2123. if pos is None:
  2124. x = self.mapWindow.view['pos']['x']
  2125. y = self.mapWindow.view['pos']['y']
  2126. x = x * w
  2127. y = y * h
  2128. else:
  2129. x, y = pos
  2130. self.pdc.Clear()
  2131. self.pdc.BeginDrawing()
  2132. self.pdc.DrawLine(w / 2, h / 2, x, y)
  2133. self.pdc.DrawCircle(x, y, 5)
  2134. self.pdc.EndDrawing()
  2135. def OnPaint(self, event):
  2136. dc = wx.BufferedPaintDC(self)
  2137. dc.SetBackground(wx.Brush("White"))
  2138. dc.Clear()
  2139. self.PrepareDC(dc)
  2140. self.pdc.DrawToDC(dc)
  2141. def OnMouse(self, event):
  2142. if event.LeftIsDown():
  2143. x, y = event.GetPosition()
  2144. self.Draw(pos=(x, y))
  2145. self.Refresh(False)
  2146. w, h = self.GetClientSize()
  2147. x = float(x) / w
  2148. y = float(y) / h
  2149. if x >= 0 and x <= 1.0:
  2150. self.mapWindow.view['pos']['x'] = x
  2151. if y >= 0 and y <= 1.0:
  2152. self.mapWindow.view['pos']['y'] = y
  2153. self.mapWindow.update.append('view')
  2154. self.mapWindow.render = False
  2155. self.mapWindow.Refresh(eraseBackground=False)
  2156. elif event.LeftUp():
  2157. self.mapWindow.render = True
  2158. self.mapWindow.Refresh(eraseBackground=False)
  2159. event.Skip()