nviz.py 73 KB

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