nviz.py 77 KB

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