GRASS Programmer's Manual  6.4.4(2014)-r
mcalc_builder.py
Go to the documentation of this file.
1 """!
2 @package modules::mcalc_builder
3 
4 @brief Map calculator, GUI wrapper for r.mapcalc
5 
6 Classes:
7  - mcalc_builder::MapCalcFrame
8 
9 (C) 2008, 2011 by the GRASS Development Team
10 
11 This program is free software under the GNU General Public License
12 (>=v2). Read the file COPYING that comes with GRASS for details.
13 
14 @author Michael Barton, Arizona State University
15 @author Martin Landa <landa.martin gmail.com>
16 @author Tim Michelsen (load/save expression)
17 """
18 
19 import os
20 import sys
21 import re
22 
23 if __name__ == "__main__":
24  sys.path.append(os.path.join(os.getenv('GISBASE'), 'etc', 'wxpython'))
25 from core import globalvar
26 import wx
27 
28 import grass.script as grass
29 
30 from core.gcmd import GError, RunCommand
31 from gui_core.gselect import Select
32 from core.settings import UserSettings
33 
34 
35 class MapCalcFrame(wx.Frame):
36  """!Mapcalc Frame class. Calculator-style window to create and run
37  r(3).mapcalc statements.
38  """
39  def __init__(self, parent, cmd, id = wx.ID_ANY,
40  style = wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER, **kwargs):
41  self.parent = parent
42  if self.parent:
43  self.log = self.parent.GetLogWindow()
44  else:
45  self.log = None
46 
47  # grass command
48  self.cmd = cmd
49 
50  if self.cmd == 'r.mapcalc':
51  self.rast3d = False
52  title = _('GRASS GIS Raster Map Calculator')
53  if self.cmd == 'r3.mapcalc':
54  self.rast3d = True
55  title = _('GRASS GIS 3D Raster Map Calculator')
56 
57  wx.Frame.__init__(self, parent, id = id, title = title, **kwargs)
58  self.SetIcon(wx.Icon(os.path.join(globalvar.ETCICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO))
59 
60  self.panel = wx.Panel(parent = self, id = wx.ID_ANY)
61  self.CreateStatusBar()
62 
63  #
64  # variables
65  #
66  self.heading = _('mapcalc statement')
67  self.funct_dict = {
68  'abs(x)':'abs()',
69  'acos(x)':'acos()',
70  'asin(x)':'asin()',
71  'atan(x)':'atan()',
72  'atan(x,y)':'atan( , )',
73  'cos(x)':'cos()',
74  'double(x)':'double()',
75  'eval([x,y,...,]z)':'eval()',
76  'exp(x)':'exp()',
77  'exp(x,y)':'exp( , )',
78  'float(x)':'float()',
79  'graph(x,x1,y1[x2,y2..])':'graph( , , )',
80  'if(x)':'if()',
81  'if(x,a)':'if( , )',
82  'if(x,a,b)':'if( , , )',
83  'if(x,a,b,c)':'if( , , , )',
84  'int(x)':'int()',
85  'isnull(x)':'isnull()',
86  'log(x)':'log(',
87  'log(x,b)':'log( , )',
88  'max(x,y[,z...])':'max( , )',
89  'median(x,y[,z...])':'median( , )',
90  'min(x,y[,z...])':'min( , )',
91  'mode(x,y[,z...])':'mode( , )',
92  'not(x)':'not()',
93  'pow(x,y)':'pow( , )',
94  'rand(a,b)':'rand( , )',
95  'round(x)':'round()',
96  'sin(x)':'sin()',
97  'sqrt(x)':'sqrt()',
98  'tan(x)':'tan()',
99  'xor(x,y)':'xor( , )',
100  'row()':'row()',
101  'col()':'col()',
102  'x()':'x()',
103  'y()':'y()',
104  'ewres()':'ewres()',
105  'nsres()':'nsres()',
106  'null()':'null()'
107  }
108 
109  if self.rast3d:
110  self.funct_dict['z()'] = 'z()'
111  self.funct_dict['tbres()'] = 'tbres()'
112  element = 'rast3d'
113  else:
114  element = 'cell'
115 
116  # characters which can be in raster map name but the map name must be then quoted
117  self.charactersToQuote = '+-&!<>%~?^|'
118  # stores last typed map name in Select widget to distinguish typing from selection
119  self.lastMapName = ''
120 
121  self.operatorBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
122  label=" %s " % _('Operators'))
123  self.operandBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
124  label=" %s " % _('Operands'))
125  self.expressBox = wx.StaticBox(parent = self.panel, id = wx.ID_ANY,
126  label=" %s " % _('Expression'))
127 
128  #
129  # Buttons
130  #
131  self.btn_clear = wx.Button(parent = self.panel, id = wx.ID_CLEAR)
132  self.btn_help = wx.Button(parent = self.panel, id = wx.ID_HELP)
133  self.btn_run = wx.Button(parent = self.panel, id = wx.ID_ANY, label = _("&Run"))
134  self.btn_run.SetForegroundColour(wx.Colour(35, 142, 35))
135  self.btn_run.SetDefault()
136  self.btn_close = wx.Button(parent = self.panel, id = wx.ID_CLOSE)
137  self.btn_save = wx.Button(parent = self.panel, id = wx.ID_SAVE)
138  self.btn_save.SetToolTipString(_('Save expression to file'))
139  self.btn_load = wx.Button(parent = self.panel, id = wx.ID_ANY,
140  label = _("&Load"))
141  self.btn_load.SetToolTipString(_('Load expression from file'))
142 
143  self.btn = dict()
144  self.btn['pow'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "^")
145  self.btn['pow'].SetToolTipString(_('exponent'))
146  self.btn['div'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "/")
147  self.btn['div'].SetToolTipString(_('divide'))
148  self.btn['add'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "+")
149  self.btn['add'].SetToolTipString(_('add'))
150  self.btn['minus'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "-")
151  self.btn['minus'].SetToolTipString(_('subtract'))
152  self.btn['mod'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "%")
153  self.btn['mod'].SetToolTipString(_('modulus'))
154  self.btn['mult'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "*")
155  self.btn['mult'].SetToolTipString(_('multiply'))
156 
157  self.btn['parenl'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "(")
158  self.btn['parenr'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = ")")
159  self.btn['lshift'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "<<")
160  self.btn['lshift'].SetToolTipString(_('left shift'))
161  self.btn['rshift'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = ">>")
162  self.btn['rshift'].SetToolTipString(_('right shift'))
163  self.btn['rshiftu'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = ">>>")
164  self.btn['rshiftu'].SetToolTipString(_('right shift (unsigned)'))
165  self.btn['gt'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = ">")
166  self.btn['gt'].SetToolTipString(_('greater than'))
167  self.btn['gteq'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = ">=")
168  self.btn['gteq'].SetToolTipString(_('greater than or equal to'))
169  self.btn['lt'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "<")
170  self.btn['lt'].SetToolTipString(_('less than'))
171  self.btn['lteq'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "<=")
172  self.btn['lteq'].SetToolTipString(_('less than or equal to'))
173  self.btn['eq'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "==")
174  self.btn['eq'].SetToolTipString(_('equal to'))
175  self.btn['noteq'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "!=")
176  self.btn['noteq'].SetToolTipString(_('not equal to'))
177 
178  self.btn['compl'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "~")
179  self.btn['compl'].SetToolTipString(_('one\'s complement'))
180  self.btn['not'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "!")
181  self.btn['not'].SetToolTipString(_('NOT'))
182  self.btn['andbit'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = '&&')
183  self.btn['andbit'].SetToolTipString(_('bitwise AND'))
184  self.btn['orbit'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "|")
185  self.btn['orbit'].SetToolTipString(_('bitwise OR'))
186  self.btn['and'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "&&&&")
187  self.btn['and'].SetToolTipString(_('logical AND'))
188  self.btn['andnull'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "&&&&&&")
189  self.btn['andnull'].SetToolTipString(_('logical AND (ignores NULLs)'))
190  self.btn['or'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "||")
191  self.btn['or'].SetToolTipString(_('logical OR'))
192  self.btn['ornull'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "|||")
193  self.btn['ornull'].SetToolTipString(_('logical OR (ignores NULLs)'))
194  self.btn['cond'] = wx.Button(parent = self.panel, id = wx.ID_ANY, label = "a ? b : c")
195  self.btn['cond'].SetToolTipString(_('conditional'))
196 
197  #
198  # Text area
199  #
200  self.text_mcalc = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY, size = (-1, 75),
201  style = wx.TE_MULTILINE)
202  wx.CallAfter(self.text_mcalc.SetFocus)
203 
204  #
205  # Map and function insertion text and ComboBoxes
206  self.newmaplabel = wx.StaticText(parent = self.panel, id = wx.ID_ANY)
207  if self.rast3d:
208  self.newmaplabel.SetLabel(_('Name for new 3D raster map to create'))
209  else:
210  self.newmaplabel.SetLabel(_('Name for new raster map to create'))
211  self.newmaptxt = wx.TextCtrl(parent = self.panel, id = wx.ID_ANY, size=(250, -1))
212  self.mapsellabel = wx.StaticText(parent = self.panel, id = wx.ID_ANY)
213  if self.rast3d:
214  self.mapsellabel.SetLabel(_('Insert existing 3D raster map'))
215  else:
216  self.mapsellabel.SetLabel(_('Insert existing raster map'))
217  self.mapselect = Select(parent = self.panel, id = wx.ID_ANY, size = (250, -1),
218  type = element, multiple = False)
219  self.functlabel = wx.StaticText(parent = self.panel, id = wx.ID_ANY,
220  label = _('Insert mapcalc function'))
221  self.function = wx.ComboBox(parent = self.panel, id = wx.ID_ANY,
222  size = (250, -1), choices = sorted(self.funct_dict.keys()),
223  style = wx.CB_DROPDOWN |
224  wx.CB_READONLY | wx.TE_PROCESS_ENTER)
225 
226  self.addbox = wx.CheckBox(parent=self.panel,
227  label=_('Add created raster map into layer tree'), style = wx.NO_BORDER)
228  self.addbox.SetValue(UserSettings.Get(group='cmd', key='addNewLayer', subkey='enabled'))
229  if not self.parent or self.parent.GetName() != 'LayerManager':
230  self.addbox.Hide()
231 
232  #
233  # Bindings
234  #
235  for btn in self.btn.keys():
236  self.btn[btn].Bind(wx.EVT_BUTTON, self.AddMark)
237 
238  self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose)
239  self.btn_clear.Bind(wx.EVT_BUTTON, self.OnClear)
240  self.btn_run.Bind(wx.EVT_BUTTON, self.OnMCalcRun)
241  self.btn_help.Bind(wx.EVT_BUTTON, self.OnHelp)
242  self.btn_save.Bind(wx.EVT_BUTTON, self.OnSaveExpression)
243  self.btn_load.Bind(wx.EVT_BUTTON, self.OnLoadExpression)
244 
245  self.mapselect.Bind(wx.EVT_TEXT, self.OnSelectTextEvt)
246  self.function.Bind(wx.EVT_COMBOBOX, self._return_funct)
247  self.function.Bind(wx.EVT_TEXT_ENTER, self.OnSelect)
248  self.newmaptxt.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar)
249  self.text_mcalc.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar)
250 
251  self._layout()
252 
253  self.SetMinSize(self.GetBestSize())
254 
255  def _return_funct(self,event):
256  i = event.GetString()
257  self._addSomething(self.funct_dict[i])
258 
259  def _layout(self):
260  sizer = wx.BoxSizer(wx.VERTICAL)
261 
262  controlSizer = wx.BoxSizer(wx.HORIZONTAL)
263  operatorSizer = wx.StaticBoxSizer(self.operatorBox, wx.HORIZONTAL)
264 
265  buttonSizer1 = wx.GridBagSizer(5, 1)
266  buttonSizer1.Add(item = self.btn['add'], pos = (0,0))
267  buttonSizer1.Add(item = self.btn['minus'], pos = (0,1))
268  buttonSizer1.Add(item = self.btn['mod'], pos = (5,0))
269  buttonSizer1.Add(item = self.btn['mult'], pos = (1,0))
270  buttonSizer1.Add(item = self.btn['div'], pos = (1,1))
271  buttonSizer1.Add(item = self.btn['pow'], pos = (5,1))
272  buttonSizer1.Add(item = self.btn['gt'], pos = (2,0))
273  buttonSizer1.Add(item = self.btn['gteq'], pos = (2,1))
274  buttonSizer1.Add(item = self.btn['eq'], pos = (4,0))
275  buttonSizer1.Add(item = self.btn['lt'], pos = (3,0))
276  buttonSizer1.Add(item = self.btn['lteq'], pos = (3,1))
277  buttonSizer1.Add(item = self.btn['noteq'], pos = (4,1))
278 
279  buttonSizer2 = wx.GridBagSizer(5, 1)
280  buttonSizer2.Add(item = self.btn['and'], pos = (0,0))
281  buttonSizer2.Add(item = self.btn['andbit'], pos = (1,0))
282  buttonSizer2.Add(item = self.btn['andnull'], pos = (2,0))
283  buttonSizer2.Add(item = self.btn['or'], pos = (0,1))
284  buttonSizer2.Add(item = self.btn['orbit'], pos = (1,1))
285  buttonSizer2.Add(item = self.btn['ornull'], pos = (2,1))
286  buttonSizer2.Add(item = self.btn['lshift'], pos = (3,0))
287  buttonSizer2.Add(item = self.btn['rshift'], pos = (3,1))
288  buttonSizer2.Add(item = self.btn['rshiftu'], pos = (4,0))
289  buttonSizer2.Add(item = self.btn['cond'], pos = (5,0))
290  buttonSizer2.Add(item = self.btn['compl'], pos = (5,1))
291  buttonSizer2.Add(item = self.btn['not'], pos = (4,1))
292 
293  operandSizer = wx.StaticBoxSizer(self.operandBox, wx.HORIZONTAL)
294  buttonSizer3 = wx.GridBagSizer(7, 1)
295  buttonSizer3.Add(item = self.newmaplabel, pos = (0,0),
296  span = (1, 2), flag = wx.ALIGN_CENTER)
297  buttonSizer3.Add(item = self.newmaptxt, pos = (1,0),
298  span = (1, 2))
299  buttonSizer3.Add(item = self.functlabel, pos = (2,0),
300  span = (1,2), flag = wx.ALIGN_CENTER)
301  buttonSizer3.Add(item = self.function, pos = (3,0),
302  span = (1,2))
303  buttonSizer3.Add(item = self.mapsellabel, pos = (4,0),
304  span = (1,2), flag = wx.ALIGN_CENTER)
305  buttonSizer3.Add(item = self.mapselect, pos = (5,0),
306  span = (1,2))
307  threebutton = wx.GridBagSizer(1, 2)
308  threebutton.Add(item = self.btn['parenl'], pos = (0,0),
309  span = (1,1), flag = wx.ALIGN_LEFT)
310  threebutton.Add(item = self.btn['parenr'], pos = (0,1),
311  span = (1,1), flag = wx.ALIGN_CENTER)
312  threebutton.Add(item = self.btn_clear, pos = (0,2),
313  span = (1,1), flag = wx.ALIGN_RIGHT)
314  buttonSizer3.Add(item = threebutton, pos = (6,0),
315  span = (1,1), flag = wx.ALIGN_CENTER)
316 
317  buttonSizer4 = wx.BoxSizer(wx.HORIZONTAL)
318  buttonSizer4.AddSpacer(10)
319  buttonSizer4.Add(item = self.btn_load,
320  flag = wx.ALL, border = 5)
321  buttonSizer4.Add(item = self.btn_save,
322  flag = wx.ALL, border = 5)
323  buttonSizer4.AddSpacer(30)
324  buttonSizer4.Add(item = self.btn_help,
325  flag = wx.ALL, border = 5)
326  buttonSizer4.Add(item = self.btn_run,
327  flag = wx.ALL, border = 5)
328  buttonSizer4.Add(item = self.btn_close,
329  flag = wx.ALL, border = 5)
330 
331  operatorSizer.Add(item = buttonSizer1, proportion = 0,
332  flag = wx.ALL | wx.EXPAND, border = 5)
333  operatorSizer.Add(item = buttonSizer2, proportion = 0,
334  flag = wx.TOP | wx.BOTTOM | wx.RIGHT | wx.EXPAND, border = 5)
335 
336  operandSizer.Add(item = buttonSizer3, proportion = 0,
337  flag = wx.TOP | wx.BOTTOM | wx.RIGHT, border = 5)
338 
339  controlSizer.Add(item = operatorSizer, proportion = 1,
340  flag = wx.RIGHT | wx.EXPAND, border = 5)
341  controlSizer.Add(item = operandSizer, proportion = 0,
342  flag = wx.EXPAND)
343 
344  expressSizer = wx.StaticBoxSizer(self.expressBox, wx.HORIZONTAL)
345  expressSizer.Add(item = self.text_mcalc, proportion = 1,
346  flag = wx.EXPAND)
347 
348  sizer.Add(item = controlSizer, proportion = 0,
349  flag = wx.EXPAND | wx.ALL,
350  border = 5)
351  sizer.Add(item = expressSizer, proportion = 1,
352  flag = wx.EXPAND | wx.LEFT | wx.RIGHT,
353  border = 5)
354  sizer.Add(item = buttonSizer4, proportion = 0,
355  flag = wx.ALIGN_RIGHT | wx.ALL, border = 3)
356  if self.addbox.IsShown():
357  sizer.Add(item = self.addbox, proportion = 0,
358  flag = wx.LEFT | wx.RIGHT,
359  border = 5)
360 
361  self.panel.SetAutoLayout(True)
362  self.panel.SetSizer(sizer)
363  sizer.Fit(self.panel)
364 
365  self.Layout()
366 
367  def AddMark(self,event):
368  """!Sends operators to insertion method
369  """
370  if event.GetId() == self.btn['compl'].GetId(): mark = "~"
371  elif event.GetId() == self.btn['not'].GetId(): mark = "!"
372  elif event.GetId() == self.btn['pow'].GetId(): mark = "^"
373  elif event.GetId() == self.btn['div'].GetId(): mark = "/"
374  elif event.GetId() == self.btn['add'].GetId(): mark = "+"
375  elif event.GetId() == self.btn['minus'].GetId(): mark = "-"
376  elif event.GetId() == self.btn['mod'].GetId(): mark = "%"
377  elif event.GetId() == self.btn['mult'].GetId(): mark = "*"
378  elif event.GetId() == self.btn['lshift'].GetId(): mark = "<<"
379  elif event.GetId() == self.btn['rshift'].GetId(): mark = ">>"
380  elif event.GetId() == self.btn['rshiftu'].GetId(): mark = ">>>"
381  elif event.GetId() == self.btn['gt'].GetId(): mark = ">"
382  elif event.GetId() == self.btn['gteq'].GetId(): mark = ">="
383  elif event.GetId() == self.btn['lt'].GetId(): mark = "<"
384  elif event.GetId() == self.btn['lteq'].GetId(): mark = "<="
385  elif event.GetId() == self.btn['eq'].GetId(): mark = "=="
386  elif event.GetId() == self.btn['noteq'].GetId(): mark = "!="
387  elif event.GetId() == self.btn['andbit'].GetId(): mark = "&"
388  elif event.GetId() == self.btn['orbit'].GetId(): mark = "|"
389  elif event.GetId() == self.btn['or'].GetId(): mark = "||"
390  elif event.GetId() == self.btn['ornull'].GetId(): mark = "|||"
391  elif event.GetId() == self.btn['and'].GetId(): mark = "&&"
392  elif event.GetId() == self.btn['andnull'].GetId(): mark = "&&&"
393  elif event.GetId() == self.btn['cond'].GetId(): mark = " ? : "
394  elif event.GetId() == self.btn['parenl'].GetId(): mark = "("
395  elif event.GetId() == self.btn['parenr'].GetId(): mark = ")"
396  self._addSomething(mark)
397 
398  def OnSelectTextEvt(self, event):
399  """!Checks if user is typing or the event was emited by map selection.
400  Prevents from changing focus.
401  """
402  item = event.GetString()
403  if not (abs(len(item) - len(self.lastMapName)) == 1 and \
404  self.lastMapName in item or item in self.lastMapName):
405  self.OnSelect(event)
406  self.lastMapName = item
407 
408  def OnSelect(self, event):
409  """!Gets raster map or function selection and send it to
410  insertion method.
411 
412  Checks for characters which can be in raster map name but
413  the raster map name must be then quoted.
414  """
415  item = event.GetString().strip()
416  if any((char in item) for char in self.charactersToQuote):
417  item = '"' + item + '"'
418  self._addSomething(item)
419 
420  def OnUpdateStatusBar(self, event):
421  """!Update statusbar text"""
422  expr = self.text_mcalc.GetValue().strip().replace("\n", " ")
423  cmd = 'r.mapcalc'
424  if self.rast3d:
425  cmd = 'r3.mapcalc'
426  self.SetStatusText("%s '%s = %s'" % (cmd, self.newmaptxt.GetValue(),
427  expr))
428  event.Skip()
429 
430  def _addSomething(self, what):
431  """!Inserts operators, map names, and functions into text area
432  """
433  self.text_mcalc.SetFocus()
434  mcalcstr = self.text_mcalc.GetValue()
435  position = self.text_mcalc.GetInsertionPoint()
436 
437  newmcalcstr = mcalcstr[:position]
438 
439  position_offset = 0
440  try:
441  if newmcalcstr[-1] != ' ':
442  newmcalcstr += ' '
443  position_offset += 1
444  except:
445  pass
446 
447  newmcalcstr += what + ' ' + mcalcstr[position:]
448 
449  self.text_mcalc.SetValue(newmcalcstr)
450  if len(what) > 1:
451  match = re.search(pattern="\(.*\)", string=what)
452  if match:
453  position_offset += match.start() + 1
454  else:
455  position_offset += len(what)
456 
457  self.text_mcalc.SetInsertionPoint(position + position_offset)
458  self.text_mcalc.Update()
459 
460  def OnMCalcRun(self,event):
461  """!Builds and runs r.mapcalc statement
462  """
463  name = self.newmaptxt.GetValue().strip()
464  if not name:
465  GError(parent = self,
466  message = _("You must enter the name of "
467  "a new raster map to create."))
468  return
469 
470  if not (name[0] == '"' and name[-1] == '"') and any((char in name) for char in self.charactersToQuote):
471  name = '"' + name + '"'
472 
473  expr = self.text_mcalc.GetValue().strip().replace("\n", " ")
474  if not expr:
475  GError(parent = self,
476  message = _("You must enter an expression "
477  "to create a new raster map."))
478  return
479 
480  if self.log:
481  cmd = [self.cmd, str('%s = %s' % (name, expr))]
482  self.log.RunCmd(cmd, onDone = self.OnDone)
483  self.parent.Raise()
484  else:
485  RunCommand(self.cmd,
486  **{name: expr})
487 
488  def OnDone(self, cmd, returncode):
489  """!Add create map to the layer tree"""
490  if not self.addbox.IsChecked():
491  return
492  name = self.newmaptxt.GetValue().strip(' "') + '@' + grass.gisenv()['MAPSET']
493  ltype = 'raster'
494  lcmd = 'd.rast'
495  if self.rast3d:
496  ltype = '3d-raster'
497  lcmd = 'd.rast3d.py'
498  mapTree = self.parent.GetLayerTree()
499  if not mapTree.GetMap().GetListOfLayers(l_name = name):
500  mapTree.AddLayer(ltype = ltype,
501  lname = name,
502  lcmd = [lcmd, 'map=%s' % name],
503  multiple = False)
504 
505  display = self.parent.GetLayerTree().GetMapDisplay()
506  if display and display.IsAutoRendered():
507  display.GetWindow().UpdateMap(render = True)
508 
509  def OnSaveExpression(self, event):
510  """!Saves expression to file
511  """
512  mctxt = self.newmaptxt.GetValue() + ' = ' + self.text_mcalc.GetValue() + os.linesep
513 
514  #dialog
515  dlg = wx.FileDialog(parent = self,
516  message = _("Choose a file name to save the expression"),
517  wildcard = _("Expression file (*)|*"),
518  style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
519  if dlg.ShowModal() == wx.ID_OK:
520  path = dlg.GetPath()
521  if not path:
522  dlg.Destroy()
523  return
524 
525  try:
526  fobj = open(path, 'w')
527  fobj.write(mctxt)
528  finally:
529  fobj.close()
530 
531  dlg.Destroy()
532 
533  def OnLoadExpression(self, event):
534  """!Load expression from file
535  """
536  dlg = wx.FileDialog(parent = self,
537  message = _("Choose a file name to load the expression"),
538  wildcard = _("Expression file (*)|*"),
539  style = wx.FD_OPEN)
540  if dlg.ShowModal() == wx.ID_OK:
541  path = dlg.GetPath()
542  if not path:
543  dlg.Destroy()
544  return
545 
546  try:
547  fobj = open(path,'r')
548  mctxt = fobj.read()
549  finally:
550  fobj.close()
551 
552  try:
553  result, exp = mctxt.split('=', 1)
554  except ValueError:
555  result = ''
556  exp = mctxt
557 
558  self.newmaptxt.SetValue(result.strip())
559  self.text_mcalc.SetValue(exp.strip())
560  self.text_mcalc.SetFocus()
561  self.text_mcalc.SetInsertionPointEnd()
562 
563  dlg.Destroy()
564 
565  def OnClear(self, event):
566  """!Clears text area
567  """
568  self.text_mcalc.SetValue('')
569 
570  def OnHelp(self, event):
571  """!Launches r.mapcalc help
572  """
573  RunCommand('g.manual', parent = self, entry = self.cmd)
574 
575  def OnClose(self,event):
576  """!Close window"""
577  self.Destroy()
578 
579 if __name__ == "__main__":
580  import gettext
581  gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'), unicode = True)
582 
583  app = wx.App(0)
584  frame = MapCalcFrame(parent = None, cmd = 'r.mapcalc')
585  frame.Show()
586  app.MainLoop()
wxGUI command interface
def AddMark(self, event)
Sends operators to insertion method.
def OnUpdateStatusBar(self, event)
Update statusbar text.
def OnClose(self, event)
Close window.
def OnSelectTextEvt(self, event)
Checks if user is typing or the event was emited by map selection.
def OnLoadExpression(self, event)
Load expression from file.
Mapcalc Frame class.
def OnHelp(self, event)
Launches r.mapcalc help.
def __init__(self, parent, cmd, id=wx.ID_ANY, style=wx.DEFAULT_FRAME_STYLE|wx.RESIZE_BORDER, kwargs)
Custom control that selects elements.
def _return_funct(self, event)
def OnDone(self, cmd, returncode)
Add create map to the layer tree.
def OnClear(self, event)
Clears text area.
def OnSaveExpression(self, event)
Saves expression to file.
def _addSomething(self, what)
Inserts operators, map names, and functions into text area.
def RunCommand(prog, flags="", overwrite=False, quiet=False, verbose=False, parent=None, read=False, stdin=None, getErrorMsg=False, kwargs)
Run GRASS command.
Definition: gcmd.py:633
Default GUI settings.
def OnSelect(self, event)
Gets raster map or function selection and send it to insertion method.
def OnMCalcRun(self, event)
Builds and runs r.mapcalc statement.