nviz.py 99 KB

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