vkrige.py 28 KB

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