nviz.py 78 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018
  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. #
  68. # create nviz instance
  69. #
  70. self.nvizClass = wxnviz.Nviz()
  71. #
  72. # set current display
  73. #
  74. self.nvizClass.SetDisplay(self)
  75. #
  76. # set default lighting model
  77. #
  78. self.nvizClass.SetLightsDefault()
  79. #
  80. # initialize mouse position
  81. #
  82. self.lastX = self.x = 30
  83. self.lastY = self.y = 30
  84. #
  85. # default values
  86. #
  87. self.view = copy.deepcopy(UserSettings.Get(group='nviz', key='view')) # copy
  88. self.iview = UserSettings.Get(group='nviz', key='view', internal=True)
  89. self.update = {} # update view/controls
  90. self.update['view'] = None
  91. self.update['surface'] = {}
  92. for sec in ('attribute', 'draw', 'mask', 'position'):
  93. self.update['surface'][sec] = {}
  94. self.update['vector'] = {}
  95. for sec in ('lines', ):
  96. self.update['vector'][sec] = {}
  97. self.object = {} # loaded data objects (layer index / gsurf id)
  98. self.size = None
  99. self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
  100. self.Bind(wx.EVT_SIZE, self.OnSize)
  101. self.Bind(wx.EVT_PAINT, self.OnPaint)
  102. self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
  103. self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
  104. self.Bind(wx.EVT_MOTION, self.OnMouseAction)
  105. self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouseAction)
  106. def OnEraseBackground(self, event):
  107. pass # do nothing, to avoid flashing on MSW
  108. def OnSize(self, event):
  109. self.size = self.parent.GetClientSize()
  110. if self.GetContext():
  111. Debug.msg(3, "GLCanvas.OnPaint(): w=%d, h=%d" % \
  112. (self.size.width, self.size.height))
  113. self.SetCurrent()
  114. self.nvizClass.ResizeWindow(self.size.width,
  115. self.size.height)
  116. event.Skip()
  117. def OnPaint(self, event):
  118. Debug.msg(3, "GLCanvas.OnPaint()")
  119. dc = wx.PaintDC(self)
  120. self.SetCurrent()
  121. if not self.init:
  122. self.nvizClass.InitView()
  123. self.LoadDataLayers()
  124. self.ResetView()
  125. if hasattr(self.parent, "nvizToolWin"):
  126. self.parent.nvizToolWin.UpdatePage('view')
  127. self.parent.nvizToolWin.UpdateSettings()
  128. self.init = True
  129. self.UpdateMap()
  130. def OnMouseAction(self, event):
  131. # change position
  132. if event.Dragging() and event.LeftIsDown():
  133. self.lastX = self.lastY = self.x = self.y
  134. self.x, self.y = event.GetPosition()
  135. self.Refresh(False)
  136. # change perspective with mouse wheel
  137. wheel = event.GetWheelRotation()
  138. if wheel != 0:
  139. current = event.GetPositionTuple()[:]
  140. Debug.msg (5, "GLWindow.OnMouseMotion(): wheel=%d" % wheel)
  141. if wheel > 0:
  142. value = -1 * self.view['persp']['step']
  143. else:
  144. value = self.view['persp']['step']
  145. self.view['persp']['value'] += value
  146. if self.view['persp']['value'] < 1:
  147. self.view['persp']['value'] = 1
  148. elif self.view['persp']['value'] > 100:
  149. self.view['persp']['value'] = 100
  150. if hasattr(self.parent, "nvizToolWin"):
  151. self.parent.nvizToolWin.UpdateSettings()
  152. self.nvizClass.SetView(self.view['pos']['x'], self.view['pos']['y'],
  153. self.iview['height']['value'],
  154. self.view['persp']['value'],
  155. self.view['twist']['value'])
  156. # redraw map
  157. self.OnPaint(None)
  158. # update statusbar
  159. ### self.parent.StatusbarUpdate()
  160. def OnLeftDown(self, event):
  161. self.CaptureMouse()
  162. self.x, self.y = self.lastX, self.lastY = event.GetPosition()
  163. def OnLeftUp(self, event):
  164. self.ReleaseMouse()
  165. def UpdateMap(self, render=True):
  166. """
  167. Updates the canvas anytime there is a change to the
  168. underlaying images or to the geometry of the canvas.
  169. @param render re-render map composition
  170. """
  171. start = time.clock()
  172. self.resize = False
  173. # if self.size is None:
  174. # self.size = self.GetClientSize()
  175. # w, h = self.size
  176. # w = float(max(w, 1.0))
  177. # h = float(max(h, 1.0))
  178. # d = float(min(w, h))
  179. # xScale = d / w
  180. # yScale = d / h
  181. # print w, h, d, xScale, yScale
  182. # print self.y, self.lastY, self.x, self.lastX
  183. # print (self.y - self.lastY) * yScale, (self.x - self.lastX) * xScale
  184. # print self.x * xScale
  185. #glRotatef((self.y - self.lastY) * yScale, 1.0, 0.0, 0.0);
  186. #glRotatef((self.x - self.lastX) * xScale, 0.0, 1.0, 0.0);
  187. if self.render:
  188. self.parent.onRenderGauge.Show()
  189. self.parent.onRenderGauge.SetRange(2)
  190. self.parent.onRenderGauge.SetValue(0)
  191. if self.update['view']:
  192. if 'z-exag' in self.update['view']:
  193. self.nvizClass.SetZExag(self.view['z-exag']['value'])
  194. self.nvizClass.SetView(self.view['pos']['x'], self.view['pos']['y'],
  195. self.iview['height']['value'],
  196. self.view['persp']['value'],
  197. self.view['twist']['value'])
  198. self.update['view'] = None
  199. if self.render is True:
  200. self.parent.onRenderGauge.SetValue(1)
  201. wx.Yield()
  202. self.nvizClass.Draw(False)
  203. else:
  204. self.nvizClass.Draw(True) # quick
  205. self.SwapBuffers()
  206. stop = time.clock()
  207. if self.render:
  208. self.parent.onRenderGauge.SetValue(2)
  209. # hide process bar
  210. self.parent.onRenderGauge.Hide()
  211. #
  212. # update statusbar
  213. #
  214. # self.parent.StatusbarUpdate()
  215. Debug.msg(3, "GLWindow.UpdateMap(): render=%s, -> time=%g" % \
  216. (self.render, (stop-start)))
  217. def EraseMap(self):
  218. """
  219. Erase the canvas
  220. """
  221. self.nvizClass.EraseMap()
  222. self.SwapBuffers()
  223. def IsLoaded(self, layer):
  224. """Check if layer is already loaded"""
  225. if self.Map.GetLayerIndex(layer) in self.object.keys():
  226. return 1
  227. return 0
  228. def LoadDataLayers(self):
  229. """Load raster/vector from current layer tree
  230. @todo volumes
  231. """
  232. # load raster maps
  233. for layer in self.Map.GetListOfLayers(l_type='raster', l_active=True):
  234. self.LoadRaster(layer)
  235. # load vector maps
  236. for layer in self.Map.GetListOfLayers(l_type='vector', l_active=True):
  237. self.LoadVector(layer)
  238. def LoadRaster(self, layer):
  239. """Load raster map -> surface"""
  240. if layer.type != 'raster':
  241. return
  242. id = self.nvizClass.LoadSurface(str(layer.name), None, None)
  243. if id < 0:
  244. raise gcmd.NvizError(parent=self.parent,
  245. message=_("Unable to load raster map <%s>" % layer.name))
  246. # set resolution
  247. res = UserSettings.Get(group='nviz', key='surface',
  248. subkey=['draw', 'res-fine'])
  249. wire = UserSettings.Get(group='nviz', key='surface',
  250. subkey=['draw', 'res-coarse'])
  251. self.nvizClass.SetSurfaceRes(id, res, wire)
  252. self.object[self.Map.GetLayerIndex(layer)] = id ### FIXME layer index is not fixed id!
  253. def UnloadRaster(self, layer):
  254. """Unload raster map"""
  255. if layer.type != 'raster':
  256. return
  257. idx = self.Map.GetLayerIndex(layer) ### FIXME layer index is not fixed id!
  258. if not self.object.has_key(idx):
  259. return
  260. if layer.type == 'raster':
  261. if self.nvizClass.UnloadSurface(self.object[idx]) == 0:
  262. raise gcmd.NvizError(parent=self.parent,
  263. message=_("Unable to unload raster map <%s>" % layer.name))
  264. def LoadVector(self, layer):
  265. """Load vector map overlay"""
  266. if layer.type != 'vector':
  267. return
  268. id = self.nvizClass.LoadVector(str(layer.name))
  269. if id < 0:
  270. raise gcmd.NvizError(parent=self.parent,
  271. message=_("Unable to load vector map <%s>" % layer.name))
  272. self.object[self.Map.GetLayerIndex(layer)] = id ### FIXME layer index is not fixed id!
  273. def UnloadVector(self, layer):
  274. """Unload vector map overlay"""
  275. if layer.type != 'vector':
  276. return
  277. idx = self.Map.GetLayerIndex(layer) ### FIXME layer index is not fixed id!
  278. if not self.object.has_key(idx):
  279. return
  280. if layer.type == 'vector':
  281. if self.nvizClass.UnloadVector(self.object[idx]) == 0:
  282. raise gcmd.NvizError(parent=self.parent,
  283. message=_("Unable to unload vector map <%s>" % layer.name))
  284. def Reset(self):
  285. """Reset (unload data)"""
  286. self.nvizClass.Reset()
  287. self.init = False
  288. def OnZoomToMap(self, event):
  289. """
  290. Set display extents to match selected raster
  291. or vector map or volume.
  292. @todo vector, volume
  293. """
  294. layer = self.GetSelectedLayer()
  295. if layer is None:
  296. return
  297. Debug.msg (3, "GLWindow.OnZoomToMap(): layer=%s, type=%s" % \
  298. (layer.name, layer.type))
  299. self.nvizClass.SetViewportDefault()
  300. def ResetView(self):
  301. """Reset to default view"""
  302. self.view['z-exag']['value'], \
  303. self.iview['height']['value'] = self.nvizClass.SetViewDefault()
  304. self.view['pos']['x'] = UserSettings.Get(group='nviz', key='view',
  305. subkey=('pos', 'x'))
  306. self.view['pos']['y'] = UserSettings.Get(group='nviz', key='view',
  307. subkey=('pos', 'x'))
  308. self.view['persp']['value'] = UserSettings.Get(group='nviz', key='view',
  309. subkey=('persp', 'value'))
  310. self.view['twist']['value'] = UserSettings.Get(group='nviz', key='view',
  311. subkey=('twist', 'value'))
  312. self.update['view'] = ('z-exag', 'pos', 'persp', 'twist')
  313. def GetMapObjId(self, layer):
  314. """Get map object id of given map layer (2D)
  315. @param layer MapLayer instance
  316. """
  317. index = self.Map.GetLayerIndex(layer)
  318. try:
  319. return self.object[index]
  320. except:
  321. return -1
  322. class NvizToolWindow(wx.Frame):
  323. """Experimental window for Nviz tools
  324. @todo integrate with Map display
  325. """
  326. def __init__(self, parent=None, id=wx.ID_ANY, title=_("Nviz tools"),
  327. pos=wx.DefaultPosition, size=wx.DefaultSize,
  328. style=wx.DEFAULT_FRAME_STYLE, mapWindow=None):
  329. self.parent = parent # MapFrame
  330. self.lmgr = self.parent.gismanager # GMFrame
  331. self.mapWindow = mapWindow
  332. wx.Frame.__init__(self, parent, id, title, pos, size, style)
  333. #
  334. # icon
  335. #
  336. self.SetIcon(wx.Icon(os.path.join(globalvar.ETCDIR, 'grass_nviz.ico'), wx.BITMAP_TYPE_ICO))
  337. #
  338. # dialog body
  339. #
  340. mainSizer = wx.BoxSizer(wx.VERTICAL)
  341. self.win = {} # window ids
  342. #
  343. # notebook
  344. #
  345. self.notebook = wx.Notebook(parent=self, id=wx.ID_ANY, style=wx.BK_DEFAULT)
  346. self.page = {}
  347. # view page
  348. self.__createViewPage()
  349. self.page['view'] = 0
  350. # surface page
  351. self.__createSurfacePage()
  352. self.page['surface'] = 1
  353. # vector page
  354. self.__createVectorPage()
  355. self.page['vector'] = 2
  356. # settings page
  357. self.__createSettingsPage()
  358. self.page['settings'] = 3
  359. self.pageUpdated = True
  360. self.UpdatePage('surface')
  361. self.UpdatePage('vector')
  362. self.UpdatePage('settings')
  363. mainSizer.Add(item=self.notebook, proportion=1,
  364. flag=wx.EXPAND | wx.ALL, border=5)
  365. #
  366. # update dialog (selected layer)
  367. #
  368. mapLayer = self.mapWindow.GetSelectedLayer()
  369. if mapLayer:
  370. type = mapLayer.type
  371. if type == 'raster':
  372. self.UpdatePage('surface')
  373. elif type == 'vector':
  374. self.UpdatePage('vector')
  375. #
  376. # bindings
  377. #
  378. self.Bind(wx.EVT_CLOSE, self.OnClose)
  379. #
  380. # layout
  381. #
  382. self.SetSizer(mainSizer)
  383. mainSizer.Fit(self)
  384. def __createViewPage(self):
  385. """Create view settings page"""
  386. panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
  387. self.notebook.AddPage(page=panel,
  388. text=" %s " % _("View"))
  389. pageSizer = wx.BoxSizer(wx.VERTICAL)
  390. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  391. self.win['view'] = {}
  392. # position
  393. posSizer = wx.GridBagSizer(vgap=3, hgap=3)
  394. posSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("W")),
  395. pos=(1, 0), flag=wx.ALIGN_CENTER)
  396. posSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("N")),
  397. pos=(0, 1), flag=wx.ALIGN_CENTER | wx.ALIGN_BOTTOM)
  398. viewPos = ViewPositionWindow(panel, id=wx.ID_ANY, size=(175, 175),
  399. mapwindow=self.mapWindow)
  400. self.win['view']['pos'] = viewPos.GetId()
  401. posSizer.Add(item=viewPos,
  402. pos=(1, 1), flag=wx.ALIGN_CENTER | wx.ALIGN_CENTER_VERTICAL)
  403. posSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("S")),
  404. pos=(2, 1), flag=wx.ALIGN_CENTER | wx.ALIGN_TOP)
  405. posSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("E")),
  406. pos=(1, 2), flag=wx.ALIGN_CENTER)
  407. gridSizer.Add(item=posSizer, pos=(0, 0))
  408. # perspective
  409. range = UserSettings.Get(group='nviz', key='view', subkey='persp', internal=True)
  410. self.CreateControl(panel, dict=self.win['view'], name='persp',
  411. range=(range['min'], range['max']),
  412. bind=(self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
  413. gridSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("Perspective:")),
  414. pos=(1, 0), flag=wx.ALIGN_CENTER)
  415. gridSizer.Add(item=self.FindWindowById(self.win['view']['persp']['slider']), pos=(2, 0))
  416. gridSizer.Add(item=self.FindWindowById(self.win['view']['persp']['spin']), pos=(3, 0),
  417. flag=wx.ALIGN_CENTER)
  418. # twist
  419. range = UserSettings.Get(group='nviz', key='view', subkey='twist', internal=True)
  420. self.CreateControl(panel, dict=self.win['view'], name='twist',
  421. range=(range['min'], range['max']),
  422. bind=(self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
  423. gridSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("Twist:")),
  424. pos=(1, 1), flag=wx.ALIGN_CENTER)
  425. gridSizer.Add(item=self.FindWindowById(self.win['view']['twist']['slider']), pos=(2, 1))
  426. gridSizer.Add(item=self.FindWindowById(self.win['view']['twist']['spin']), pos=(3, 1),
  427. flag=wx.ALIGN_CENTER)
  428. # height + z-exag
  429. self.CreateControl(panel, dict=self.win['view'], name='height', sliderHor=False,
  430. range=(self.mapWindow.view['height']['min'], self.mapWindow.view['height']['max']),
  431. bind=(self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
  432. self.CreateControl(panel, dict=self.win['view'], name='z-exag', sliderHor=False,
  433. range=(0, 1),
  434. bind=(self.OnViewChange, self.OnViewChanged, self.OnViewChangedSpin))
  435. heightSizer = wx.GridBagSizer(vgap=3, hgap=3)
  436. heightSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("Height:")),
  437. pos=(0, 0), flag=wx.ALIGN_LEFT, span=(1, 2))
  438. heightSizer.Add(item=self.FindWindowById(self.win['view']['height']['slider']),
  439. flag=wx.ALIGN_RIGHT, pos=(1, 0))
  440. heightSizer.Add(item=self.FindWindowById(self.win['view']['height']['spin']),
  441. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.TOP |
  442. wx.BOTTOM | wx.RIGHT, pos=(1, 1))
  443. heightSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY, label=_("Z-exag:")),
  444. pos=(0, 2), flag=wx.ALIGN_LEFT, span=(1, 2))
  445. heightSizer.Add(item=self.FindWindowById(self.win['view']['z-exag']['slider']),
  446. flag=wx.ALIGN_RIGHT, pos=(1, 2))
  447. heightSizer.Add(item=self.FindWindowById(self.win['view']['z-exag']['spin']),
  448. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_LEFT | wx.TOP |
  449. wx.BOTTOM | wx.RIGHT, pos=(1, 3))
  450. gridSizer.Add(item=heightSizer, pos=(0, 1), flag=wx.ALIGN_RIGHT)
  451. # view setup + reset
  452. viewSizer = wx.BoxSizer(wx.HORIZONTAL)
  453. viewSizer.Add(item=wx.StaticText(panel, id=wx.ID_ANY,
  454. label=_("Look at:")),
  455. flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5)
  456. viewType = wx.Choice (parent=panel, id=wx.ID_ANY, size=(125, -1),
  457. choices = [_("top"),
  458. _("north"),
  459. _("south"),
  460. _("east"),
  461. _("west"),
  462. _("north-west"),
  463. _("north-east"),
  464. _("south-east"),
  465. _("south-west")])
  466. viewType.SetSelection(0)
  467. viewType.Bind(wx.EVT_CHOICE, self.OnLookAt)
  468. # self.win['lookAt'] = viewType.GetId()
  469. viewSizer.Add(item=viewType, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL,
  470. border=5)
  471. reset = wx.Button(panel, id=wx.ID_ANY, label=_("Reset"))
  472. reset.SetToolTipString(_("Reset to default view"))
  473. # self.win['reset'] = reset.GetId()
  474. reset.Bind(wx.EVT_BUTTON, self.OnResetView)
  475. viewSizer.Add(item=reset, proportion=1,
  476. flag=wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT,
  477. border=5)
  478. gridSizer.AddGrowableCol(3)
  479. gridSizer.Add(item=viewSizer, pos=(4, 0), span=(1, 2),
  480. flag=wx.EXPAND)
  481. # body
  482. pageSizer.Add(item=gridSizer, proportion=1,
  483. flag=wx.EXPAND | wx.ALL,
  484. border=5)
  485. panel.SetSizer(pageSizer)
  486. def __createSurfacePage(self):
  487. """Create view settings page"""
  488. panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
  489. # panel = scrolled.ScrolledPanel(parent=self.notebook, id=wx.ID_ANY)
  490. # panel.SetupScrolling(scroll_x=True, scroll_y=True)
  491. self.notebook.AddPage(page=panel,
  492. text=" %s " % _("Surface"))
  493. pageSizer = wx.BoxSizer(wx.VERTICAL)
  494. self.win['surface'] = {}
  495. #
  496. # surface attributes
  497. #
  498. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  499. label=" %s " % (_("Surface attributes")))
  500. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  501. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  502. # labels
  503. # col = 0
  504. # for type in (_("Attribute"),
  505. # _("Use"),
  506. # _("Map"),
  507. # _("Constant")):
  508. # gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  509. # label=type),
  510. # pos=(0, col))
  511. # col += 1
  512. # type
  513. self.win['surface']['attr'] = {}
  514. row = 0
  515. for code, attrb in (('topo', _("Topography")),
  516. ('color', _("Color")),
  517. ('mask', _("Mask")),
  518. ('transp', _("Transparency")),
  519. ('shine', _("Shininess")),
  520. ('emit', _("Emission"))):
  521. self.win['surface'][code] = {}
  522. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  523. label=attrb + ':'),
  524. pos=(row, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  525. use = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1),
  526. choices = [_("map")])
  527. if code not in ('topo', 'color', 'shine'):
  528. use.Insert(item=_("unset"), pos=0)
  529. self.win['surface'][code]['required'] = False
  530. else:
  531. self.win['surface'][code]['required'] = True
  532. if code != 'mask':
  533. use.Append(item=_('constant'))
  534. self.win['surface'][code]['use'] = use.GetId()
  535. use.Bind(wx.EVT_CHOICE, self.OnSurfaceUse)
  536. gridSizer.Add(item=use, flag=wx.ALIGN_CENTER_VERTICAL,
  537. pos=(row, 1))
  538. map = gselect.Select(parent=panel, id=wx.ID_ANY,
  539. # size=globalvar.DIALOG_GSELECT_SIZE,
  540. size=(200, -1),
  541. type="raster")
  542. self.win['surface'][code]['map'] = map.GetId() - 1 # FIXME
  543. map.Bind(wx.EVT_TEXT, self.OnSurfaceMap)
  544. # changing map topography not allowed
  545. if code == 'topo':
  546. map.Enable(False)
  547. gridSizer.Add(item=map, flag=wx.ALIGN_CENTER_VERTICAL,
  548. pos=(row, 2))
  549. if code == 'color':
  550. value = csel.ColourSelect(panel, id=wx.ID_ANY,
  551. colour=UserSettings.Get(group='nviz', key='surface',
  552. subkey=['color', 'value']))
  553. value.Bind(csel.EVT_COLOURSELECT, self.OnSurfaceMap)
  554. elif code == 'mask':
  555. value = None
  556. else:
  557. value = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  558. initial=0)
  559. if code == 'topo':
  560. value.SetRange(minVal=-1e9, maxVal=1e9)
  561. elif code in ('shine', 'transp', 'emit'):
  562. value.SetRange(minVal=0, maxVal=255)
  563. else:
  564. value.SetRange(minVal=0, maxVal=100)
  565. value.Bind(wx.EVT_TEXT, self.OnSurfaceMap)
  566. if value:
  567. self.win['surface'][code]['const'] = value.GetId()
  568. value.Enable(False)
  569. gridSizer.Add(item=value, flag=wx.ALIGN_CENTER_VERTICAL,
  570. pos=(row, 3))
  571. else:
  572. self.win['surface'][code]['const'] = None
  573. self.SetSurfaceUseMap(code) # -> enable map / disable constant
  574. row += 1
  575. boxSizer.Add(item=gridSizer, proportion=1,
  576. flag=wx.ALL | wx.EXPAND, border=3)
  577. pageSizer.Add(item=boxSizer, proportion=0,
  578. flag=wx.EXPAND | wx.ALL,
  579. border=5)
  580. #
  581. # draw
  582. #
  583. self.win['surface']['draw'] = {}
  584. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  585. label=" %s " % (_("Draw")))
  586. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  587. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  588. gridSizer.AddGrowableCol(4)
  589. # mode
  590. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  591. label=_("Mode:")),
  592. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  593. mode = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1),
  594. choices = [_("coarse"),
  595. _("fine"),
  596. _("both")])
  597. mode.SetName("selection")
  598. mode.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
  599. self.win['surface']['draw']['mode'] = mode.GetId()
  600. gridSizer.Add(item=mode, flag=wx.ALIGN_CENTER_VERTICAL,
  601. pos=(0, 1))
  602. # resolution (mode)
  603. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  604. label=_("Resolution:")),
  605. pos=(0, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  606. resSizer = wx.BoxSizer(wx.HORIZONTAL)
  607. resSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  608. label=_("coarse:")),
  609. flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3)
  610. resC = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  611. initial=1,
  612. min=1,
  613. max=100)
  614. resC.SetName("value")
  615. self.win['surface']['draw']['res-coarse'] = resC.GetId()
  616. resC.Bind(wx.EVT_SPINCTRL, self.OnSurfaceResolution)
  617. resSizer.Add(item=resC, flag=wx.ALL, border=3)
  618. resSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  619. label=_("fine:")),
  620. flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3)
  621. resF = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  622. initial=1,
  623. min=1,
  624. max=100)
  625. resF.SetName("value")
  626. self.win['surface']['draw']['res-fine'] = resF.GetId()
  627. resF.Bind(wx.EVT_SPINCTRL, self.OnSurfaceResolution)
  628. resSizer.Add(item=resF, flag=wx.ALL, border=3)
  629. gridSizer.Add(item=resSizer, pos=(0, 3), span=(1, 2))
  630. # style
  631. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  632. label=_("Coarse style:")),
  633. pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  634. style = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1),
  635. choices = [_("wire"),
  636. _("surface")])
  637. style.SetName("selection")
  638. self.win['surface']['draw']['style'] = style.GetId()
  639. style.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
  640. gridSizer.Add(item=style, flag=wx.ALIGN_CENTER_VERTICAL,
  641. pos=(1, 1))
  642. # shading
  643. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  644. label=_("Shading:")),
  645. pos=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  646. shade = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1),
  647. choices = [_("flat"),
  648. _("gouraud")])
  649. shade.SetName("selection")
  650. self.win['surface']['draw']['shading'] = shade.GetId()
  651. shade.Bind(wx.EVT_CHOICE, self.OnSurfaceMode)
  652. gridSizer.Add(item=shade, flag=wx.ALIGN_CENTER_VERTICAL,
  653. pos=(1, 3))
  654. # color
  655. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  656. label=_("Wire color:")),
  657. pos=(2, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  658. color = csel.ColourSelect(panel, id=wx.ID_ANY)
  659. color.SetName("colour")
  660. color.Bind(csel.EVT_COLOURSELECT, self.OnSurfaceWireColor)
  661. self.win['surface']['draw']['color'] = color.GetId()
  662. gridSizer.Add(item=color, flag=wx.ALIGN_CENTER_VERTICAL,
  663. pos=(2, 1))
  664. boxSizer.Add(item=gridSizer, proportion=1,
  665. flag=wx.ALL | wx.EXPAND, border=3)
  666. pageSizer.Add(item=boxSizer, proportion=0,
  667. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  668. border=5)
  669. all = wx.Button(panel, id=wx.ID_ANY, label=_("All"))
  670. all.SetToolTipString(_("Use for all loaded surfaces"))
  671. # self.win['reset'] = reset.GetId()
  672. all.Bind(wx.EVT_BUTTON, self.OnSurfaceModeAll)
  673. gridSizer.Add(item=all, flag=wx.ALIGN_CENTER_VERTICAL | wx.EXPAND,
  674. pos=(2, 4))
  675. #
  676. # mask
  677. #
  678. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  679. label=" %s " % (_("Mask")))
  680. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  681. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  682. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  683. label=_("Mask zeros:")),
  684. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  685. elev = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  686. label=_("by elevation"))
  687. elev.Enable(False) # TODO: not implemented yet
  688. gridSizer.Add(item=elev, pos=(0, 1))
  689. color = wx.CheckBox(parent=panel, id=wx.ID_ANY,
  690. label=_("by color"))
  691. color.Enable(False) # TODO: not implemented yet
  692. gridSizer.Add(item=color, pos=(0, 2))
  693. boxSizer.Add(item=gridSizer, proportion=1,
  694. flag=wx.ALL | wx.EXPAND, border=3)
  695. pageSizer.Add(item=boxSizer, proportion=0,
  696. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  697. border=5)
  698. #
  699. # position
  700. #
  701. self.win['surface']['position'] = {}
  702. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  703. label=" %s " % (_("Position")))
  704. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  705. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  706. # position
  707. axis = wx.Choice (parent=panel, id=wx.ID_ANY, size=(75, -1),
  708. choices = ["X",
  709. "Y",
  710. "Z"])
  711. axis.SetSelection(0)
  712. self.win['surface']['position']['axis'] = axis.GetId()
  713. axis.Bind(wx.EVT_CHOICE, self.OnSurfaceAxis)
  714. gridSizer.Add(item=axis, flag=wx.ALIGN_CENTER_VERTICAL,
  715. pos=(0, 0))
  716. value = wx.Slider(parent=panel, id=wx.ID_ANY,
  717. value=0,
  718. minValue=-1e4,
  719. maxValue=1e4,
  720. style=wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | \
  721. wx.SL_TOP | wx.SL_LABELS,
  722. size=(350, -1))
  723. self.win['surface']['position']['pos'] = value.GetId()
  724. value.Bind(wx.EVT_SCROLL, self.OnSurfacePosition)
  725. gridSizer.Add(item=value, flag=wx.ALIGN_CENTER_VERTICAL,
  726. pos=(0, 1))
  727. boxSizer.Add(item=gridSizer, proportion=1,
  728. flag=wx.ALL | wx.EXPAND, border=3)
  729. pageSizer.Add(item=boxSizer, proportion=0,
  730. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  731. border=5)
  732. panel.SetSizer(pageSizer)
  733. def __createVectorPage(self):
  734. """Create view settings page"""
  735. panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
  736. self.notebook.AddPage(page=panel,
  737. text=" %s " % _("Vector"))
  738. pageSizer = wx.BoxSizer(wx.VERTICAL)
  739. self.win['vector'] = {}
  740. #
  741. # vector lines
  742. #
  743. self.win['vector']['lines'] = {}
  744. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  745. label=" %s " % (_("Vector lines")))
  746. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  747. gridSizer = wx.GridBagSizer(vgap=5, hgap=5)
  748. # width
  749. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  750. label=_("Width:")),
  751. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  752. width = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  753. initial=1,
  754. min=1,
  755. max=100)
  756. self.win['vector']['lines']['width'] = width.GetId()
  757. width.Bind(wx.EVT_SPINCTRL, self.OnVectorLines)
  758. gridSizer.Add(item=width, pos=(0, 1),
  759. flag=wx.ALIGN_CENTER_VERTICAL)
  760. gridSizer.AddGrowableCol(2)
  761. # color
  762. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  763. label=_("Color:")),
  764. pos=(0, 3), flag=wx.ALIGN_CENTER_VERTICAL)
  765. color = csel.ColourSelect(panel, id=wx.ID_ANY,
  766. colour=UserSettings.Get(group='nviz', key='vector',
  767. subkey=['lines', 'color']))
  768. self.win['vector']['lines']['color'] = color.GetId()
  769. color.Bind(csel.EVT_COLOURSELECT, self.OnVectorLines)
  770. gridSizer.Add(item=color, pos=(0, 4))
  771. gridSizer.AddGrowableCol(5)
  772. # display
  773. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  774. label=_("Display:")),
  775. pos=(0, 6), flag=wx.ALIGN_CENTER_VERTICAL)
  776. display = wx.Choice (parent=panel, id=wx.ID_ANY, size=(100, -1),
  777. choices = [_("on surface"),
  778. _("flat")])
  779. self.win['vector']['lines']['flat'] = display.GetId()
  780. display.Bind(wx.EVT_CHOICE, self.OnVectorDisplay)
  781. gridSizer.Add(item=display, flag=wx.ALIGN_CENTER_VERTICAL,
  782. pos=(0, 7))
  783. surface = wx.ComboBox(parent=panel, id=wx.ID_ANY, size=(250, -1),
  784. style=wx.CB_SIMPLE | wx.CB_READONLY,
  785. choices=[])
  786. self.win['vector']['lines']['surface'] = surface.GetId()
  787. gridSizer.Add(item=surface,
  788. pos=(1, 0), span=(1, 8),
  789. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALIGN_RIGHT)
  790. # high
  791. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  792. label=_("Hight above surface:")),
  793. pos=(2, 0), flag=wx.ALIGN_CENTER_VERTICAL,
  794. span=(1, 2))
  795. self.CreateControl(panel, dict=self.win['vector']['lines'], name='height', size=300,
  796. range=(0, 1000),
  797. bind=(self.OnVectorHeight, self.OnVectorHeight, self.OnVectorHeight))
  798. gridSizer.Add(item=self.FindWindowById(self.win['vector']['lines']['height']['slider']),
  799. pos=(2, 2), span=(1, 6))
  800. gridSizer.Add(item=self.FindWindowById(self.win['vector']['lines']['height']['spin']),
  801. pos=(3, 4),
  802. flag=wx.ALIGN_CENTER)
  803. boxSizer.Add(item=gridSizer, proportion=1,
  804. flag=wx.ALL | wx.EXPAND, border=3)
  805. pageSizer.Add(item=boxSizer, proportion=0,
  806. flag=wx.EXPAND | wx.ALL,
  807. border=5)
  808. panel.SetSizer(pageSizer)
  809. def __createSettingsPage(self):
  810. """Create settings page"""
  811. panel = wx.Panel(parent=self.notebook, id=wx.ID_ANY)
  812. self.notebook.AddPage(page=panel,
  813. text=" %s " % _("Settings"))
  814. pageSizer = wx.BoxSizer(wx.VERTICAL)
  815. self.win['settings'] = {}
  816. #
  817. # general
  818. #
  819. self.win['settings']['general'] = {}
  820. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  821. label=" %s " % (_("General")))
  822. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  823. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  824. # background color
  825. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  826. label=_("Background color:")),
  827. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  828. color = csel.ColourSelect(panel, id=wx.ID_ANY,
  829. colour=UserSettings.Get(group='nviz', key='settings',
  830. subkey=['general', 'bgcolor']))
  831. self.win['settings']['general']['bgcolor'] = color.GetId()
  832. color.Bind(csel.EVT_COLOURSELECT, self.OnBgColor)
  833. gridSizer.Add(item=color, pos=(0, 1))
  834. boxSizer.Add(item=gridSizer, proportion=1,
  835. flag=wx.ALL | wx.EXPAND, border=3)
  836. pageSizer.Add(item=boxSizer, proportion=0,
  837. flag=wx.EXPAND | wx.ALL,
  838. border=5)
  839. #
  840. # view
  841. #
  842. self.win['settings']['view'] = {}
  843. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  844. label=" %s " % (_("View")))
  845. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  846. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  847. # perspective
  848. self.win['settings']['view']['persp'] = {}
  849. pvals = UserSettings.Get(group='nviz', key='view', subkey='persp')
  850. ipvals = UserSettings.Get(group='nviz', key='view', subkey='persp', internal=True)
  851. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  852. label=_("Perspective (value):")),
  853. pos=(0, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  854. pval = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  855. initial=pvals['value'],
  856. min=ipvals['min'],
  857. max=ipvals['max'])
  858. self.win['settings']['view']['persp']['value'] = pval.GetId()
  859. gridSizer.Add(item=pval, pos=(0, 1),
  860. flag=wx.ALIGN_CENTER_VERTICAL)
  861. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  862. label=_("(step):")),
  863. pos=(0, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  864. pstep = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  865. initial=pvals['step'],
  866. min=ipvals['min'],
  867. max=ipvals['max']-1)
  868. self.win['settings']['view']['persp']['step'] = pstep.GetId()
  869. gridSizer.Add(item=pstep, pos=(0, 3),
  870. flag=wx.ALIGN_CENTER_VERTICAL)
  871. # position
  872. self.win['settings']['view']['pos'] = {}
  873. posvals = UserSettings.Get(group='nviz', key='view', subkey='pos')
  874. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  875. label=_("Position") + " (x):"),
  876. pos=(1, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  877. px = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  878. initial=posvals['x'] * 100,
  879. min=0,
  880. max=100)
  881. self.win['settings']['view']['pos']['x'] = px.GetId()
  882. gridSizer.Add(item=px, pos=(1, 1),
  883. flag=wx.ALIGN_CENTER_VERTICAL)
  884. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  885. label="(y):"),
  886. pos=(1, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  887. py = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  888. initial=posvals['y'] * 100,
  889. min=0,
  890. max=100)
  891. self.win['settings']['view']['pos']['y'] = py.GetId()
  892. gridSizer.Add(item=py, pos=(1, 3),
  893. flag=wx.ALIGN_CENTER_VERTICAL)
  894. # height
  895. self.win['settings']['view']['height'] = {}
  896. hvals = UserSettings.Get(group='nviz', key='view', subkey='height')
  897. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  898. label=_("Height") + " (min):"),
  899. pos=(2, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  900. hmin = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  901. initial=hvals['min'],
  902. min=-1e6,
  903. max=1e6)
  904. self.win['settings']['view']['height']['min'] = hmin.GetId()
  905. gridSizer.Add(item=hmin, pos=(2, 1),
  906. flag=wx.ALIGN_CENTER_VERTICAL)
  907. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  908. label="(max):"),
  909. pos=(2, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  910. hmax = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  911. initial=hvals['max'],
  912. min=-1e6,
  913. max=1e6)
  914. self.win['settings']['view']['height']['max'] = hmax.GetId()
  915. gridSizer.Add(item=hmax, pos=(2, 3),
  916. flag=wx.ALIGN_CENTER_VERTICAL)
  917. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  918. label="(step):"),
  919. pos=(2, 4), flag=wx.ALIGN_CENTER_VERTICAL)
  920. hstep = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  921. initial=hvals['step'],
  922. min=1,
  923. max=hvals['max']-1)
  924. self.win['settings']['view']['height']['step'] = hstep.GetId()
  925. gridSizer.Add(item=hstep, pos=(2, 5),
  926. flag=wx.ALIGN_CENTER_VERTICAL)
  927. # twist
  928. self.win['settings']['view']['twist'] = {}
  929. tvals = UserSettings.Get(group='nviz', key='view', subkey='twist')
  930. itvals = UserSettings.Get(group='nviz', key='view', subkey='twist', internal=True)
  931. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  932. label=_("Twist (value):")),
  933. pos=(3, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  934. tval = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  935. initial=tvals['value'],
  936. min=itvals['min'],
  937. max=itvals['max'])
  938. self.win['settings']['view']['twist']['value'] = tval.GetId()
  939. gridSizer.Add(item=tval, pos=(3, 1),
  940. flag=wx.ALIGN_CENTER_VERTICAL)
  941. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  942. label=_("(step):")),
  943. pos=(3, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  944. tstep = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  945. initial=tvals['step'],
  946. min=itvals['min'],
  947. max=itvals['max']-1)
  948. self.win['settings']['view']['twist']['step'] = tstep.GetId()
  949. gridSizer.Add(item=tstep, pos=(3, 3),
  950. flag=wx.ALIGN_CENTER_VERTICAL)
  951. # z-exag
  952. self.win['settings']['view']['z-exag'] = {}
  953. zvals = UserSettings.Get(group='nviz', key='view', subkey='z-exag')
  954. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  955. label=_("Z-exag (value):")),
  956. pos=(4, 0), flag=wx.ALIGN_CENTER_VERTICAL)
  957. zval = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  958. initial=zvals['value'],
  959. min=-1e6,
  960. max=1e6)
  961. self.win['settings']['view']['z-exag']['value'] = zval.GetId()
  962. gridSizer.Add(item=zval, pos=(4, 1),
  963. flag=wx.ALIGN_CENTER_VERTICAL)
  964. gridSizer.Add(item=wx.StaticText(parent=panel, id=wx.ID_ANY,
  965. label=_("(step):")),
  966. pos=(4, 2), flag=wx.ALIGN_CENTER_VERTICAL)
  967. zstep = wx.SpinCtrl(parent=panel, id=wx.ID_ANY, size=(65, -1),
  968. initial=zvals['step'],
  969. min=-1e6,
  970. max=1e6)
  971. self.win['settings']['view']['z-exag']['step'] = zstep.GetId()
  972. gridSizer.Add(item=zstep, pos=(4, 3),
  973. flag=wx.ALIGN_CENTER_VERTICAL)
  974. boxSizer.Add(item=gridSizer, proportion=1,
  975. flag=wx.ALL | wx.EXPAND, border=3)
  976. pageSizer.Add(item=boxSizer, proportion=0,
  977. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  978. border=5)
  979. #
  980. # surface
  981. #
  982. self.win['settings']['surface'] = {}
  983. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  984. label=" %s " % (_("Surface")))
  985. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  986. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  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. #
  993. # vector
  994. #
  995. self.win['settings']['vector'] = {}
  996. box = wx.StaticBox (parent=panel, id=wx.ID_ANY,
  997. label=" %s " % (_("Vector")))
  998. boxSizer = wx.StaticBoxSizer(box, wx.VERTICAL)
  999. gridSizer = wx.GridBagSizer(vgap=3, hgap=3)
  1000. boxSizer.Add(item=gridSizer, proportion=1,
  1001. flag=wx.ALL | wx.EXPAND, border=3)
  1002. pageSizer.Add(item=boxSizer, proportion=0,
  1003. flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM,
  1004. border=5)
  1005. #
  1006. # buttons
  1007. #
  1008. btnDefault = wx.Button(panel, wx.ID_CANCEL, label=_("Default"))
  1009. btnSave = wx.Button(panel, wx.ID_SAVE)
  1010. btnApply = wx.Button(panel, wx.ID_APPLY)
  1011. btnDefault.Bind(wx.EVT_BUTTON, self.OnDefault)
  1012. btnDefault.SetToolTipString(_("Restore default settings"))
  1013. btnApply.Bind(wx.EVT_BUTTON, self.OnApply)
  1014. btnApply.SetToolTipString(_("Apply changes for the current session"))
  1015. btnSave.Bind(wx.EVT_BUTTON, self.OnSave)
  1016. btnSave.SetToolTipString(_("Apply and save changes to user settings file (default for next sessions)"))
  1017. btnSave.SetDefault()
  1018. btnSizer = wx.StdDialogButtonSizer()
  1019. btnSizer.AddButton(btnDefault)
  1020. btnSizer.AddButton(btnApply)
  1021. btnSizer.AddButton(btnSave)
  1022. btnSizer.Realize()
  1023. pageSizer.Add(item=btnSizer, proportion=1,
  1024. flag=wx.EXPAND | wx.ALL | wx.ALIGN_RIGHT | wx.ALIGN_BOTTOM,
  1025. border=5)
  1026. panel.SetSizer(pageSizer)
  1027. def CreateControl(self, parent, dict, name, range, bind, sliderHor=True, size=200):
  1028. """Add control (Slider + SpinCtrl)"""
  1029. dict[name] = {}
  1030. if sliderHor:
  1031. style = wx.SL_HORIZONTAL | wx.SL_AUTOTICKS | \
  1032. wx.SL_BOTTOM
  1033. sizeW = (size, -1)
  1034. else:
  1035. style = wx.SL_VERTICAL | wx.SL_AUTOTICKS | \
  1036. wx.SL_BOTTOM | wx.SL_INVERSE
  1037. sizeW = (-1, size)
  1038. try:
  1039. val = self.mapWindow.view[name]['value']
  1040. except KeyError:
  1041. val=-1
  1042. slider = wx.Slider(parent=parent, id=wx.ID_ANY,
  1043. value=val,
  1044. minValue=range[0],
  1045. maxValue=range[1],
  1046. style=style,
  1047. size=sizeW)
  1048. slider.SetName('slider')
  1049. slider.Bind(wx.EVT_SCROLL, bind[0])
  1050. slider.Bind(wx.EVT_SCROLL_CHANGED, bind[1])
  1051. dict[name]['slider'] = slider.GetId()
  1052. spin = wx.SpinCtrl(parent=parent, id=wx.ID_ANY, size=(65, -1),
  1053. initial=val,
  1054. min=range[0],
  1055. max=range[1])
  1056. # spin = wx.SpinButton(parent=parent, id=wx.ID_ANY)
  1057. # spin.SetValue (self.mapWindow.view[name]['value'])
  1058. # spin.SetRange(self.mapWindow.view[name]['min'],
  1059. # self.mapWindow.view[name]['max'])
  1060. # no 'changed' event ... (FIXME)
  1061. spin.SetName('spin')
  1062. spin.Bind(wx.EVT_SPINCTRL, bind[2])
  1063. dict[name]['spin'] = spin.GetId()
  1064. def UpdateSettings(self):
  1065. """Update dialog settings"""
  1066. for control in ('height',
  1067. 'persp',
  1068. 'twist',
  1069. 'z-exag'):
  1070. for win in self.win['view'][control].itervalues():
  1071. if control == 'height':
  1072. value = UserSettings.Get(group='nviz', key='view',
  1073. subkey=['height', 'value'], internal=True)
  1074. else:
  1075. value = self.mapWindow.view[control]['value']
  1076. self.FindWindowById(win).SetValue(value)
  1077. self.FindWindowById(self.win['view']['pos']).Draw()
  1078. self.FindWindowById(self.win['view']['pos']).Refresh(False)
  1079. self.Refresh(False)
  1080. def __GetWindowName(self, dict, id):
  1081. for name in dict.iterkeys():
  1082. if type(dict[name]) is type({}):
  1083. for win in dict[name].itervalues():
  1084. if win == id:
  1085. return name
  1086. else:
  1087. if dict[name] == id:
  1088. return name
  1089. return None
  1090. def OnViewChange(self, event):
  1091. """Change view, render in quick mode"""
  1092. # find control
  1093. winName = self.__GetWindowName(self.win['view'], event.GetId())
  1094. if not winName:
  1095. return
  1096. if winName == 'height':
  1097. view = self.mapWindow.iview # internal
  1098. else:
  1099. view = self.mapWindow.view
  1100. view[winName]['value'] = event.GetInt()
  1101. for win in self.win['view'][winName].itervalues():
  1102. self.FindWindowById(win).SetValue(view[winName]['value'])
  1103. self.mapWindow.update['view'] = (winName, )
  1104. self.mapWindow.render = False
  1105. self.mapWindow.Refresh(False)
  1106. def OnViewChanged(self, event):
  1107. """View changed, render in full resolution"""
  1108. self.mapWindow.render = True
  1109. self.mapWindow.Refresh(False)
  1110. def OnViewChangedSpin(self, event):
  1111. """View changed, render in full resolution"""
  1112. # TODO: use step value instead
  1113. self.OnViewChange(event)
  1114. self.OnViewChanged(None)
  1115. def OnResetView(self, event):
  1116. """Reset to default view (view page)"""
  1117. self.mapWindow.ResetView()
  1118. self.UpdateSettings()
  1119. self.mapWindow.Refresh(False)
  1120. def OnLookAt(self, event):
  1121. """Look at (view page)"""
  1122. sel = event.GetSelection()
  1123. if sel == 0: # top
  1124. self.mapWindow.view['pos']['x'] = 0.5
  1125. self.mapWindow.view['pos']['y'] = 0.5
  1126. elif sel == 1: # north
  1127. self.mapWindow.view['pos']['x'] = 0.5
  1128. self.mapWindow.view['pos']['y'] = 0.0
  1129. elif sel == 2: # south
  1130. self.mapWindow.view['pos']['x'] = 0.5
  1131. self.mapWindow.view['pos']['y'] = 1.0
  1132. elif sel == 3: # east
  1133. self.mapWindow.view['pos']['x'] = 1.0
  1134. self.mapWindow.view['pos']['y'] = 0.5
  1135. elif sel == 4: # west
  1136. self.mapWindow.view['pos']['x'] = 0.0
  1137. self.mapWindow.view['pos']['y'] = 0.5
  1138. elif sel == 5: # north-west
  1139. self.mapWindow.view['pos']['x'] = 0.0
  1140. self.mapWindow.view['pos']['y'] = 0.0
  1141. elif sel == 6: # north-east
  1142. self.mapWindow.view['pos']['x'] = 1.0
  1143. self.mapWindow.view['pos']['y'] = 0.0
  1144. elif sel == 7: # south-east
  1145. self.mapWindow.view['pos']['x'] = 1.0
  1146. self.mapWindow.view['pos']['y'] = 1.0
  1147. elif sel == 8: # south-west
  1148. self.mapWindow.view['pos']['x'] = 0.0
  1149. self.mapWindow.view['pos']['y'] = 1.0
  1150. self.mapWindow.update['view'] = ('pos', )
  1151. self.UpdateSettings()
  1152. self.mapWindow.Refresh(False)
  1153. def OnDefault(self, event):
  1154. """Restore default settings"""
  1155. settings = copy.deepcopy(UserSettings.GetDefaultSettings()['nviz'])
  1156. UserSettings.Set(group='nviz',
  1157. value=settings)
  1158. for subgroup, key in settings.iteritems(): # view, surface, vector...
  1159. if subgroup != 'view':
  1160. continue
  1161. for subkey, value in key.iteritems():
  1162. for subvalue in value.keys():
  1163. win = self.FindWindowById(self.win['settings'][subgroup][subkey][subvalue])
  1164. val = settings[subgroup][subkey][subvalue]
  1165. if subkey == 'pos':
  1166. val = int(val * 100)
  1167. win.SetValue(val)
  1168. event.Skip()
  1169. def OnApply(self, event):
  1170. """Apply button pressed"""
  1171. if self.notebook.GetSelection() == self.page['settings']:
  1172. self.ApplySettings()
  1173. if event:
  1174. event.Skip()
  1175. def ApplySettings(self):
  1176. """Apply Nviz settings for current session"""
  1177. settings = UserSettings.Get(group='nviz')
  1178. for subgroup, key in settings.iteritems(): # view, surface, vector...
  1179. if subgroup != 'view':
  1180. continue
  1181. for subkey, value in key.iteritems():
  1182. for subvalue in value.keys():
  1183. value = self.FindWindowById(self.win['settings'][subgroup][subkey][subvalue]).GetValue()
  1184. if subkey == 'pos':
  1185. value = float(value) / 100
  1186. settings[subgroup][subkey][subvalue] = value
  1187. def OnSave(self, event):
  1188. """OK button pressed
  1189. Apply changes, update map and save settings of selected layer
  1190. """
  1191. #
  1192. # apply changes
  1193. #
  1194. self.OnApply(None)
  1195. if self.notebook.GetSelection() == self.page['settings']:
  1196. fileSettings = {}
  1197. UserSettings.ReadSettingsFile(settings=fileSettings)
  1198. fileSettings['nviz'] = UserSettings.Get(group='nviz')
  1199. file = UserSettings.SaveToFile(fileSettings)
  1200. self.lmgr.goutput.WriteLog(_('Nviz settings saved to file <%s>.') % file)
  1201. def UpdateLayerProperties(self):
  1202. """Update data layer properties"""
  1203. mapLayer = self.mapWindow.GetSelectedLayer()
  1204. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1205. id = self.mapWindow.GetMapObjId(mapLayer)
  1206. if mapLayer.type == 'raster':
  1207. self.UpdateRasterProperties(id, data)
  1208. # reset updates
  1209. for sec in self.mapWindow.update['surface'].keys():
  1210. self.mapWindow.update['surface'][sec] = {}
  1211. elif mapLayer.type == 'vector':
  1212. self.UpdateVectorProperties(id, data)
  1213. # reset updates
  1214. for sec in self.mapWindow.update['vector'].keys():
  1215. self.mapWindow.update['vector'][sec] = {}
  1216. print self.mapWindow.GetSelectedLayer(nviz=True)
  1217. def UpdateRasterProperties(self, id, data):
  1218. """Apply changes for surfaces"""
  1219. # surface attributes
  1220. for attrb in ('topo', 'color', 'mask',
  1221. 'transp', 'shine', 'emit'):
  1222. if self.mapWindow.update['surface']['attribute'].has_key(attrb):
  1223. map = self.mapWindow.update['surface']['attribute'][attrb]['map']
  1224. value = self.mapWindow.update['surface']['attribute'][attrb]['value']
  1225. if map is None: # unset
  1226. # only optional attributes
  1227. if attrb == 'mask':
  1228. # TODO: invert mask
  1229. # TODO: broken in NVIZ
  1230. self.mapWindow.nvizClass.UnsetSurfaceMask(id)
  1231. elif attrb == 'transp':
  1232. self.mapWindow.nvizClass.UnsetSurfaceTransp(id)
  1233. elif attrb == 'emit':
  1234. self.mapWindow.nvizClass.UnsetSurfaceEmit(id)
  1235. else:
  1236. if len(value) <= 0: # ignore empty values (TODO: warning)
  1237. continue
  1238. if attrb == 'topo':
  1239. self.mapWindow.nvizClass.SetSurfaceTopo(id, map, str(value))
  1240. elif attrb == 'color':
  1241. self.mapWindow.nvizClass.SetSurfaceColor(id, map, str(value))
  1242. elif attrb == 'mask':
  1243. # TODO: invert mask
  1244. # TODO: broken in NVIZ
  1245. self.mapWindow.nvizClass.SetSurfaceMask(id, False, str(value))
  1246. elif attrb == 'transp':
  1247. self.mapWindow.nvizClass.SetSurfaceTransp(id, map, str(value))
  1248. elif attrb == 'shine':
  1249. self.mapWindow.nvizClass.SetSurfaceShine(id, map, str(value))
  1250. elif attrb == 'emit':
  1251. self.mapWindow.nvizClass.SetSurfaceEmit(id, map, str(value))
  1252. # draw res
  1253. if self.mapWindow.update['surface']['draw'].has_key('resolution'):
  1254. coarse, fine, all = self.mapWindow.update['surface']['draw']['resolution']
  1255. if all:
  1256. self.mapWindow.nvizClass.SetSurfaceRes(-1, fine, coarse)
  1257. else:
  1258. self.mapWindow.nvizClass.SetSurfaceRes(id, fine, coarse)
  1259. # draw style
  1260. if self.mapWindow.update['surface']['draw'].has_key('mode'):
  1261. style, all = self.mapWindow.update['surface']['draw']['mode']
  1262. if all:
  1263. self.mapWindow.nvizClass.SetSurfaceStyle(-1, style)
  1264. else:
  1265. self.mapWindow.nvizClass.SetSurfaceStyle(id, style)
  1266. # wire color
  1267. if self.mapWindow.update['surface']['draw'].has_key('color'):
  1268. color, all = self.mapWindow.update['surface']['draw']['color']
  1269. if all:
  1270. self.mapWindow.nvizClass.SetWireColor(id, str(color))
  1271. else:
  1272. self.mapWindow.nvizClass.SetWireColor(-1, str(color))
  1273. # position
  1274. if self.mapWindow.update['surface']['position'].has_key('coords'):
  1275. axis, value = self.mapWindow.update['surface']['position']['coords']
  1276. x, y, z = self.mapWindow.nvizClass.GetSurfacePosition(id)
  1277. if axis == 0:
  1278. x = value
  1279. elif axis == 1:
  1280. y = value
  1281. else:
  1282. z = value
  1283. self.mapWindow.update['surface']['position']['coords'] = (x, y, z)
  1284. self.mapWindow.nvizClass.SetSurfacePosition(id, x, y, z)
  1285. # update properties
  1286. for sec in self.mapWindow.update['surface'].keys():
  1287. if not data.has_key(sec):
  1288. data[sec] = {}
  1289. for prop in self.mapWindow.update['surface'][sec].keys():
  1290. data[sec][prop] = self.mapWindow.update['surface'][sec][prop]
  1291. def UpdateVectorProperties(self, id, data):
  1292. """Apply changes for vector"""
  1293. if self.mapWindow.update['vector']['lines'].has_key('mode'):
  1294. attrb = self.mapWindow.update['vector']['lines']['mode']
  1295. self.mapWindow.nvizClass.SetVectorLineMode(id, attrb['color'],
  1296. attrb['width'], attrb['flat'][0])
  1297. if self.mapWindow.update['vector']['lines'].has_key('height'):
  1298. height = self.mapWindow.update['vector']['lines']['height']
  1299. self.mapWindow.nvizClass.SetVectorHeight(id, height)
  1300. # update properties
  1301. for sec in self.mapWindow.update['vector'].keys():
  1302. if not data.has_key(sec):
  1303. data[sec] = {}
  1304. for prop in self.mapWindow.update['vector'][sec].keys():
  1305. data[sec][prop] = self.mapWindow.update['vector'][sec][prop]
  1306. def OnBgColor(self, event):
  1307. """Background color changed"""
  1308. color = event.GetValue()
  1309. color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  1310. self.mapWindow.nvizClass.SetBgColor(str(color))
  1311. if self.parent.autoRender.IsChecked():
  1312. self.mapWindow.Refresh(False)
  1313. def OnClose(self, event):
  1314. """Close button pressed
  1315. Close dialog
  1316. """
  1317. self.Hide()
  1318. def OnSurfaceUse(self, event):
  1319. """Surface attribute -- use -- map/constant"""
  1320. if not self.mapWindow.init:
  1321. return
  1322. # find attribute row
  1323. attrb = self.__GetWindowName(self.win['surface'], event.GetId())
  1324. if not attrb:
  1325. return
  1326. # reset updates
  1327. self.mapWindow.update['surface']['attribute'] = {}
  1328. selection = event.GetSelection()
  1329. if self.win['surface'][attrb]['required']: # no 'unset'
  1330. selection += 1
  1331. if selection == 0: # unset
  1332. useMap = None
  1333. value = ''
  1334. elif selection == 1: # map
  1335. useMap = True
  1336. value = self.FindWindowById(self.win['surface'][attrb]['map']).GetValue()
  1337. elif selection == 2: # constant
  1338. useMap = False
  1339. if attrb == 'color':
  1340. value = self.FindWindowById(self.win['surface'][attrb]['const']).GetColour()
  1341. value = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
  1342. else:
  1343. value = self.FindWindowById(self.win['surface'][attrb]['const']).GetValue()
  1344. self.SetSurfaceUseMap(attrb, useMap)
  1345. self.mapWindow.update['surface']['attribute'][attrb] = { 'map' : useMap,
  1346. 'value' : str(value),
  1347. }
  1348. self.UpdateLayerProperties()
  1349. if self.parent.autoRender.IsChecked():
  1350. self.mapWindow.Refresh(False)
  1351. def SetSurfaceUseMap(self, attrb, map=None):
  1352. if attrb in ('topo', 'color', 'shine'):
  1353. incSel = -1 # decrement selection (no 'unset')
  1354. else:
  1355. incSel = 0
  1356. if map is True: # map
  1357. if attrb != 'topo': # changing map topography not allowed
  1358. self.FindWindowById(self.win['surface'][attrb]['map'] + 1).Enable(True) # FIXME
  1359. if self.win['surface'][attrb]['const']:
  1360. self.FindWindowById(self.win['surface'][attrb]['const']).Enable(False)
  1361. self.FindWindowById(self.win['surface'][attrb]['use']).SetSelection(1 + incSel)
  1362. elif map is False: # const
  1363. self.FindWindowById(self.win['surface'][attrb]['map'] + 1).Enable(False)
  1364. if self.win['surface'][attrb]['const']:
  1365. self.FindWindowById(self.win['surface'][attrb]['const']).Enable(True)
  1366. self.FindWindowById(self.win['surface'][attrb]['use']).SetSelection(2 + incSel)
  1367. else: # unset
  1368. self.FindWindowById(self.win['surface'][attrb]['map'] + 1).Enable(False)
  1369. if self.win['surface'][attrb]['const']:
  1370. self.FindWindowById(self.win['surface'][attrb]['const']).Enable(False)
  1371. self.FindWindowById(self.win['surface'][attrb]['use']).SetSelection(0)
  1372. def OnSurfaceMap(self, event):
  1373. """Set surface attribute"""
  1374. if not self.mapWindow.init:
  1375. return
  1376. attrb = self.__GetWindowName(self.win['surface'], event.GetId())
  1377. if not attrb:
  1378. return
  1379. selection = self.FindWindowById(self.win['surface'][attrb]['use']).GetSelection()
  1380. if self.win['surface'][attrb]['required']:
  1381. selection += 1
  1382. if selection == 0: # unset
  1383. map = None
  1384. value = ''
  1385. elif selection == 1: # map
  1386. value = self.FindWindowById(self.win['surface'][attrb]['map']).GetValue()
  1387. map = True
  1388. else: # constant
  1389. if attrb == 'color':
  1390. value = self.FindWindowById(self.win['surface'][attrb]['const']).GetColour()
  1391. value = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
  1392. else:
  1393. value = self.FindWindowById(self.win['surface'][attrb]['const']).GetValue()
  1394. map = False
  1395. if self.pageUpdated: # do not update when selection is changed
  1396. self.mapWindow.update['surface']['attribute'][attrb] = { 'map' : map,
  1397. 'value' : str(value),
  1398. }
  1399. self.UpdateLayerProperties()
  1400. if self.parent.autoRender.IsChecked():
  1401. self.mapWindow.Refresh(False)
  1402. def OnSurfaceResolution(self, event):
  1403. """Draw resolution changed"""
  1404. self.SetSurfaceResolution()
  1405. if apply and self.parent.autoRender.IsChecked():
  1406. self.mapWindow.Refresh(False)
  1407. def SetSurfaceResolution(self, all=False):
  1408. """Set draw resolution"""
  1409. coarse = self.FindWindowById(self.win['surface']['draw']['res-coarse']).GetValue()
  1410. fine = self.FindWindowById(self.win['surface']['draw']['res-fine']).GetValue()
  1411. # reset updates
  1412. self.mapWindow.update['surface']['draw'] = {}
  1413. self.mapWindow.update['surface']['draw']['resolution'] = (coarse, fine, all)
  1414. self.UpdateLayerProperties()
  1415. def SetSurfaceMode(self, all=False):
  1416. """Set draw mode
  1417. @param apply allow auto-rendering
  1418. """
  1419. value = 0
  1420. mode = self.FindWindowById(self.win['surface']['draw']['mode']).GetSelection()
  1421. if mode == 0: # coarse
  1422. value |= wxnviz.DM_WIRE
  1423. self.FindWindowById(self.win['surface']['draw']['res-coarse']).Enable(True)
  1424. self.FindWindowById(self.win['surface']['draw']['res-fine']).Enable(False)
  1425. elif mode == 1: # fine
  1426. value |= wxnviz.DM_POLY
  1427. self.FindWindowById(self.win['surface']['draw']['res-coarse']).Enable(False)
  1428. self.FindWindowById(self.win['surface']['draw']['res-fine']).Enable(True)
  1429. else: # both
  1430. value |= wxnviz.DM_WIRE_POLY
  1431. self.FindWindowById(self.win['surface']['draw']['res-coarse']).Enable(True)
  1432. self.FindWindowById(self.win['surface']['draw']['res-fine']).Enable(True)
  1433. style = self.FindWindowById(self.win['surface']['draw']['style']).GetSelection()
  1434. if style == 0: # wire
  1435. value |= wxnviz.DM_GRID_WIRE
  1436. else: # surface
  1437. value |= wxnviz.DM_GRID_SURF
  1438. shade = self.FindWindowById(self.win['surface']['draw']['shading']).GetSelection()
  1439. if shade == 0:
  1440. value |= wxnviz.DM_FLAT
  1441. else: # surface
  1442. value |= wxnviz.DM_GOURAUD
  1443. if self.pageUpdated:
  1444. # reset updates
  1445. self.mapWindow.update['surface']['draw'] = {}
  1446. self.mapWindow.update['surface']['draw']['mode'] = (value, all)
  1447. self.UpdateLayerProperties()
  1448. def OnSurfaceMode(self, event):
  1449. """Set draw mode"""
  1450. self.SetSurfaceMode()
  1451. if apply and self.parent.autoRender.IsChecked():
  1452. self.mapWindow.Refresh(False)
  1453. def OnSurfaceModeAll(self, event):
  1454. """Set draw mode (including wire color) for all loaded surfaces"""
  1455. self.SetSurfaceMode(all=True)
  1456. self.SetSurfaceResolution(all=True)
  1457. color = self.FindWindowById(self.win['surface']['draw']['color']).GetColour()
  1458. self.SetSurfaceWireColor(color, all=True)
  1459. if apply and self.parent.autoRender.IsChecked():
  1460. self.mapWindow.Refresh(False)
  1461. def SetSurfaceWireColor(self, color, all=False, apply=True):
  1462. """Set wire color"""
  1463. value = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  1464. if self.pageUpdated:
  1465. # reset updates
  1466. self.mapWindow.update['surface']['draw'] = {}
  1467. self.mapWindow.update['surface']['draw']['color'] = (value, all)
  1468. self.UpdateLayerProperties()
  1469. def OnSurfaceWireColor(self, event):
  1470. """Set wire color"""
  1471. self.SetSurfaceWireColor(event.GetValue())
  1472. if self.parent.autoRender.IsChecked():
  1473. self.mapWindow.Refresh(False)
  1474. def OnSurfaceAxis(self, event):
  1475. """Surface position, axis changed"""
  1476. mapLayer = self.mapWindow.GetSelectedLayer()
  1477. id = self.mapWindow.GetMapObjId(mapLayer)
  1478. axis = self.FindWindowById(self.win['surface']['position']['axis']).GetSelection()
  1479. win = self.FindWindowById(self.win['surface']['position']['pos'])
  1480. x, y, z = self.mapWindow.nvizClass.GetSurfacePosition(id)
  1481. if axis == 0: # x
  1482. win.SetRange(-1e4, 1e4)
  1483. win.SetValue(x)
  1484. elif axis == 1: # y
  1485. win.SetRange(-1e4, 1e4)
  1486. win.SetValue(y)
  1487. else: # z
  1488. win.SetRange(-1e3, 1e3)
  1489. win.SetValue(z)
  1490. def OnSurfacePosition(self, event):
  1491. """Surface position"""
  1492. axis = self.FindWindowById(self.win['surface']['position']['axis']).GetSelection()
  1493. value = event.GetInt()
  1494. self.mapWindow.update['surface']['position'] = {}
  1495. self.mapWindow.update['surface']['position']['coords'] = (axis, value)
  1496. self.UpdateLayerProperties()
  1497. if self.parent.autoRender.IsChecked():
  1498. self.mapWindow.Refresh(False)
  1499. def OnVectorDisplay(self, event):
  1500. """Display vector lines on surface/flat"""
  1501. if event.GetSelection() == 0: # surface
  1502. self.FindWindowById(self.win['vector']['lines']['surface']).Enable(True)
  1503. # set first found surface
  1504. ### TODO
  1505. else: # flat
  1506. self.FindWindowById(self.win['vector']['lines']['surface']).Enable(False)
  1507. self.OnVectorLines(event)
  1508. event.Skip()
  1509. def OnVectorLines(self, event):
  1510. """Set vector lines mode, apply changes if auto-rendering is enabled"""
  1511. width = self.FindWindowById(self.win['vector']['lines']['width']).GetValue()
  1512. color = self.FindWindowById(self.win['vector']['lines']['color']).GetColour()
  1513. color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  1514. if self.FindWindowById(self.win['vector']['lines']['flat']).GetSelection() == 0:
  1515. flat = False
  1516. map = ''
  1517. else:
  1518. flat = True
  1519. map = ''
  1520. self.mapWindow.update['vector']['lines']['mode'] = { 'width' : width,
  1521. 'color' : color,
  1522. 'flat' : (flat, map)
  1523. }
  1524. self.UpdateLayerProperties()
  1525. if self.parent.autoRender.IsChecked():
  1526. self.mapWindow.Refresh(False)
  1527. def OnVectorHeight(self, event):
  1528. value = event.GetInt()
  1529. if type(event) == type(wx.ScrollEvent()):
  1530. # slider
  1531. win = self.FindWindowById(self.win['vector']['lines']['height']['spin'])
  1532. else:
  1533. # spin
  1534. win = self.FindWindowById(self.win['vector']['lines']['height']['slider'])
  1535. win.SetValue(value)
  1536. self.mapWindow.update['vector']['lines']['height'] = value
  1537. self.UpdateLayerProperties()
  1538. if self.parent.autoRender.IsChecked():
  1539. self.mapWindow.Refresh(False)
  1540. def UpdatePage(self, pageId):
  1541. """Update dialog (selected page)"""
  1542. self.pageUpdated = False
  1543. layer = self.mapWindow.GetSelectedLayer()
  1544. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1545. if pageId == 'view':
  1546. max = self.mapWindow.view['z-exag']['value'] * 10
  1547. for control in ('spin', 'slider'):
  1548. self.FindWindowById(self.win['view']['z-exag'][control]).SetRange(0,
  1549. max)
  1550. elif pageId == 'surface':
  1551. # disable vector and enable surface page
  1552. self.notebook.GetPage(self.page['surface']).Enable(True)
  1553. self.notebook.GetPage(self.page['vector']).Enable(False)
  1554. #
  1555. # set default values
  1556. #
  1557. # attributes
  1558. for attr in ('topo', 'color'): # required
  1559. if layer and layer.type == 'raster':
  1560. self.FindWindowById(self.win['surface'][attr]['map']).SetValue(layer.name)
  1561. else:
  1562. self.FindWindowById(self.win['surface'][attr]['map']).SetValue('')
  1563. self.SetSurfaceUseMap(attr, True) # -> map
  1564. if UserSettings.Get(group='nviz', key='surface', subkey=['shine', 'map']) is False:
  1565. self.SetSurfaceUseMap('shine', False)
  1566. value = UserSettings.Get(group='nviz', key='surface', subkey=['shine', 'value'])
  1567. self.FindWindowById(self.win['surface']['shine']['const']).SetValue(value)
  1568. #
  1569. # draw
  1570. #
  1571. for control, value in UserSettings.Get(group='nviz', key='surface', subkey='draw').iteritems():
  1572. win = self.FindWindowById(self.win['surface']['draw'][control])
  1573. name = win.GetName()
  1574. if name == "selection":
  1575. win.SetSelection(value)
  1576. elif name == "colour":
  1577. win.SetColour(value)
  1578. else:
  1579. win.SetValue(value)
  1580. # enable/disable res widget + set draw mode
  1581. self.SetSurfaceMode()
  1582. color = self.FindWindowById(self.win['surface']['draw']['color'])
  1583. self.SetSurfaceWireColor(color.GetColour())
  1584. if layer.type == 'raster':
  1585. surfProp = data['surface']
  1586. # surface attributes
  1587. for attr in surfProp['attribute'].iterkeys():
  1588. print attr
  1589. if surfProp['attribute'][attr]['map']:
  1590. win = self.FindWindowById(self.win['surface'][attr]['map'])
  1591. else:
  1592. win = self.FindWindowById(self.win['surface'][attr]['const'])
  1593. if attr == 'color':
  1594. color = tuple(map(int, surfProp['attribute'][attr]['value'].split(':')))
  1595. # TODO: save as tuple
  1596. win.SetColour(color)
  1597. else:
  1598. win.SetValue(surfProp['attribute'][attr]['value'])
  1599. elif pageId == 'vector':
  1600. # disable surface and enable current
  1601. self.notebook.GetPage(self.page['surface']).Enable(False)
  1602. self.notebook.GetPage(self.page['vector']).Enable(True)
  1603. if data is None: # defaut values
  1604. # lines
  1605. for name in ('width', 'color'):
  1606. win = self.FindWindowById(self.win['vector']['lines'][name])
  1607. win.SetValue(UserSettings.Get(group='nviz', key='vector',
  1608. subkey=['lines', name]))
  1609. display = self.FindWindowById(self.win['vector']['lines']['flat'])
  1610. if UserSettings.Get(group='nviz', key='vector',
  1611. subkey=['lines', 'flat']):
  1612. display.SetSelection(1)
  1613. else:
  1614. display.SetSelection(0)
  1615. value = UserSettings.Get(group='nviz', key='vector',
  1616. subkey=['lines', 'height'])
  1617. for type in ('slider', 'spin'):
  1618. win = self.FindWindowById(self.win['vector']['lines']['height'][type])
  1619. win.SetValue(value)
  1620. self.pageUpdated = True
  1621. def SetPage(self, name):
  1622. """Get named page"""
  1623. self.notebook.SetSelection(self.page[name])
  1624. class ViewPositionWindow(wx.Window):
  1625. """Position control window (for NvizToolWindow)"""
  1626. def __init__(self, parent, id, mapwindow,
  1627. pos=wx.DefaultPosition,
  1628. size=wx.DefaultSize):
  1629. self.mapWindow = mapwindow
  1630. wx.Window.__init__(self, parent, id, pos, size)
  1631. self.SetBackgroundColour("WHITE")
  1632. self.pdc = wx.PseudoDC()
  1633. self.pdc.SetBrush(wx.Brush(colour='dark green', style=wx.SOLID))
  1634. self.pdc.SetPen(wx.Pen(colour='dark green', width=2, style=wx.SOLID))
  1635. self.Draw()
  1636. self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x: None)
  1637. self.Bind(wx.EVT_PAINT, self.OnPaint)
  1638. # self.Bind(wx.EVT_MOTION, self.OnMouse)
  1639. self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse)
  1640. def Draw(self, pos=None):
  1641. w, h = self.GetClientSize()
  1642. if pos is None:
  1643. x = self.mapWindow.view['pos']['x']
  1644. y = self.mapWindow.view['pos']['y']
  1645. x = x * w
  1646. y = y * h
  1647. else:
  1648. x, y = pos
  1649. self.pdc.Clear()
  1650. self.pdc.BeginDrawing()
  1651. self.pdc.DrawLine(w / 2, h / 2, x, y)
  1652. self.pdc.DrawCircle(x, y, 5)
  1653. self.pdc.EndDrawing()
  1654. def OnPaint(self, event):
  1655. dc = wx.BufferedPaintDC(self)
  1656. dc.SetBackground(wx.Brush("White"))
  1657. dc.Clear()
  1658. self.PrepareDC(dc)
  1659. self.pdc.DrawToDC(dc)
  1660. def OnMouse(self, event):
  1661. if event.LeftIsDown():
  1662. x, y = event.GetPosition()
  1663. self.Draw(pos=(x, y))
  1664. self.Refresh(False)
  1665. w, h = self.GetClientSize()
  1666. x = float(x) / w
  1667. y = float(y) / h
  1668. if x >= 0 and x <= 1.0:
  1669. self.mapWindow.view['pos']['x'] = x
  1670. if y >= 0 and y <= 1.0:
  1671. self.mapWindow.view['pos']['y'] = y
  1672. self.mapWindow.update['view'] = ('pos', )
  1673. self.mapWindow.render = False
  1674. if event.LeftUp():
  1675. self.mapWindow.render = True
  1676. self.mapWindow.Refresh(eraseBackground=False)