nviz.py 83 KB

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