nviz.py 78 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022
  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.lmgr = self.parent.gismanager # GMFrame
  333. self.mapWindow = mapWindow
  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. 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.mapWindow.view['height']['min'], self.mapWindow.view['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.mapWindow.view[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.mapWindow.view[name]['value'])
  1060. # spin.SetRange(self.mapWindow.view[name]['min'],
  1061. # self.mapWindow.view[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.mapWindow.view[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.mapWindow.view[winName]['value'] = event.GetInt()
  1099. for win in self.win['view'][winName].itervalues():
  1100. self.FindWindowById(win).SetValue(self.mapWindow.view[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.mapWindow.view['pos']['x'] = 0.5
  1125. self.mapWindow.view['pos']['y'] = 0.5
  1126. elif sel == 1: # north
  1127. self.mapWindow.view['pos']['x'] = 0.5
  1128. self.mapWindow.view['pos']['y'] = 0.0
  1129. elif sel == 2: # south
  1130. self.mapWindow.view['pos']['x'] = 0.5
  1131. self.mapWindow.view['pos']['y'] = 1.0
  1132. elif sel == 3: # east
  1133. self.mapWindow.view['pos']['x'] = 1.0
  1134. self.mapWindow.view['pos']['y'] = 0.5
  1135. elif sel == 4: # west
  1136. self.mapWindow.view['pos']['x'] = 0.0
  1137. self.mapWindow.view['pos']['y'] = 0.5
  1138. elif sel == 5: # north-west
  1139. self.mapWindow.view['pos']['x'] = 0.0
  1140. self.mapWindow.view['pos']['y'] = 0.0
  1141. elif sel == 6: # north-east
  1142. self.mapWindow.view['pos']['x'] = 1.0
  1143. self.mapWindow.view['pos']['y'] = 0.0
  1144. elif sel == 7: # south-east
  1145. self.mapWindow.view['pos']['x'] = 1.0
  1146. self.mapWindow.view['pos']['y'] = 1.0
  1147. elif sel == 8: # south-west
  1148. self.mapWindow.view['pos']['x'] = 0.0
  1149. self.mapWindow.view['pos']['y'] = 1.0
  1150. self.mapWindow.update['view'] = None
  1151. self.UpdateSettings()
  1152. self.mapWindow.Refresh(False)
  1153. def OnDefault(self, event):
  1154. """Restore default settings"""
  1155. settings = copy.deepcopy(UserSettings.GetDefaultSettings()['nviz'])
  1156. UserSettings.Set(group='nviz',
  1157. value=settings)
  1158. for subgroup, key in settings.iteritems(): # view, surface, vector...
  1159. if subgroup != 'view':
  1160. continue
  1161. for subkey, value in key.iteritems():
  1162. for subvalue in value.keys():
  1163. win = self.FindWindowById(self.win['settings'][subgroup][subkey][subvalue])
  1164. val = settings[subgroup][subkey][subvalue]
  1165. if subkey == 'pos':
  1166. val = int(val * 100)
  1167. win.SetValue(val)
  1168. event.Skip()
  1169. def OnApply(self, event):
  1170. """Apply button pressed"""
  1171. if self.notebook.GetSelection() == self.page['settings']:
  1172. self.ApplySettings()
  1173. if event:
  1174. event.Skip()
  1175. def ApplySettings(self):
  1176. """Apply Nviz settings for current session"""
  1177. settings = UserSettings.Get(group='nviz')
  1178. for subgroup, key in settings.iteritems(): # view, surface, vector...
  1179. if subgroup != 'view':
  1180. continue
  1181. for subkey, value in key.iteritems():
  1182. for subvalue in value.keys():
  1183. value = self.FindWindowById(self.win['settings'][subgroup][subkey][subvalue]).GetValue()
  1184. if subkey == 'pos':
  1185. value = float(value) / 100
  1186. settings[subgroup][subkey][subvalue] = value
  1187. def OnSave(self, event):
  1188. """OK button pressed
  1189. Apply changes, update map and save settings of selected layer
  1190. """
  1191. #
  1192. # apply changes
  1193. #
  1194. self.OnApply(None)
  1195. if self.notebook.GetSelection() == self.page['settings']:
  1196. fileSettings = {}
  1197. UserSettings.ReadSettingsFile(settings=fileSettings)
  1198. fileSettings['nviz'] = UserSettings.Get(group='nviz')
  1199. file = UserSettings.SaveToFile(fileSettings)
  1200. self.lmgr.goutput.WriteLog(_('Nviz settings saved to file <%s>.') % file)
  1201. # #
  1202. # # save settings
  1203. # #
  1204. # type = self.mapWindow.GetSelectedLayer().type
  1205. # data = self.mapWindow.GetSelectedLayer(nviz=True)
  1206. # if data is None: # no settings
  1207. # data = {}
  1208. # if type == 'raster': # -> surface
  1209. # #
  1210. # # surface attributes
  1211. # #
  1212. # data['attribute'] = {}
  1213. # for attrb in ('topo', 'color', 'mask',
  1214. # 'transp', 'shine', 'emit'):
  1215. # use = self.FindWindowById(self.win['surface'][attrb]['use']).GetSelection()
  1216. # if self.win['surface'][attrb]['required']: # map, constant
  1217. # if use == 0: # map
  1218. # map = True
  1219. # elif use == 1: # constant
  1220. # map = False
  1221. # else: # unset, map, constant
  1222. # if use == 0: # unset
  1223. # map = None
  1224. # elif use == 1: # map
  1225. # map = True
  1226. # elif use == 2: # constant
  1227. # map = False
  1228. # if map is None:
  1229. # continue
  1230. # if map:
  1231. # value = self.FindWindowById(self.win['surface'][attrb]['map']).GetValue()
  1232. # else:
  1233. # if attrb == 'color':
  1234. # value = self.FindWindowById(self.win['surface'][attrb]['map']).GetColour()
  1235. # else:
  1236. # value = self.FindWindowById(self.win['surface'][attrb]['const']).GetValue()
  1237. # data['attribute'][attrb] = {}
  1238. # data['attribute'][attrb]['map'] = map
  1239. # data['attribute'][attrb]['value'] = value
  1240. # #
  1241. # # draw
  1242. # #
  1243. # data['draw'] = {}
  1244. # for control in ('mode', 'shading', 'style'):
  1245. # data['draw'][control] = self.FindWindowById(self.win['surface']['draw'][control]).GetSelection()
  1246. # for control in ('res-coarse', 'res-fine'):
  1247. # data['draw'][control] = self.FindWindowById(self.win['surface']['draw'][control]).GetValue()
  1248. # self.mapWindow.SetLayerSettings(data)
  1249. def UpdateLayerProperties(self):
  1250. """Update data layer properties"""
  1251. mapLayer = self.mapWindow.GetSelectedLayer()
  1252. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1253. id = self.mapWindow.GetMapObjId(mapLayer)
  1254. if mapLayer.type == 'raster':
  1255. self.UpdateRasterProperties(id, data)
  1256. elif mapLayer.type == 'vector':
  1257. self.UpdateVectorProperties(id, data)
  1258. # reset
  1259. self.mapWindow.update = {}
  1260. # print self.mapWindow.GetSelectedLayer(nviz=True)
  1261. def UpdateRasterProperties(self, id, data):
  1262. """Apply changes for surfaces"""
  1263. # surface attributes
  1264. for attrb in ('topo', 'color', 'mask',
  1265. 'transp', 'shine', 'emit'):
  1266. if self.mapWindow.update.has_key(attrb):
  1267. map, value = self.mapWindow.update[attrb]
  1268. if map is None: # unset
  1269. # only optional attributes
  1270. if attrb == 'mask':
  1271. # TODO: invert mask
  1272. # TODO: broken in NVIZ
  1273. self.mapWindow.nvizClass.UnsetSurfaceMask(id)
  1274. elif attrb == 'transp':
  1275. self.mapWindow.nvizClass.UnsetSurfaceTransp(id)
  1276. elif attrb == 'emit':
  1277. self.mapWindow.nvizClass.UnsetSurfaceEmit(id)
  1278. else:
  1279. if len(value) <= 0: # ignore empty values (TODO: warning)
  1280. continue
  1281. if attrb == 'topo':
  1282. self.mapWindow.nvizClass.SetSurfaceTopo(id, map, str(value))
  1283. elif attrb == 'color':
  1284. self.mapWindow.nvizClass.SetSurfaceColor(id, map, str(value))
  1285. elif attrb == 'mask':
  1286. # TODO: invert mask
  1287. # TODO: broken in NVIZ
  1288. self.mapWindow.nvizClass.SetSurfaceMask(id, False, str(value))
  1289. elif attrb == 'transp':
  1290. self.mapWindow.nvizClass.SetSurfaceTransp(id, map, str(value))
  1291. elif attrb == 'shine':
  1292. self.mapWindow.nvizClass.SetSurfaceShine(id, map, str(value))
  1293. elif attrb == 'emit':
  1294. self.mapWindow.nvizClass.SetSurfaceEmit(id, map, str(value))
  1295. # draw res
  1296. if self.mapWindow.update.has_key('draw-res'):
  1297. coarse, fine, all = self.mapWindow.update['draw-res']
  1298. if all:
  1299. self.mapWindow.nvizClass.SetSurfaceRes(-1, fine, coarse)
  1300. else:
  1301. self.mapWindow.nvizClass.SetSurfaceRes(id, fine, coarse)
  1302. # draw style
  1303. if self.mapWindow.update.has_key('draw-style'):
  1304. style, all = self.mapWindow.update['draw-style']
  1305. if all:
  1306. self.mapWindow.nvizClass.SetSurfaceStyle(-1, style)
  1307. else:
  1308. self.mapWindow.nvizClass.SetSurfaceStyle(id, style)
  1309. # wire color
  1310. if self.mapWindow.update.has_key('draw-color'):
  1311. color, all = self.mapWindow.update['draw-color']
  1312. if all:
  1313. self.mapWindow.nvizClass.SetWireColor(id, str(color))
  1314. else:
  1315. self.mapWindow.nvizClass.SetWireColor(-1, str(color))
  1316. # position
  1317. if self.mapWindow.update.has_key('surface-position'):
  1318. axis, value = self.mapWindow.update['surface-position']
  1319. x, y, z = self.mapWindow.nvizClass.GetSurfacePosition(id)
  1320. if axis == 0:
  1321. x = value
  1322. elif axis == 1:
  1323. y = value
  1324. else:
  1325. z = value
  1326. self.mapWindow.nvizClass.SetSurfacePosition(id, x, y, z)
  1327. # update properties
  1328. for prop in self.mapWindow.update.keys():
  1329. data[prop] = self.mapWindow.update[prop]
  1330. def UpdateVectorProperties(self, id, data):
  1331. """Apply changes for vector"""
  1332. if self.mapWindow.update.has_key('vector-lines'):
  1333. width, color, flat = self.mapWindow.update['vector-lines']
  1334. self.mapWindow.nvizClass.SetVectorLineMode(id, color, width, flat)
  1335. if self.mapWindow.update.has_key('vector-height'):
  1336. height = self.mapWindow.update['vector-height']
  1337. self.mapWindow.nvizClass.SetVectorHeight(id, height)
  1338. # update properties
  1339. for prop in self.mapWindow.update.keys():
  1340. data[prop] = self.mapWindow.update[prop]
  1341. def OnBgColor(self, event):
  1342. """Background color changed"""
  1343. color = event.GetValue()
  1344. color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  1345. self.mapWindow.nvizClass.SetBgColor(str(color))
  1346. if self.parent.autoRender.IsChecked():
  1347. self.mapWindow.Refresh(False)
  1348. def OnClose(self, event):
  1349. """Close button pressed
  1350. Close dialog
  1351. """
  1352. self.Hide()
  1353. def OnSurfaceUse(self, event):
  1354. """Surface attribute -- use -- map/constant"""
  1355. if not self.mapWindow.init:
  1356. return
  1357. # find attribute row
  1358. attrb = self.__GetWindowName(self.win['surface'], event.GetId())
  1359. if not attrb:
  1360. return
  1361. selection = event.GetSelection()
  1362. if self.win['surface'][attrb]['required']: # no 'unset'
  1363. selection += 1
  1364. if selection == 0: # unset
  1365. useMap = None
  1366. value = ''
  1367. elif selection == 1: # map
  1368. useMap = True
  1369. value = self.FindWindowById(self.win['surface'][attrb]['map']).GetValue()
  1370. elif selection == 2: # constant
  1371. useMap = False
  1372. if attrb == 'color':
  1373. value = self.FindWindowById(self.win['surface'][attrb]['const']).GetColour()
  1374. value = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
  1375. else:
  1376. value = self.FindWindowById(self.win['surface'][attrb]['const']).GetValue()
  1377. self.SetSurfaceUseMap(attrb, useMap)
  1378. self.mapWindow.update[attrb] = (useMap, str(value))
  1379. self.UpdateLayerProperties()
  1380. if self.parent.autoRender.IsChecked():
  1381. self.mapWindow.Refresh(False)
  1382. def SetSurfaceUseMap(self, attrb, map=None):
  1383. if attrb in ('topo', 'color', 'shine'):
  1384. incSel = -1 # decrement selection (no 'unset')
  1385. else:
  1386. incSel = 0
  1387. if map is True: # map
  1388. if attrb != 'topo': # changing map topography not allowed
  1389. self.FindWindowById(self.win['surface'][attrb]['map'] + 1).Enable(True) # FIXME
  1390. if self.win['surface'][attrb]['const']:
  1391. self.FindWindowById(self.win['surface'][attrb]['const']).Enable(False)
  1392. self.FindWindowById(self.win['surface'][attrb]['use']).SetSelection(1 + incSel)
  1393. elif map is False: # const
  1394. self.FindWindowById(self.win['surface'][attrb]['map'] + 1).Enable(False)
  1395. if self.win['surface'][attrb]['const']:
  1396. self.FindWindowById(self.win['surface'][attrb]['const']).Enable(True)
  1397. self.FindWindowById(self.win['surface'][attrb]['use']).SetSelection(2 + incSel)
  1398. else: # unset
  1399. self.FindWindowById(self.win['surface'][attrb]['map'] + 1).Enable(False)
  1400. if self.win['surface'][attrb]['const']:
  1401. self.FindWindowById(self.win['surface'][attrb]['const']).Enable(False)
  1402. self.FindWindowById(self.win['surface'][attrb]['use']).SetSelection(0)
  1403. def OnSurfaceMap(self, event):
  1404. """Set surface attribute"""
  1405. if not self.mapWindow.init:
  1406. return
  1407. attrb = self.__GetWindowName(self.win['surface'], event.GetId())
  1408. if not attrb:
  1409. return
  1410. selection = self.FindWindowById(self.win['surface'][attrb]['use']).GetSelection()
  1411. if self.win['surface'][attrb]['required']:
  1412. selection += 1
  1413. if selection == 0: # unset
  1414. map = None
  1415. value = ''
  1416. elif selection == 1: # map
  1417. value = self.FindWindowById(self.win['surface'][attrb]['map']).GetValue()
  1418. map = True
  1419. else: # constant
  1420. if attrb == 'color':
  1421. value = self.FindWindowById(self.win['surface'][attrb]['const']).GetColour()
  1422. value = str(value[0]) + ':' + str(value[1]) + ':' + str(value[2])
  1423. else:
  1424. value = self.FindWindowById(self.win['surface'][attrb]['const']).GetValue()
  1425. map = False
  1426. if self.pageUpdated: # do not update when selection is changed
  1427. self.mapWindow.update[attrb] = (map, str(value))
  1428. self.UpdateLayerProperties()
  1429. if self.parent.autoRender.IsChecked():
  1430. self.mapWindow.Refresh(False)
  1431. def OnSurfaceResolution(self, event):
  1432. """Draw resolution changed"""
  1433. self.SetSurfaceResolution()
  1434. if apply and self.parent.autoRender.IsChecked():
  1435. self.mapWindow.Refresh(False)
  1436. def SetSurfaceResolution(self, all=False):
  1437. """Set draw resolution"""
  1438. coarse = self.FindWindowById(self.win['surface']['draw']['res-coarse']).GetValue()
  1439. fine = self.FindWindowById(self.win['surface']['draw']['res-fine']).GetValue()
  1440. self.mapWindow.update['draw-res'] = (coarse, fine, all)
  1441. self.UpdateLayerProperties()
  1442. def SetSurfaceMode(self, all=False):
  1443. """Set draw mode
  1444. @param apply allow auto-rendering
  1445. """
  1446. value = 0
  1447. mode = self.FindWindowById(self.win['surface']['draw']['mode']).GetSelection()
  1448. if mode == 0: # coarse
  1449. value |= wxnviz.DM_WIRE
  1450. self.FindWindowById(self.win['surface']['draw']['res-coarse']).Enable(True)
  1451. self.FindWindowById(self.win['surface']['draw']['res-fine']).Enable(False)
  1452. elif mode == 1: # fine
  1453. value |= wxnviz.DM_POLY
  1454. self.FindWindowById(self.win['surface']['draw']['res-coarse']).Enable(False)
  1455. self.FindWindowById(self.win['surface']['draw']['res-fine']).Enable(True)
  1456. else: # both
  1457. value |= wxnviz.DM_WIRE_POLY
  1458. self.FindWindowById(self.win['surface']['draw']['res-coarse']).Enable(True)
  1459. self.FindWindowById(self.win['surface']['draw']['res-fine']).Enable(True)
  1460. style = self.FindWindowById(self.win['surface']['draw']['style']).GetSelection()
  1461. if style == 0: # wire
  1462. value |= wxnviz.DM_GRID_WIRE
  1463. else: # surface
  1464. value |= wxnviz.DM_GRID_SURF
  1465. shade = self.FindWindowById(self.win['surface']['draw']['shading']).GetSelection()
  1466. if shade == 0:
  1467. value |= wxnviz.DM_FLAT
  1468. else: # surface
  1469. value |= wxnviz.DM_GOURAUD
  1470. if self.pageUpdated:
  1471. self.mapWindow.update['draw-style'] = (value, all)
  1472. self.UpdateLayerProperties()
  1473. def OnSurfaceMode(self, event):
  1474. """Set draw mode"""
  1475. self.SetSurfaceMode()
  1476. if apply and self.parent.autoRender.IsChecked():
  1477. self.mapWindow.Refresh(False)
  1478. def OnSurfaceModeAll(self, event):
  1479. """Set draw mode (including wire color) for all loaded surfaces"""
  1480. self.SetSurfaceMode(all=True)
  1481. self.SetSurfaceResolution(all=True)
  1482. color = self.FindWindowById(self.win['surface']['draw']['color']).GetColour()
  1483. self.SetSurfaceWireColor(color, all=True)
  1484. if apply and self.parent.autoRender.IsChecked():
  1485. self.mapWindow.Refresh(False)
  1486. def SetSurfaceWireColor(self, color, all=False, apply=True):
  1487. """Set wire color"""
  1488. value = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  1489. if self.pageUpdated:
  1490. self.mapWindow.update['draw-color'] = (value, all)
  1491. self.UpdateLayerProperties()
  1492. def OnSurfaceWireColor(self, event):
  1493. """Set wire color"""
  1494. self.SetSurfaceWireColor(event.GetValue())
  1495. if self.parent.autoRender.IsChecked():
  1496. self.mapWindow.Refresh(False)
  1497. def OnSurfaceAxis(self, event):
  1498. """Surface position, axis changed"""
  1499. mapLayer = self.mapWindow.GetSelectedLayer()
  1500. id = self.mapWindow.GetMapObjId(mapLayer)
  1501. axis = self.FindWindowById(self.win['surface']['position']['axis']).GetSelection()
  1502. win = self.FindWindowById(self.win['surface']['position']['pos'])
  1503. x, y, z = self.mapWindow.nvizClass.GetSurfacePosition(id)
  1504. if axis == 0: # x
  1505. win.SetRange(-1e4, 1e4)
  1506. win.SetValue(x)
  1507. elif axis == 1: # y
  1508. win.SetRange(-1e4, 1e4)
  1509. win.SetValue(y)
  1510. else: # z
  1511. win.SetRange(-1e3, 1e3)
  1512. win.SetValue(z)
  1513. def OnSurfacePosition(self, event):
  1514. """Surface position"""
  1515. axis = self.FindWindowById(self.win['surface']['position']['axis']).GetSelection()
  1516. value = event.GetInt()
  1517. self.mapWindow.update['surface-position'] = (axis, value)
  1518. self.UpdateLayerProperties()
  1519. if self.parent.autoRender.IsChecked():
  1520. self.mapWindow.Refresh(False)
  1521. def OnVectorDisplay(self, event):
  1522. """Display vector lines on surface/flat"""
  1523. if event.GetSelection() == 0: # surface
  1524. self.FindWindowById(self.win['vector']['lines']['surface']).Enable(True)
  1525. # set first found surface
  1526. ### TODO
  1527. else: # flat
  1528. self.FindWindowById(self.win['vector']['lines']['surface']).Enable(False)
  1529. self.OnVectorLines(event)
  1530. event.Skip()
  1531. def OnVectorLines(self, event):
  1532. """Set vector lines mode, apply changes if auto-rendering is enabled"""
  1533. width = self.FindWindowById(self.win['vector']['lines']['width']).GetValue()
  1534. color = self.FindWindowById(self.win['vector']['lines']['color']).GetColour()
  1535. color = str(color[0]) + ':' + str(color[1]) + ':' + str(color[2])
  1536. if self.FindWindowById(self.win['vector']['lines']['flat']).GetSelection() == 0:
  1537. flat = False
  1538. else:
  1539. flat = True
  1540. self.mapWindow.update['vector-lines'] = (width, color, flat)
  1541. self.UpdateLayerProperties()
  1542. if self.parent.autoRender.IsChecked():
  1543. self.mapWindow.Refresh(False)
  1544. def OnVectorHeight(self, event):
  1545. value = event.GetInt()
  1546. if type(event) == type(wx.ScrollEvent()):
  1547. # slider
  1548. win = self.FindWindowById(self.win['vector']['lines']['height']['spin'])
  1549. else:
  1550. # spin
  1551. win = self.FindWindowById(self.win['vector']['lines']['height']['slider'])
  1552. win.SetValue(value)
  1553. self.mapWindow.update['vector-height'] = value
  1554. self.UpdateLayerProperties()
  1555. if self.parent.autoRender.IsChecked():
  1556. self.mapWindow.Refresh(False)
  1557. def UpdatePage(self, pageId):
  1558. """Update dialog (selected page)"""
  1559. self.pageUpdated = False
  1560. layer = self.mapWindow.GetSelectedLayer()
  1561. data = self.mapWindow.GetSelectedLayer(nviz=True)
  1562. if pageId == 'view':
  1563. max = self.mapWindow.view['z-exag']['value'] * 10
  1564. for control in ('spin', 'slider'):
  1565. self.FindWindowById(self.win['view']['z-exag'][control]).SetRange(0,
  1566. max)
  1567. elif pageId == 'surface':
  1568. # disable vector and enable surface page
  1569. self.notebook.GetPage(self.page['surface']).Enable(True)
  1570. self.notebook.GetPage(self.page['vector']).Enable(False)
  1571. # use default values
  1572. if data == {}:
  1573. # attributes
  1574. for attr in ('topo', 'color'): # required
  1575. if layer and layer.type == 'raster':
  1576. self.FindWindowById(self.win['surface'][attr]['map']).SetValue(layer.name)
  1577. else:
  1578. self.FindWindowById(self.win['surface'][attr]['map']).SetValue('')
  1579. self.SetSurfaceUseMap(attr, True) # -> map
  1580. if UserSettings.Get(group='nviz', key='surface', subkey=['shine', 'map']) is False:
  1581. self.SetSurfaceUseMap('shine', False)
  1582. value = UserSettings.Get(group='nviz', key='surface', subkey=['shine', 'value'])
  1583. self.FindWindowById(self.win['surface']['shine']['const']).SetValue(value)
  1584. #
  1585. # draw
  1586. #
  1587. for control, value in UserSettings.Get(group='nviz', key='surface', subkey='draw').iteritems():
  1588. win = self.FindWindowById(self.win['surface']['draw'][control])
  1589. name = win.GetName()
  1590. if name == "selection":
  1591. win.SetSelection(value)
  1592. elif name == "colour":
  1593. win.SetColour(value)
  1594. else:
  1595. win.SetValue(value)
  1596. # enable/disable res widget + set draw mode
  1597. self.SetSurfaceMode()
  1598. color = self.FindWindowById(self.win['surface']['draw']['color'])
  1599. self.SetSurfaceWireColor(color.GetColour())
  1600. elif layer.type == 'raster':
  1601. # surface attributes
  1602. for attr in data['attr']:
  1603. if attr['map']:
  1604. win = self.FindWindowById(self.win['surface'][attr]['map'])
  1605. else:
  1606. win = self.FindWindowById(self.win['surface'][attr]['const'])
  1607. win.SetValue(data['value'])
  1608. elif pageId == 'vector':
  1609. # disable surface and enable current
  1610. self.notebook.GetPage(self.page['surface']).Enable(False)
  1611. self.notebook.GetPage(self.page['vector']).Enable(True)
  1612. if data is None: # defaut values
  1613. # lines
  1614. for name in ('width', 'color'):
  1615. win = self.FindWindowById(self.win['vector']['lines'][name])
  1616. win.SetValue(UserSettings.Get(group='nviz', key='vector',
  1617. subkey=['lines', name]))
  1618. display = self.FindWindowById(self.win['vector']['lines']['flat'])
  1619. if UserSettings.Get(group='nviz', key='vector',
  1620. subkey=['lines', 'flat']):
  1621. display.SetSelection(1)
  1622. else:
  1623. display.SetSelection(0)
  1624. value = UserSettings.Get(group='nviz', key='vector',
  1625. subkey=['lines', 'height'])
  1626. for type in ('slider', 'spin'):
  1627. win = self.FindWindowById(self.win['vector']['lines']['height'][type])
  1628. win.SetValue(value)
  1629. self.pageUpdated = True
  1630. def SetPage(self, name):
  1631. """Get named page"""
  1632. self.notebook.SetSelection(self.page[name])
  1633. class ViewPositionWindow(wx.Window):
  1634. """Position control window (for NvizToolWindow)"""
  1635. def __init__(self, parent, id, mapwindow,
  1636. pos=wx.DefaultPosition,
  1637. size=wx.DefaultSize):
  1638. self.mapWindow = mapwindow
  1639. wx.Window.__init__(self, parent, id, pos, size)
  1640. self.SetBackgroundColour("WHITE")
  1641. self.pdc = wx.PseudoDC()
  1642. self.pdc.SetBrush(wx.Brush(colour='dark green', style=wx.SOLID))
  1643. self.pdc.SetPen(wx.Pen(colour='dark green', width=2, style=wx.SOLID))
  1644. self.Draw()
  1645. self.Bind(wx.EVT_ERASE_BACKGROUND, lambda x: None)
  1646. self.Bind(wx.EVT_PAINT, self.OnPaint)
  1647. # self.Bind(wx.EVT_MOTION, self.OnMouse)
  1648. self.Bind(wx.EVT_MOUSE_EVENTS, self.OnMouse)
  1649. def Draw(self, pos=None):
  1650. w, h = self.GetClientSize()
  1651. if pos is None:
  1652. x = self.mapWindow.view['pos']['x']
  1653. y = self.mapWindow.view['pos']['y']
  1654. x = x * w
  1655. y = y * h
  1656. else:
  1657. x, y = pos
  1658. self.pdc.Clear()
  1659. self.pdc.BeginDrawing()
  1660. self.pdc.DrawLine(w / 2, h / 2, x, y)
  1661. self.pdc.DrawCircle(x, y, 5)
  1662. self.pdc.EndDrawing()
  1663. def OnPaint(self, event):
  1664. dc = wx.BufferedPaintDC(self)
  1665. dc.SetBackground(wx.Brush("White"))
  1666. dc.Clear()
  1667. self.PrepareDC(dc)
  1668. self.pdc.DrawToDC(dc)
  1669. def OnMouse(self, event):
  1670. if event.LeftIsDown():
  1671. x, y = event.GetPosition()
  1672. self.Draw(pos=(x, y))
  1673. self.Refresh(False)
  1674. w, h = self.GetClientSize()
  1675. x = float(x) / w
  1676. y = float(y) / h
  1677. self.mapWindow.view['pos']['x'] = x
  1678. self.mapWindow.view['pos']['y'] = y
  1679. self.mapWindow.update['view'] = None
  1680. self.mapWindow.render = False
  1681. if event.LeftUp():
  1682. self.mapWindow.render = True
  1683. self.mapWindow.Refresh(eraseBackground=False)