vkrige.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. """
  2. MODULE: vkrige
  3. AUTHOR(S): Anne Ghisla <a.ghisla AT gmail.com>
  4. PURPOSE: Dedicated GUI for v.krige script.
  5. DEPENDS: R 2.x, packages gstat, maptools and spgrass6, optional: automap
  6. COPYRIGHT: (C) 2009 by the GRASS Development Team
  7. This program is free software under the GNU General Public
  8. License (>=v2). Read the file COPYING that comes with GRASS
  9. for details.
  10. """
  11. #@TODO move here imports related to wxGUI
  12. # generic imports
  13. import os
  14. import sys
  15. from tempfile import gettempdir
  16. import time
  17. import thread
  18. from core.utils import _
  19. # dependencies to be checked once, as they are quite
  20. # time-consuming. cfr. grass.parser.
  21. try:
  22. import grass.script as grass
  23. except ImportError:
  24. sys.exit(_("No GRASS-python library found."))
  25. from core import globalvar
  26. from gui_core import gselect
  27. from core import gconsole
  28. from gui_core import goutput
  29. from core.settings import UserSettings
  30. from gui_core.widgets import GNotebook
  31. from core.giface import Notification
  32. #import help
  33. import wx
  34. # import wx.lib.plot as plot # for plotting the variogram.
  35. import rpy2.robjects as robjects
  36. import rpy2.rinterface as rinterface
  37. # global variables
  38. # instead of sys.maxint, not working with SpinCtrl on 64bit [reported by
  39. # Bob Moskovitz]
  40. maxint = 1e6
  41. #@TODO move away functions not regarding the GUI
  42. class KrigingPanel(wx.Panel):
  43. """Main panel. Contains all widgets except Menus and Statusbar. """
  44. def __init__(self, parent, Rinstance, controller, *args, **kwargs):
  45. wx.Panel.__init__(self, parent, *args, **kwargs)
  46. self.parent = parent
  47. self.border = 4
  48. # 1. Input data
  49. InputBoxSizer = wx.StaticBoxSizer(
  50. wx.StaticBox(
  51. self,
  52. id=wx.ID_ANY,
  53. label=_("Input Data")),
  54. orient=wx.HORIZONTAL)
  55. flexSizer = wx.FlexGridSizer(cols=3, hgap=5, vgap=5)
  56. flexSizer.AddGrowableCol(1)
  57. flexSizer.Add(
  58. item=wx.StaticText(
  59. self,
  60. id=wx.ID_ANY,
  61. label=_("Point dataset:")),
  62. flag=wx.ALIGN_CENTER_VERTICAL)
  63. self.InputDataMap = gselect.VectorSelect(parent=self,
  64. ftype='points',
  65. updateOnPopup=False)
  66. self.InputDataMap.SetFocus()
  67. flexSizer.Add(item=self.InputDataMap, flag=wx.ALIGN_CENTER_VERTICAL)
  68. RefreshButton = wx.Button(self, id=wx.ID_REFRESH)
  69. RefreshButton.Bind(wx.EVT_BUTTON, self.OnButtonRefresh)
  70. flexSizer.Add(item=RefreshButton, flag=wx.ALIGN_CENTER_VERTICAL)
  71. flexSizer.Add(
  72. item=wx.StaticText(
  73. self,
  74. id=wx.ID_ANY,
  75. label=_("Numeric column:")),
  76. flag=wx.ALIGN_CENTER_VERTICAL)
  77. self.InputDataColumn = gselect.ColumnSelect(self, id=wx.ID_ANY)
  78. flexSizer.Add(item=self.InputDataColumn)
  79. self.InputDataMap.GetChildren()[0].Bind(
  80. wx.EVT_TEXT, self.OnInputMapChanged)
  81. self.InputDataColumn.GetChildren()[0].Bind(
  82. wx.EVT_TEXT, self.OnInputColumnChanged)
  83. InputBoxSizer.Add(item=flexSizer)
  84. # 2. Kriging. In book pages one for each R package. Includes variogram
  85. # fit.
  86. KrigingSizer = wx.StaticBoxSizer(
  87. wx.StaticBox(
  88. self,
  89. id=wx.ID_ANY,
  90. label=_("Kriging")),
  91. wx.HORIZONTAL)
  92. self.RPackagesBook = GNotebook(
  93. parent=self, style=globalvar.FNPageDStyle)
  94. # , "geoR"]: #@TODO: enable it if/when it'll be implemented.
  95. for Rpackage in ["gstat"]:
  96. self.CreatePage(
  97. package=Rpackage,
  98. Rinstance=Rinstance,
  99. controller=controller)
  100. # Command output. From menuform module, cmdPanel class
  101. self._gconsole = gconsole.GConsole(guiparent=self)
  102. self.goutput = goutput.GConsoleWindow(
  103. parent=self, gconsole=self._gconsole, margin=False)
  104. self.goutputId = self.RPackagesBook.GetPageCount()
  105. self.outpage = self.RPackagesBook.AddPage(
  106. page=self.goutput, text=_("Command output"), name='output')
  107. self._gconsole.Bind(
  108. gconsole.EVT_CMD_RUN,
  109. lambda event: self._switchPageHandler(
  110. event=event,
  111. notification=Notification.MAKE_VISIBLE))
  112. self._gconsole.Bind(
  113. gconsole.EVT_CMD_DONE,
  114. lambda event: self._switchPageHandler(
  115. event=event,
  116. notification=Notification.RAISE_WINDOW))
  117. self.RPackagesBook.SetSelection(0)
  118. KrigingSizer.Add(self.RPackagesBook, proportion=1, flag=wx.EXPAND)
  119. # 3. Output Parameters.
  120. OutputSizer = wx.StaticBoxSizer(
  121. wx.StaticBox(
  122. self,
  123. id=wx.ID_ANY,
  124. label=_("Output")),
  125. wx.HORIZONTAL)
  126. OutputParameters = wx.GridBagSizer(hgap=5, vgap=5)
  127. OutputParameters.Add(
  128. item=wx.StaticText(
  129. self, id=wx.ID_ANY,
  130. label=_("Name for the output raster map:")),
  131. flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 0))
  132. self.OutputMapName = gselect.Select(parent=self, id=wx.ID_ANY,
  133. type='raster',
  134. mapsets=[grass.gisenv()['MAPSET']])
  135. OutputParameters.Add(item=self.OutputMapName, flag=wx.EXPAND | wx.ALL,
  136. pos=(0, 1))
  137. self.VarianceRasterCheckbox = wx.CheckBox(
  138. self, id=wx.ID_ANY, label=_("Export variance map as well: "))
  139. self.VarianceRasterCheckbox.SetValue(state=True)
  140. OutputParameters.Add(item=self.VarianceRasterCheckbox,
  141. flag=wx.ALIGN_CENTER_VERTICAL,
  142. pos=(1, 0))
  143. self.OutputVarianceMapName = gselect.Select(
  144. parent=self, id=wx.ID_ANY, type='raster',
  145. mapsets=[grass.gisenv()['MAPSET']])
  146. self.VarianceRasterCheckbox.Bind(
  147. wx.EVT_CHECKBOX, self.OnVarianceCBChecked)
  148. OutputParameters.Add(
  149. item=self.OutputVarianceMapName,
  150. flag=wx.EXPAND | wx.ALL,
  151. pos=(
  152. 1,
  153. 1))
  154. self.OverwriteCheckBox = wx.CheckBox(self, id=wx.ID_ANY, label=_(
  155. "Allow output files to overwrite existing files"))
  156. self.OverwriteCheckBox.SetValue(
  157. UserSettings.Get(
  158. group='cmd',
  159. key='overwrite',
  160. subkey='enabled'))
  161. OutputParameters.Add(item=self.OverwriteCheckBox,
  162. pos=(2, 0), span=(1, 2))
  163. OutputParameters.AddGrowableCol(1)
  164. OutputSizer.Add(
  165. OutputParameters,
  166. proportion=0,
  167. flag=wx.EXPAND | wx.ALL,
  168. border=self.border)
  169. # 4. Run Button and Quit Button
  170. ButtonSizer = wx.BoxSizer(wx.HORIZONTAL)
  171. HelpButton = wx.Button(self, id=wx.ID_HELP)
  172. HelpButton.Bind(wx.EVT_BUTTON, self.OnHelpButton)
  173. QuitButton = wx.Button(self, id=wx.ID_EXIT)
  174. QuitButton.Bind(wx.EVT_BUTTON, self.OnCloseWindow)
  175. # no stock ID for Run button..
  176. self.RunButton = wx.Button(self, id=wx.ID_ANY, label=_("&Run"))
  177. self.RunButton.Bind(wx.EVT_BUTTON, self.OnRunButton)
  178. # disable it on loading the interface, as input map is not set
  179. self.RunButton.Enable(False)
  180. ButtonSizer.Add(
  181. HelpButton,
  182. proportion=0,
  183. flag=wx.ALIGN_LEFT | wx.ALL,
  184. border=self.border)
  185. ButtonSizer.Add(
  186. QuitButton,
  187. proportion=0,
  188. flag=wx.ALIGN_RIGHT | wx.ALL,
  189. border=self.border)
  190. ButtonSizer.Add(
  191. self.RunButton,
  192. proportion=0,
  193. flag=wx.ALIGN_RIGHT | wx.ALL,
  194. border=self.border)
  195. # Main Sizer. Add each child sizer as soon as it is ready.
  196. Sizer = wx.BoxSizer(wx.VERTICAL)
  197. Sizer.Add(
  198. InputBoxSizer,
  199. proportion=0,
  200. flag=wx.EXPAND | wx.ALL,
  201. border=self.border)
  202. Sizer.Add(
  203. KrigingSizer,
  204. proportion=1,
  205. flag=wx.EXPAND | wx.ALL,
  206. border=self.border)
  207. Sizer.Add(
  208. OutputSizer,
  209. proportion=0,
  210. flag=wx.EXPAND | wx.ALL,
  211. border=self.border)
  212. Sizer.Add(
  213. ButtonSizer,
  214. proportion=0,
  215. flag=wx.ALIGN_RIGHT | wx.ALL,
  216. border=self.border)
  217. self.SetSizerAndFit(Sizer)
  218. # last action of __init__: update imput data list.
  219. # it's performed in the few seconds gap while user examines interface before clicking anything.
  220. #@TODO: implement a splashcreen IF the maps cause a noticeable lag [markus' suggestion]
  221. self.InputDataMap.GetElementList()
  222. def CreatePage(self, package, Rinstance, controller):
  223. """Creates the three notebook pages, one for each R package """
  224. for package in [
  225. "gstat"]: # @TODO add here other packages when they will be implemented
  226. classobj = eval("RBook" + package + "Panel")
  227. setattr(
  228. self,
  229. "RBook" +
  230. package +
  231. "Panel",
  232. (classobj(
  233. self,
  234. id=wx.ID_ANY,
  235. Rinstance=Rinstance,
  236. controller=controller)))
  237. self.RPackagesBook.AddPage(
  238. page=getattr(
  239. self,
  240. "RBook" +
  241. package +
  242. "Panel"),
  243. text=package)
  244. def OnButtonRefresh(self, event):
  245. """Forces refresh of list of available layers. """
  246. self.InputDataMap.GetElementList()
  247. def OnCloseWindow(self, event):
  248. """Cancel button pressed"""
  249. self.parent.Close()
  250. event.Skip()
  251. def OnHelpButton(self, event):
  252. grass.run_command('g.manual', entry='v.krige')
  253. event.Skip()
  254. def OnInputMapChanged(self, event):
  255. """Refreshes list of columns."""
  256. MapName = event.GetString()
  257. self.InputDataColumn.InsertColumns(
  258. vector=MapName, layer=1, excludeKey=False,
  259. type=['integer', 'double precision'])
  260. def OnInputColumnChanged(self, event):
  261. """Fills output map name TextCtrl """
  262. MapName = self.InputDataMap.GetValue()
  263. enable = bool(self.InputDataColumn.GetValue())
  264. self.RunButton.Enable(enable)
  265. self.RBookgstatPanel.PlotButton.Enable(enable)
  266. if enable:
  267. self.OutputMapName.SetValue(MapName.split("@")[0] + "_kriging")
  268. self.OutputVarianceMapName.SetValue(
  269. MapName.split("@")[0] + "_kriging.var")
  270. else:
  271. self.OutputMapName.SetValue('')
  272. self.OutputVarianceMapName.SetValue('')
  273. def OnRunButton(self, event):
  274. """Execute R analysis. """
  275. #@FIXME: send data to main method instead of running it here.
  276. #-1: get the selected notebook page. The user shall know that [s]he can modify settings in all
  277. # pages, but only the selected one will be executed when Run is
  278. # pressed.
  279. SelectedPanel = self.RPackagesBook.GetCurrentPage()
  280. if self.RPackagesBook.GetPageText(
  281. self.RPackagesBook.GetSelection()) == 'Command output':
  282. self._gconsole.WriteError(
  283. "No parameters for running. Please select \"gstat\" tab, check parameters and re-run.")
  284. return False # no break invoked by above function
  285. # mount command string as it would have been written on CLI
  286. command = [
  287. "v.krige",
  288. "input=" +
  289. self.InputDataMap.GetValue(),
  290. "column=" +
  291. self.InputDataColumn.GetValue(),
  292. "output=" +
  293. self.OutputMapName.GetValue(),
  294. "package=" +
  295. '%s' %
  296. self.RPackagesBook.GetPageText(
  297. self.RPackagesBook.GetSelection())]
  298. if not hasattr(
  299. SelectedPanel, 'VariogramCheckBox') or not SelectedPanel.VariogramCheckBox.IsChecked():
  300. command.append(
  301. "model=" + '%s' %
  302. SelectedPanel.ModelChoicebox.GetStringSelection().split(" ")[0])
  303. for i in ['Sill', 'Nugget', 'Range', 'Kappa']:
  304. if getattr(SelectedPanel, i + "ChextBox").IsChecked():
  305. command.append(
  306. i.lower() +
  307. "=" +
  308. '%s' %
  309. getattr(
  310. SelectedPanel,
  311. i +
  312. 'Ctrl').GetValue())
  313. if SelectedPanel.KrigingRadioBox.GetStringSelection() == "Block kriging":
  314. command.append(
  315. "block=" + '%s' %
  316. SelectedPanel.BlockSpinBox.GetValue())
  317. if self.OverwriteCheckBox.IsChecked():
  318. command.append("--overwrite")
  319. if self.VarianceRasterCheckbox.IsChecked():
  320. command.append(
  321. "output_var=" +
  322. self.OutputVarianceMapName.GetValue())
  323. # give it to the output console
  324. #@FIXME: it runs the command as a NEW instance. Reimports data, recalculates variogram fit..
  325. # otherwise I can use Controller() and mimic RunCmd behaviour.
  326. self._gconsole.RunCmd(command)
  327. def OnVarianceCBChecked(self, event):
  328. self.OutputVarianceMapName.Enable(event.IsChecked())
  329. def _switchPageHandler(self, event, notification):
  330. self._switchPage(notification=notification)
  331. event.Skip()
  332. def _switchPage(self, notification):
  333. """Manages @c 'output' notebook page according to event notification."""
  334. if notification == Notification.HIGHLIGHT:
  335. self.RPackagesBook.HighlightPageByName('output')
  336. if notification == Notification.MAKE_VISIBLE:
  337. self.RPackagesBook.SetSelectionByName('output')
  338. if notification == Notification.RAISE_WINDOW:
  339. self.RPackagesBook.SetSelectionByName('output')
  340. self.SetFocus()
  341. self.Raise()
  342. class KrigingModule(wx.Frame):
  343. """Kriging module for GRASS GIS. Depends on R and its packages gstat and geoR. """
  344. def __init__(self, parent, Rinstance, controller, *args, **kwargs):
  345. wx.Frame.__init__(self, parent, *args, **kwargs)
  346. # setting properties and all widgettery
  347. self.SetTitle(_("Kriging Module"))
  348. self.SetIcon(
  349. wx.Icon(
  350. os.path.join(
  351. globalvar.ICONDIR,
  352. 'grass_dialog.ico'),
  353. wx.BITMAP_TYPE_ICO))
  354. self.log = Log(self)
  355. self.CreateStatusBar()
  356. self.log.message(_("Ready."))
  357. self.Panel = KrigingPanel(self, Rinstance, controller)
  358. self.SetMinSize(self.GetBestSize())
  359. self.SetSize(self.GetBestSize())
  360. class Log:
  361. """The log output is redirected to the status bar of the containing frame. """
  362. def __init__(self, parent):
  363. self.parent = parent
  364. def message(self, text_string):
  365. """Updates status bar """
  366. self.parent.SetStatusText(text_string.strip())
  367. class RBookPanel(wx.Panel):
  368. """Generic notebook page with shared widgets and empty kriging functions. """
  369. def __init__(self, parent, *args, **kwargs):
  370. wx.Panel.__init__(self, parent, *args, **kwargs)
  371. self.parent = parent
  372. self.VariogramSizer = wx.StaticBoxSizer(
  373. wx.StaticBox(
  374. self,
  375. id=wx.ID_ANY,
  376. label=_("Variogram fitting")),
  377. wx.HORIZONTAL)
  378. self.LeftSizer = wx.BoxSizer(wx.VERTICAL)
  379. self.RightSizer = wx.BoxSizer(wx.VERTICAL)
  380. self.ParametersSizer = wx.GridBagSizer(vgap=5, hgap=5)
  381. self.VariogramSizer.Add(
  382. self.LeftSizer,
  383. proportion=0,
  384. flag=wx.EXPAND | wx.ALL,
  385. border=parent.border)
  386. self.VariogramSizer.Add(
  387. self.RightSizer,
  388. proportion=0,
  389. flag=wx.EXPAND | wx.ALL,
  390. border=parent.border)
  391. # left side of Variogram fitting. The checkboxes and spinctrls.
  392. # no stock ID for Run button..
  393. self.PlotButton = wx.Button(
  394. self, id=wx.ID_ANY, label=_("Plot/refresh variogram"))
  395. self.PlotButton.Bind(wx.EVT_BUTTON, self.OnPlotButton)
  396. # grey it out until a suitable layer is available
  397. self.PlotButton.Enable(False)
  398. self.LeftSizer.Add(
  399. self.PlotButton,
  400. proportion=0,
  401. flag=wx.ALL,
  402. border=parent.border)
  403. self.LeftSizer.Add(
  404. self.ParametersSizer,
  405. proportion=0,
  406. flag=wx.EXPAND | wx.ALL,
  407. border=parent.border)
  408. self.ParametersList = ["Sill", "Nugget", "Range", "Kappa"]
  409. MinValues = [0, 0, 1, 0.1]
  410. for n in self.ParametersList:
  411. setattr(
  412. self,
  413. n + "ChextBox",
  414. wx.CheckBox(
  415. self,
  416. id=self.ParametersList.index(n),
  417. label=_(
  418. n + ":")))
  419. # Kappa must be float
  420. if n == "Kappa":
  421. setattr(
  422. self,
  423. n + "Ctrl",
  424. (wx.SpinCtrlDouble(
  425. self,
  426. id=wx.ID_ANY,
  427. min=MinValues[
  428. self.ParametersList.index(n)],
  429. max=maxint,
  430. inc=0.1,
  431. initial=0.5)))
  432. else:
  433. setattr(
  434. self,
  435. n + "Ctrl",
  436. (wx.SpinCtrl(
  437. self,
  438. id=wx.ID_ANY,
  439. min=MinValues[
  440. self.ParametersList.index(n)],
  441. max=maxint)))
  442. getattr(self, n + "ChextBox").Bind(wx.EVT_CHECKBOX,
  443. self.UseValue,
  444. id=self.ParametersList.index(n))
  445. setattr(self, n + "Sizer", (wx.BoxSizer(wx.HORIZONTAL)))
  446. self.ParametersSizer.Add(getattr(self, n + "ChextBox"),
  447. flag=wx.ALIGN_CENTER_VERTICAL,
  448. pos=(self.ParametersList.index(n), 0))
  449. self.ParametersSizer.Add(getattr(self, n + "Ctrl"),
  450. flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL,
  451. pos=(self.ParametersList.index(n), 1))
  452. # right side of the Variogram fitting. The plot area.
  453. #Plot = wx.StaticText(self, id= wx.ID_ANY, label = "Check Plot Variogram to interactively fit model.")
  454. #PlotPanel = wx.Panel(self)
  455. #self.PlotArea = plot.PlotCanvas(PlotPanel)
  456. #self.PlotArea.SetInitialSize(size = (250,250))
  457. #self.RightSizer.Add(PlotPanel, proportion=0, flag= wx.EXPAND|wx.ALL, border=parent.border)
  458. self.KrigingSizer = wx.StaticBoxSizer(
  459. wx.StaticBox(
  460. self,
  461. id=wx.ID_ANY,
  462. label=_("Kriging techniques")),
  463. wx.VERTICAL)
  464. # , "Universal kriging"] #@FIXME: i18n on the list?
  465. KrigingList = ["Ordinary kriging", "Block kriging"]
  466. self.KrigingRadioBox = wx.RadioBox(self,
  467. id=wx.ID_ANY,
  468. choices=KrigingList,
  469. majorDimension=1,
  470. style=wx.RA_SPECIFY_COLS)
  471. self.KrigingRadioBox.Bind(wx.EVT_RADIOBOX, self.HideBlockOptions)
  472. self.KrigingSizer.Add(
  473. self.KrigingRadioBox,
  474. proportion=0,
  475. flag=wx.EXPAND | wx.ALL,
  476. border=parent.border)
  477. # block kriging parameters. Size.
  478. BlockSizer = wx.BoxSizer(wx.HORIZONTAL)
  479. BlockLabel = wx.StaticText(self, id=wx.ID_ANY, label=_("Block size:"))
  480. self.BlockSpinBox = wx.SpinCtrl(self, id=wx.ID_ANY, min=1, max=maxint)
  481. # default choice is Ordinary kriging so block param is disabled
  482. self.BlockSpinBox.Enable(False)
  483. BlockSizer.Add(
  484. BlockLabel,
  485. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  486. border=parent.border)
  487. BlockSizer.Add(
  488. self.BlockSpinBox,
  489. flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  490. border=parent.border)
  491. self.KrigingSizer.Add(
  492. BlockSizer,
  493. flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  494. border=parent.border)
  495. self.Sizer = wx.BoxSizer(wx.VERTICAL)
  496. self.Sizer.Add(
  497. self.VariogramSizer,
  498. proportion=0,
  499. flag=wx.EXPAND | wx.ALL,
  500. border=parent.border)
  501. self.Sizer.Add(
  502. self.KrigingSizer,
  503. proportion=0,
  504. flag=wx.EXPAND | wx.ALL,
  505. border=parent.border)
  506. def HideBlockOptions(self, event):
  507. self.BlockSpinBox.Enable(event.GetInt() == 1)
  508. def OnPlotButton(self, event):
  509. """Plots variogram with current options. """
  510. pass
  511. def UseValue(self, event):
  512. """Enables/Disables the SpinCtrl in respect of the checkbox. """
  513. n = self.ParametersList[event.GetId()]
  514. getattr(self, n + "Ctrl").Enable(event.IsChecked())
  515. class RBookgstatPanel(RBookPanel):
  516. """Subclass of RBookPanel, with specific gstat options and kriging functions. """
  517. def __init__(self, parent, Rinstance, controller, *args, **kwargs):
  518. RBookPanel.__init__(self, parent, *args, **kwargs)
  519. # assigns Rinstance, that comes from the GUI call of v.krige.py.
  520. robjects = Rinstance
  521. self.controller = controller
  522. if robjects.r.require('automap')[0]:
  523. self.VariogramCheckBox = wx.CheckBox(
  524. self, id=wx.ID_ANY, label=_("Auto-fit variogram"))
  525. self.LeftSizer.Insert(
  526. 0,
  527. self.VariogramCheckBox,
  528. proportion=0,
  529. flag=wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  530. border=4)
  531. self.SetSizerAndFit(self.Sizer)
  532. self.VariogramCheckBox.Bind(wx.EVT_CHECKBOX, self.HideOptions)
  533. self.VariogramCheckBox.SetValue(state=True) # check it by default
  534. # Get list of available models. Show long name but use short one
  535. ModelFactor = robjects.r.vgm()
  536. ModelList = robjects.r.levels(ModelFactor[1])
  537. self.ModelListShort = robjects.r.levels(ModelFactor[0])
  538. #@FIXME: no other way to let the Python pick it up..
  539. # and this is te wrong place where to load this list. should be at the
  540. # very beginning.
  541. self.ModelChoicebox = wx.Choice(self, id=wx.ID_ANY, choices=ModelList)
  542. # disable model parameters' widgets by default
  543. for n in ["Sill", "Nugget", "Range", "Kappa"]:
  544. getattr(self, n + "Ctrl").Enable(False)
  545. self.ModelChoicebox.Enable(False)
  546. VariogramSubSizer = wx.BoxSizer(wx.HORIZONTAL)
  547. VariogramSubSizer.Add(item=wx.StaticText(self,
  548. id=wx.ID_ANY,
  549. label=_("Model: ")),
  550. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  551. border=4)
  552. VariogramSubSizer.Add(item=self.ModelChoicebox,
  553. flag=wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  554. border=4)
  555. self.LeftSizer.Insert(2, item=VariogramSubSizer)
  556. self.SetSizerAndFit(self.Sizer)
  557. def HideOptions(self, event):
  558. self.ModelChoicebox.Enable(not event.IsChecked())
  559. for n in ["Sill", "Nugget", "Range", "Kappa"]:
  560. if not event.IsChecked():
  561. getattr(self, n + "Ctrl").Enable(True)
  562. getattr(self, n + "ChextBox").SetValue(True)
  563. # grey it out keeping it checked.. improvable
  564. getattr(self, n + "ChextBox").Enable(False)
  565. else:
  566. getattr(self, n + "Ctrl").Enable(False)
  567. getattr(self, n + "ChextBox").SetValue(False)
  568. getattr(self, n + "ChextBox").Enable(True)
  569. #@FIXME: was for n in self.ParametersSizer.GetChildren(): n.Enable(False) but doesn't work
  570. def OnPlotButton(self, event):
  571. """Plots variogram with current options. """
  572. # BIG WARNING: smell of code duplication. Fix this asap. emminchia!
  573. # controller = Controller() # sed, if needed,
  574. #controller = self.controller
  575. map = self.parent.InputDataMap.GetValue()
  576. column = self.parent.InputDataColumn.GetValue()
  577. # import data or pick them up
  578. if self.controller.InputData is None:
  579. self.controller.InputData = self.controller.ImportMap(
  580. map=map, column=column)
  581. # fit the variogram or pick it up
  582. #~ Formula = self.controller.ComposeFormula(column = column,
  583. #~ isblock = self.KrigingRadioBox.GetStringSelection() == "Block kriging")
  584. if hasattr(
  585. self, 'VariogramCheckBox') and self.VariogramCheckBox.IsChecked():
  586. self.model = ''
  587. for each in ("Sill", "Nugget", "Range", "Kappa"):
  588. if getattr(self, each + 'ChextBox').IsChecked():
  589. setattr(
  590. self, each.lower(), getattr(
  591. self, each + "Ctrl").GetValue())
  592. else:
  593. setattr(self, each.lower(), robjects.r('''NA'''))
  594. else:
  595. self.model = self.ModelListShort[
  596. self.ModelChoicebox.GetSelection()]
  597. for each in ("Sill", "Nugget", "Range", "Kappa"):
  598. # @FIXME will be removed when chextboxes will be frozen
  599. if getattr(self, each + 'ChextBox').IsChecked():
  600. setattr(
  601. self, each.lower(), getattr(
  602. self, each + "Ctrl").GetValue())
  603. isblock = self.KrigingRadioBox.GetStringSelection() == "Block kriging"
  604. if isblock is not '':
  605. self.predictor = 'x+y'
  606. else:
  607. self.predictor = '1'
  608. self.controller.Variogram = self.controller.FitVariogram(
  609. robjects.Formula(str(column) + "~" + self.predictor),
  610. self.controller.InputData, model=self.model, sill=self.sill,
  611. nugget=self.nugget, range=self.range, kappa=self.kappa)
  612. ''' Fill parameters with autofitted values '''
  613. if hasattr(
  614. self, 'VariogramCheckBox') and self.VariogramCheckBox.IsChecked():
  615. for i in range(len(self.ModelListShort)):
  616. if self.ModelListShort[
  617. i] == self.controller.Variogram['model']:
  618. self.ModelChoicebox.SetSelection(i)
  619. break
  620. if not getattr(self, 'SillChextBox').IsChecked():
  621. self.sill = self.controller.Variogram['variogrammodel'][1][1]
  622. self.SillCtrl.SetValue(self.sill)
  623. if not getattr(self, 'NuggetChextBox').IsChecked():
  624. self.nugget = self.controller.Variogram['variogrammodel'][1][0]
  625. self.NuggetCtrl.SetValue(self.nugget)
  626. if not getattr(self, 'RangeChextBox').IsChecked():
  627. self.range = self.controller.Variogram['variogrammodel'][2][1]
  628. self.RangeCtrl.SetValue(self.range)
  629. if not getattr(self, 'KappaChextBox').IsChecked():
  630. self.kappa = self.controller.Variogram['variogrammodel'][3][1]
  631. self.KappaCtrl.SetValue(self.kappa)
  632. # use R plot function, in a separate window.
  633. thread.start_new_thread(self.plot, ())
  634. def plot(self):
  635. # robjects.r.X11()
  636. # robjects.r.png("variogram.png")
  637. textplot = robjects.r.plot(self.controller.Variogram['datavariogram'],
  638. self.controller.Variogram['variogrammodel'])
  639. print textplot
  640. self.refresh()
  641. # robjects.r['dev.off']()
  642. def refresh(self):
  643. while True:
  644. rinterface.process_revents()
  645. time.sleep(0.2)
  646. class RBookgeoRPanel(RBookPanel):
  647. """Subclass of RBookPanel, with specific geoR options and kriging functions. """
  648. def __init__(self, parent, *args, **kwargs):
  649. RBookPanel.__init__(self, parent, *args, **kwargs)
  650. #@TODO: change these two lines as soon as geoR f(x)s are integrated.
  651. for n in self.GetChildren():
  652. n.Hide()
  653. self.Sizer.Add(
  654. wx.StaticText(
  655. self,
  656. id=wx.ID_ANY,
  657. label=_("Work in progress! No functionality provided.")))
  658. self.SetSizerAndFit(self.Sizer)