nviz.py 78 KB

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