def _do_layout(self): sizer = wx.BoxSizer(wx.VERTICAL) box = wx.GridBagSizer(hgap=3, vgap=3) rastText = '' for r in self.rasterList: rastText += '%s,' % r rastText = rastText.rstrip(',') txt = _("Select raster map(s) to profile:") label = wx.StaticText(parent=self, id=wx.ID_ANY, label=txt) box.Add(item=label, flag=wx.ALIGN_CENTER_VERTICAL, pos=(0, 0)) selection = Select(self, id=wx.ID_ANY, size=globalvar.DIALOG_GSELECT_SIZE, type='cell', multiple=True) selection.SetValue(rastText) selection.Bind(wx.EVT_TEXT, self.OnSelection) box.Add(item=selection, pos=(0, 1)) sizer.Add(item=box, proportion=0, flag=wx.ALL, border=10) line = wx.StaticLine(parent=self, id=wx.ID_ANY, size=(20, -1), style=wx.LI_HORIZONTAL) sizer.Add(item=line, proportion=0, flag=wx.GROW | wx.ALIGN_CENTER_VERTICAL | wx.LEFT | wx.RIGHT, border=5) btnsizer = wx.StdDialogButtonSizer() btn = wx.Button(self, wx.ID_OK) btn.SetDefault() btnsizer.AddButton(btn) btn = wx.Button(self, wx.ID_CANCEL) btnsizer.AddButton(btn) btnsizer.Realize() sizer.Add(item=btnsizer, proportion=0, flag=wx.ALIGN_RIGHT | wx.ALL, border=5) self.SetSizer(sizer) sizer.Fit(self)
class ExportCategoryRaster(wx.Dialog): def __init__(self, parent, title, rasterName=None, id=wx.ID_ANY, style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER, **kwargs): """Dialog for export of category raster. :param parent: window :param str rasterName name of vector layer for export :param title: window title """ wx.Dialog.__init__(self, parent, id, title, style=style, **kwargs) self.rasterName = rasterName self.panel = wx.Panel(parent=self, id=wx.ID_ANY) self.btnCancel = Button(parent=self.panel, id=wx.ID_CANCEL) self.btnOK = Button(parent=self.panel, id=wx.ID_OK) self.btnOK.SetDefault() self.btnOK.Enable(False) self.btnOK.Bind(wx.EVT_BUTTON, self.OnOK) self.__layout() self.vectorNameCtrl.Bind(wx.EVT_TEXT, self.OnTextChanged) self.OnTextChanged(None) wx.CallAfter(self.vectorNameCtrl.SetFocus) def OnTextChanged(self, event): """Name of new vector map given. Enable/diable OK button. """ file = self.vectorNameCtrl.GetValue() if len(file) > 0: self.btnOK.Enable(True) else: self.btnOK.Enable(False) def __layout(self): """Do layout""" sizer = wx.BoxSizer(wx.VERTICAL) dataSizer = wx.BoxSizer(wx.VERTICAL) dataSizer.Add( StaticText( parent=self.panel, id=wx.ID_ANY, label=_("Enter name of new vector map:")), proportion=0, flag=wx.ALL, border=3) self.vectorNameCtrl = Select(parent=self.panel, type='raster', mapsets=[grass.gisenv()['MAPSET']], size=globalvar.DIALOG_GSELECT_SIZE) if self.rasterName: self.vectorNameCtrl.SetValue(self.rasterName) dataSizer.Add(self.vectorNameCtrl, proportion=0, flag=wx.ALL | wx.EXPAND, border=3) # buttons btnSizer = wx.StdDialogButtonSizer() btnSizer.AddButton(self.btnCancel) btnSizer.AddButton(self.btnOK) btnSizer.Realize() sizer.Add(dataSizer, proportion=1, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5) sizer.Add(btnSizer, proportion=0, flag=wx.EXPAND | wx.ALL | wx.ALIGN_CENTER, border=5) self.panel.SetSizer(sizer) sizer.Fit(self) self.SetMinSize(self.GetSize()) def GetRasterName(self): """Returns vector name""" return self.vectorNameCtrl.GetValue() def OnOK(self, event): """Checks if map exists and can be overwritten.""" overwrite = UserSettings.Get( group='cmd', key='overwrite', subkey='enabled') rast_name = self.GetRasterName() res = grass.find_file(rast_name, element='cell') if res['fullname'] and overwrite is False: qdlg = wx.MessageDialog( parent=self, message=_( "Raster map <%s> already exists." " Do you want to overwrite it?" % rast_name), caption=_( "Raster <%s> exists" % rast_name), style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION | wx.CENTRE) if qdlg.ShowModal() == wx.ID_YES: event.Skip() qdlg.Destroy() else: event.Skip()
class ModelDataDialog(SimpleDialog): """Data item properties dialog""" def __init__(self, parent, shape, title=_("Data properties")): self.parent = parent self.shape = shape label, etype = self._getLabel() self.etype = etype SimpleDialog.__init__(self, parent, title) self.element = Select( parent=self.panel, type=self.shape.GetPrompt(), validator=SimpleValidator( callback=self.ValidatorCallback)) if shape.GetValue(): self.element.SetValue(shape.GetValue()) self.Bind(wx.EVT_BUTTON, self.OnOK, self.btnOK) self.Bind(wx.EVT_BUTTON, self.OnCancel, self.btnCancel) if self.etype: self.typeSelect = ElementSelect( parent=self.panel, elements=[ 'raster', 'raster_3d', 'vector'], size=globalvar.DIALOG_GSELECT_SIZE) self.typeSelect.Bind(wx.EVT_CHOICE, self.OnType) self.typeSelect.SetSelection(0) self.element.SetType('raster') if shape.GetValue(): self.btnOK.Enable() self._layout() self.SetMinSize(self.GetSize()) def _getLabel(self): etype = False prompt = self.shape.GetPrompt() if prompt == 'raster': label = _('Name of raster map:') elif prompt == 'vector': label = _('Name of vector map:') else: etype = True label = _('Name of element:') return label, etype def _layout(self): """Do layout""" if self.etype: self.dataSizer.Add( StaticText( parent=self.panel, id=wx.ID_ANY, label=_("Type of element:")), proportion=0, flag=wx.ALL, border=1) self.dataSizer.Add(self.typeSelect, proportion=0, flag=wx.ALL, border=1) self.dataSizer.Add(StaticText(parent=self.panel, id=wx.ID_ANY, label=_("Name of element:")), proportion=0, flag=wx.ALL, border=1) self.dataSizer.Add(self.element, proportion=0, flag=wx.EXPAND | wx.ALL, border=1) self.panel.SetSizer(self.sizer) self.sizer.Fit(self) def GetType(self): """Get element type""" if not self.etype: return return self.element.tcp.GetType() def OnType(self, event): """Select element type""" evalue = self.typeSelect.GetValue(event.GetString()) self.element.SetType(evalue) def OnOK(self, event): """Ok pressed""" self.shape.SetValue(self.element.GetValue()) if self.etype: elem = self.GetType() if elem == 'raster': self.shape.SetPrompt('raster') elif elem == 'vector': self.shape.SetPrompt('vector') elif elem == 'raster_3d': self.shape.SetPrompt('raster_3d') self.parent.canvas.Refresh() self.parent.SetStatusText('', 0) self.shape.SetPropDialog(None) if self.IsModal(): event.Skip() else: self.Destroy() def OnCancel(self, event): """Cancel pressed""" self.shape.SetPropDialog(None) if self.IsModal(): event.Skip() else: self.Destroy()
class AnalysesPanel(wx.Panel): def __init__(self, parent, giface, settings): wx.Panel.__init__(self, parent) self.giface = giface self.settings = settings mainSizer = wx.BoxSizer(wx.VERTICAL) if self.settings['analyses']['file']: path = self.settings['analyses']['file'] initDir = os.path.dirname(path) else: path = initDir = "" self.contoursSelect = Select(self, size=(-1, -1), type='vector') self.contoursStepTextCtrl = wx.TextCtrl(self, size=(40, -1)) self.contoursStepTextCtrl.SetToolTipString("Contour step") if 'contours' in self.settings['analyses'] and self.settings[ 'analyses']['contours']: self.contoursStepTextCtrl.SetValue( str(self.settings['analyses']['contours_step'])) self.contoursSelect.SetValue(self.settings['analyses']['contours']) self.contoursSelect.Bind(wx.EVT_TEXT, self.OnAnalysesChange) self.contoursStepTextCtrl.Bind(wx.EVT_TEXT, self.OnAnalysesChange) self.selectAnalyses = filebrowse.FileBrowseButton( self, labelText="Analyses:", startDirectory=initDir, initialValue=path, changeCallback=lambda evt: self.SetAnalysesFile(evt.GetString())) if self.settings['analyses']['file']: self.selectAnalyses.SetValue(self.settings['analyses']['file']) newAnalyses = wx.Button(self, label="Create new file") newAnalyses.Bind(wx.EVT_BUTTON, lambda evt: self.CreateNewFile()) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(wx.StaticText(self, label="Contours:"), proportion=0, flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, border=5) sizer.Add(self.contoursSelect, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, border=5) sizer.Add(self.contoursStepTextCtrl, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL, border=5) mainSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.selectAnalyses, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, border=5) mainSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.AddStretchSpacer() sizer.Add(newAnalyses, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, border=5) mainSizer.Add(sizer, flag=wx.EXPAND | wx.LEFT | wx.RIGHT | wx.BOTTOM, border=5) self.SetSizer(mainSizer) mainSizer.Fit(self) def SetAnalysesFile(self, path): self.settings['analyses']['file'] = path def OnAnalysesChange(self, event): self.settings['analyses']['contours'] = self.contoursSelect.GetValue() self.settings['analyses'][ 'contours_step'] = self.contoursStepTextCtrl.GetValue() def CreateNewFile(self): get_lib_path('g.gui.tangible') dlg = wx.FileDialog(self, message="Create a new file with analyses", wildcard="Python source (*.py)|*.py", style=wx.SAVE | wx.FD_OVERWRITE_PROMPT) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() orig = os.path.join(get_lib_path('g.gui.tangible'), 'current_analyses.py') if not os.path.exists(orig): self.giface.WriteError( "File with analyses not found: {}".format(orig)) else: copyfile(orig, path) self.selectAnalyses.SetValue(path) self.settings['analyses']['file'] = path dlg.Destroy()
class ScanningPanel(wx.Panel): def __init__(self, parent, giface, settings): wx.Panel.__init__(self, parent) self.giface = giface self.settings = settings self.scan = self.settings['scan'] self.settingsChanged = Signal('ScanningPanel.settingsChanged') mainSizer = wx.BoxSizer(wx.VERTICAL) hSizer = wx.BoxSizer(wx.HORIZONTAL) # create widgets self.scan_name_ctrl = wx.TextCtrl(self, value='scan') # widgets for model self.elevInput = Select(self, size=(-1, -1), type='raster') self.regionInput = Select(self, size=(-1, -1), type='region') self.zexag = wx.TextCtrl(self) self.numscans = wx.SpinCtrl(self, min=1, max=5, initial=1) self.rotate = wx.SpinCtrl(self, min=0, max=360, initial=180) self.smooth = wx.TextCtrl(self) self.resolution = wx.TextCtrl(self) self.trim = {} for each in 'tbnsew': self.trim[each] = wx.TextCtrl(self, size=(40, -1)) self.trim_tolerance = wx.TextCtrl(self) self.interpolate = wx.CheckBox( self, label="Use interpolation instead of binning") self.equalize = wx.CheckBox(self, label="Use equalized color table for scan") self.elevInput.SetValue(self.scan['elevation']) self.regionInput.SetValue(self.scan['region']) self.zexag.SetValue(str(self.scan['zexag'])) self.rotate.SetValue(self.scan['rotation_angle']) self.numscans.SetValue(self.scan['numscans']) self.interpolate.SetValue(self.scan['interpolate']) for i, each in enumerate('nsewtb'): self.trim[each].SetValue(self.scan['trim_nsewtb'].split(',')[i]) self.equalize.SetValue(self.scan['equalize']) self.smooth.SetValue(str(self.scan['smooth'])) self.resolution.SetValue(str(self.scan['resolution'])) self.trim_tolerance.SetValue(str(self.scan['trim_tolerance'])) # layout mainSizer.Add(hSizer, flag=wx.EXPAND) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Name of scanned raster:"), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) hSizer.Add(self.scan_name_ctrl, proportion=1, flag=wx.EXPAND | wx.ALL, border=5) mainSizer.Add(hSizer, flag=wx.EXPAND) # model parameters hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Reference DEM:"), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) hSizer.Add(self.elevInput, proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) mainSizer.Add(hSizer, flag=wx.EXPAND) # region hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Reference region:"), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) hSizer.Add(self.regionInput, proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) mainSizer.Add(hSizer, flag=wx.EXPAND) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Z-exaggeration:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) hSizer.Add(self.zexag, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) mainSizer.Add(hSizer, flag=wx.EXPAND) # number of scans hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Number of scans:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) hSizer.Add(self.numscans, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) mainSizer.Add(hSizer, flag=wx.EXPAND) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Rotation angle:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) hSizer.Add(self.rotate, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) mainSizer.Add(hSizer, flag=wx.EXPAND) # smooth hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Smooth value:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) hSizer.Add(self.smooth, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) mainSizer.Add(hSizer, flag=wx.EXPAND) # resolution hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Resolution [mm]:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) hSizer.Add(self.resolution, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) mainSizer.Add(hSizer, flag=wx.EXPAND) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Limit scan vertically T, B [cm]:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) for each in 'tb': hSizer.Add(self.trim[each], flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) mainSizer.Add(hSizer, flag=wx.EXPAND) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Trim scan N, S, E, W [cm]:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) for each in 'nsew': hSizer.Add(self.trim[each], flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) mainSizer.Add(hSizer, flag=wx.EXPAND) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Trim tolerance [0-1]:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) hSizer.Add(self.trim_tolerance, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) mainSizer.Add(hSizer, flag=wx.EXPAND) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(self.interpolate, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) mainSizer.Add(hSizer, flag=wx.EXPAND) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(self.equalize, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) mainSizer.Add(hSizer, flag=wx.EXPAND) self.SetSizer(mainSizer) mainSizer.Fit(self) self.BindModelProperties() def BindModelProperties(self): self.scan_name_ctrl.Bind(wx.EVT_TEXT, self.OnModelProperties) # model parameters self.elevInput.Bind(wx.EVT_TEXT, self.OnModelProperties) self.regionInput.Bind(wx.EVT_TEXT, self.OnModelProperties) self.zexag.Bind(wx.EVT_TEXT, self.OnModelProperties) self.rotate.Bind(wx.EVT_SPINCTRL, self.OnModelProperties) self.rotate.Bind(wx.EVT_TEXT, self.OnModelProperties) self.numscans.Bind(wx.EVT_SPINCTRL, self.OnModelProperties) self.numscans.Bind(wx.EVT_TEXT, self.OnModelProperties) self.interpolate.Bind(wx.EVT_CHECKBOX, self.OnModelProperties) self.equalize.Bind(wx.EVT_CHECKBOX, self.OnModelProperties) self.smooth.Bind(wx.EVT_TEXT, self.OnModelProperties) self.resolution.Bind(wx.EVT_TEXT, self.OnModelProperties) self.trim_tolerance.Bind(wx.EVT_TEXT, self.OnModelProperties) for each in 'nsewtb': self.trim[each].Bind(wx.EVT_TEXT, self.OnModelProperties) def OnModelProperties(self, event): self.scan['scan_name'] = self.scan_name_ctrl.GetValue() self.scan['elevation'] = self.elevInput.GetValue() self.scan['region'] = self.regionInput.GetValue() self.scan['rotation_angle'] = self.rotate.GetValue() self.scan['numscans'] = self.numscans.GetValue() self.scan['interpolate'] = self.interpolate.IsChecked() self.scan['equalize'] = self.equalize.IsChecked() self.scan['smooth'] = self.smooth.GetValue() self.scan['resolution'] = self.resolution.GetValue() self.scan['trim_tolerance'] = self.trim_tolerance.GetValue() try: self.scan['zexag'] = float(self.zexag.GetValue()) nsewtb_list = [] for each in 'nsewtb': nsewtb_list.append(self.trim[each].GetValue()) self.scan['trim_nsewtb'] = ','.join(nsewtb_list) except ValueError: pass self.settingsChanged.emit()
class MapCalcFrame(wx.Frame): """Mapcalc Frame class. Calculator-style window to create and run r(3).mapcalc statements. """ def __init__(self, parent, giface, cmd, id=wx.ID_ANY, style=wx.DEFAULT_FRAME_STYLE | wx.RESIZE_BORDER, **kwargs): self.parent = parent self._giface = giface if self.parent: self.log = self.parent.GetLogWindow() else: self.log = None # grass command self.cmd = cmd if self.cmd == 'r.mapcalc': self.rast3d = False title = _('GRASS GIS Raster Map Calculator') if self.cmd == 'r3.mapcalc': self.rast3d = True title = _('GRASS GIS 3D Raster Map Calculator') wx.Frame.__init__(self, parent, id=id, title=title, **kwargs) self.SetIcon( wx.Icon(os.path.join(globalvar.ICONDIR, 'grass.ico'), wx.BITMAP_TYPE_ICO)) self.panel = wx.Panel(parent=self, id=wx.ID_ANY) self.CreateStatusBar() # # variables # self.heading = _('mapcalc statement') self.funct_dict = { 'abs(x)': 'abs()', 'acos(x)': 'acos()', 'asin(x)': 'asin()', 'atan(x)': 'atan()', 'atan(x,y)': 'atan( , )', 'cos(x)': 'cos()', 'double(x)': 'double()', 'eval([x,y,...,]z)': 'eval()', 'exp(x)': 'exp()', 'exp(x,y)': 'exp( , )', 'float(x)': 'float()', 'graph(x,x1,y1[x2,y2..])': 'graph( , , )', 'if(x)': 'if()', 'if(x,a)': 'if( , )', 'if(x,a,b)': 'if( , , )', 'if(x,a,b,c)': 'if( , , , )', 'int(x)': 'int()', 'isnull(x)': 'isnull()', 'log(x)': 'log(', 'log(x,b)': 'log( , )', 'max(x,y[,z...])': 'max( , )', 'median(x,y[,z...])': 'median( , )', 'min(x,y[,z...])': 'min( , )', 'mode(x,y[,z...])': 'mode( , )', 'nmax(x,y[,z...])': 'nmax( , )', 'nmedian(x,y[,z...])': 'nmedian( , )', 'nmin(x,y[,z...])': 'nmin( , )', 'nmode(x,y[,z...])': 'nmode( , )', 'not(x)': 'not()', 'pow(x,y)': 'pow( , )', 'rand(a,b)': 'rand( , )', 'round(x)': 'round()', 'round(x,y)': 'round( , )', 'round(x,y,z)': 'round( , , )', 'sin(x)': 'sin()', 'sqrt(x)': 'sqrt()', 'tan(x)': 'tan()', 'xor(x,y)': 'xor( , )', 'row()': 'row()', 'col()': 'col()', 'nrows()': 'nrows()', 'ncols()': 'ncols()', 'x()': 'x()', 'y()': 'y()', 'ewres()': 'ewres()', 'nsres()': 'nsres()', 'area()': 'area()', 'null()': 'null()' } if self.rast3d: self.funct_dict['z()'] = 'z()' self.funct_dict['tbres()'] = 'tbres()' element = 'raster_3d' else: element = 'cell' # characters which can be in raster map name but the map name must be # then quoted self.charactersToQuote = '+-&!<>%~?^|' # stores last typed map name in Select widget to distinguish typing # from selection self.lastMapName = '' self.operatorBox = StaticBox(parent=self.panel, id=wx.ID_ANY, label=" %s " % _('Operators')) self.outputBox = StaticBox(parent=self.panel, id=wx.ID_ANY, label=" %s " % _('Output')) self.operandBox = StaticBox(parent=self.panel, id=wx.ID_ANY, label=" %s " % _('Operands')) self.expressBox = StaticBox(parent=self.panel, id=wx.ID_ANY, label=" %s " % _('Expression')) # # Buttons # self.btn_clear = ClearButton(parent=self.panel) self.btn_help = Button(parent=self.panel, id=wx.ID_HELP) self.btn_run = Button(parent=self.panel, id=wx.ID_ANY, label=_("&Run")) self.btn_run.SetDefault() self.btn_close = CloseButton(parent=self.panel) self.btn_save = Button(parent=self.panel, id=wx.ID_SAVE) self.btn_save.SetToolTip(_('Save expression to file')) self.btn_load = Button(parent=self.panel, id=wx.ID_ANY, label=_("&Load")) self.btn_load.SetToolTip(_('Load expression from file')) self.btn_copy = Button(parent=self.panel, id=wx.ID_ANY, label=_("Copy")) self.btn_copy.SetToolTip( _("Copy the current command string to the clipboard")) self.btn = dict() self.btn['pow'] = Button(parent=self.panel, id=wx.ID_ANY, label="^") self.btn['pow'].SetToolTip(_('exponent')) self.btn['div'] = Button(parent=self.panel, id=wx.ID_ANY, label="/") self.btn['div'].SetToolTip(_('divide')) self.btn['add'] = Button(parent=self.panel, id=wx.ID_ANY, label="+") self.btn['add'].SetToolTip(_('add')) self.btn['minus'] = Button(parent=self.panel, id=wx.ID_ANY, label="-") self.btn['minus'].SetToolTip(_('subtract')) self.btn['mod'] = Button(parent=self.panel, id=wx.ID_ANY, label="%") self.btn['mod'].SetToolTip(_('modulus')) self.btn['mult'] = Button(parent=self.panel, id=wx.ID_ANY, label="*") self.btn['mult'].SetToolTip(_('multiply')) self.btn['parenl'] = Button(parent=self.panel, id=wx.ID_ANY, label="(") self.btn['parenr'] = Button(parent=self.panel, id=wx.ID_ANY, label=")") self.btn['lshift'] = Button(parent=self.panel, id=wx.ID_ANY, label="<<") self.btn['lshift'].SetToolTip(_('left shift')) self.btn['rshift'] = Button(parent=self.panel, id=wx.ID_ANY, label=">>") self.btn['rshift'].SetToolTip(_('right shift')) self.btn['rshiftu'] = Button(parent=self.panel, id=wx.ID_ANY, label=">>>") self.btn['rshiftu'].SetToolTip(_('right shift (unsigned)')) self.btn['gt'] = Button(parent=self.panel, id=wx.ID_ANY, label=">") self.btn['gt'].SetToolTip(_('greater than')) self.btn['gteq'] = Button(parent=self.panel, id=wx.ID_ANY, label=">=") self.btn['gteq'].SetToolTip(_('greater than or equal to')) self.btn['lt'] = Button(parent=self.panel, id=wx.ID_ANY, label="<") self.btn['lt'].SetToolTip(_('less than')) self.btn['lteq'] = Button(parent=self.panel, id=wx.ID_ANY, label="<=") self.btn['lteq'].SetToolTip(_('less than or equal to')) self.btn['eq'] = Button(parent=self.panel, id=wx.ID_ANY, label="==") self.btn['eq'].SetToolTip(_('equal to')) self.btn['noteq'] = Button(parent=self.panel, id=wx.ID_ANY, label="!=") self.btn['noteq'].SetToolTip(_('not equal to')) self.btn['compl'] = Button(parent=self.panel, id=wx.ID_ANY, label="~") self.btn['compl'].SetToolTip(_('one\'s complement')) self.btn['not'] = Button(parent=self.panel, id=wx.ID_ANY, label="!") self.btn['not'].SetToolTip(_('NOT')) self.btn['andbit'] = Button(parent=self.panel, id=wx.ID_ANY, label='&&') self.btn['andbit'].SetToolTip(_('bitwise AND')) self.btn['orbit'] = Button(parent=self.panel, id=wx.ID_ANY, label="|") self.btn['orbit'].SetToolTip(_('bitwise OR')) self.btn['and'] = Button(parent=self.panel, id=wx.ID_ANY, label="&&&&") self.btn['and'].SetToolTip(_('logical AND')) self.btn['andnull'] = Button(parent=self.panel, id=wx.ID_ANY, label="&&&&&&") self.btn['andnull'].SetToolTip(_('logical AND (ignores NULLs)')) self.btn['or'] = Button(parent=self.panel, id=wx.ID_ANY, label="||") self.btn['or'].SetToolTip(_('logical OR')) self.btn['ornull'] = Button(parent=self.panel, id=wx.ID_ANY, label="|||") self.btn['ornull'].SetToolTip(_('logical OR (ignores NULLs)')) self.btn['cond'] = Button(parent=self.panel, id=wx.ID_ANY, label="a ? b : c") self.btn['cond'].SetToolTip(_('conditional')) # # Text area # self.text_mcalc = TextCtrl(parent=self.panel, id=wx.ID_ANY, size=(-1, 100), style=wx.TE_MULTILINE) wx.CallAfter(self.text_mcalc.SetFocus) # # Map and function insertion text and ComboBoxes self.newmaplabel = StaticText(parent=self.panel, id=wx.ID_ANY) if self.rast3d: self.newmaplabel.SetLabel( _('Name for new 3D raster map to create')) else: self.newmaplabel.SetLabel(_('Name for new raster map to create')) # As we can write only to current mapset, names should not be fully qualified # to not confuse end user about writing in other mapset self.newmaptxt = Select(parent=self.panel, id=wx.ID_ANY, size=(250, -1), type=element, multiple=False, fullyQualified=False) self.mapsellabel = StaticText(parent=self.panel, id=wx.ID_ANY) if self.rast3d: self.mapsellabel.SetLabel(_('Insert existing 3D raster map')) else: self.mapsellabel.SetLabel(_('Insert existing raster map')) self.mapselect = Select(parent=self.panel, id=wx.ID_ANY, size=(250, -1), type=element, multiple=False) self.functlabel = StaticText(parent=self.panel, id=wx.ID_ANY, label=_('Insert mapcalc function')) self.function = wx.ComboBox(parent=self.panel, id=wx.ID_ANY, size=(250, -1), choices=sorted(self.funct_dict.keys()), style=wx.CB_DROPDOWN | wx.CB_READONLY | wx.TE_PROCESS_ENTER) self.overwrite = wx.CheckBox( parent=self.panel, id=wx.ID_ANY, label=_("Allow output files to overwrite existing files")) self.overwrite.SetValue( UserSettings.Get(group='cmd', key='overwrite', subkey='enabled')) self.randomSeed = wx.CheckBox( parent=self.panel, label=_("Generate random seed for rand()")) self.randomSeedStaticText = StaticText(parent=self.panel, label=_("Seed:")) self.randomSeedText = TextCtrl(parent=self.panel, size=(100, -1), validator=IntegerValidator()) self.randomSeedText.SetToolTip(_("Integer seed for rand() function")) self.randomSeed.SetValue(True) self.randomSeedStaticText.Disable() self.randomSeedText.Disable() self.addbox = wx.CheckBox( parent=self.panel, label=_('Add created raster map into layer tree'), style=wx.NO_BORDER) self.addbox.SetValue( UserSettings.Get(group='cmd', key='addNewLayer', subkey='enabled')) if not self.parent or self.parent.GetName() != 'LayerManager': self.addbox.Hide() # # Bindings # for btn in self.btn.keys(): self.btn[btn].Bind(wx.EVT_BUTTON, self.AddMark) self.btn_close.Bind(wx.EVT_BUTTON, self.OnClose) self.btn_clear.Bind(wx.EVT_BUTTON, self.OnClear) self.btn_run.Bind(wx.EVT_BUTTON, self.OnMCalcRun) self.btn_help.Bind(wx.EVT_BUTTON, self.OnHelp) self.btn_save.Bind(wx.EVT_BUTTON, self.OnSaveExpression) self.btn_load.Bind(wx.EVT_BUTTON, self.OnLoadExpression) self.btn_copy.Bind(wx.EVT_BUTTON, self.OnCopyCommand) self.mapselect.Bind(wx.EVT_TEXT, self.OnSelect) self.function.Bind(wx.EVT_COMBOBOX, self._return_funct) self.function.Bind(wx.EVT_TEXT_ENTER, self.OnSelect) self.newmaptxt.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar) self.text_mcalc.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar) self.overwrite.Bind(wx.EVT_CHECKBOX, self.OnUpdateStatusBar) self.randomSeed.Bind(wx.EVT_CHECKBOX, self.OnUpdateStatusBar) self.randomSeed.Bind(wx.EVT_CHECKBOX, self.OnSeedFlag) self.randomSeedText.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar) # bind closing to ESC self.Bind(wx.EVT_MENU, self.OnClose, id=wx.ID_CANCEL) accelTableList = [(wx.ACCEL_NORMAL, wx.WXK_ESCAPE, wx.ID_CANCEL)] accelTable = wx.AcceleratorTable(accelTableList) self.SetAcceleratorTable(accelTable) self._layout() self.SetMinSize(self.panel.GetBestSize()) # workaround for http://trac.wxwidgets.org/ticket/13628 self.SetSize(self.panel.GetBestSize()) def _return_funct(self, event): i = event.GetString() self._addSomething(self.funct_dict[i]) # reset win = self.FindWindowById(event.GetId()) win.SetValue('') def _layout(self): sizer = wx.BoxSizer(wx.VERTICAL) controlSizer = wx.BoxSizer(wx.HORIZONTAL) operatorSizer = wx.StaticBoxSizer(self.operatorBox, wx.HORIZONTAL) outOpeSizer = wx.BoxSizer(wx.VERTICAL) buttonSizer1 = wx.GridBagSizer(5, 1) buttonSizer1.Add(self.btn['add'], pos=(0, 0)) buttonSizer1.Add(self.btn['minus'], pos=(0, 1)) buttonSizer1.Add(self.btn['mod'], pos=(5, 0)) buttonSizer1.Add(self.btn['mult'], pos=(1, 0)) buttonSizer1.Add(self.btn['div'], pos=(1, 1)) buttonSizer1.Add(self.btn['pow'], pos=(5, 1)) buttonSizer1.Add(self.btn['gt'], pos=(2, 0)) buttonSizer1.Add(self.btn['gteq'], pos=(2, 1)) buttonSizer1.Add(self.btn['eq'], pos=(4, 0)) buttonSizer1.Add(self.btn['lt'], pos=(3, 0)) buttonSizer1.Add(self.btn['lteq'], pos=(3, 1)) buttonSizer1.Add(self.btn['noteq'], pos=(4, 1)) buttonSizer2 = wx.GridBagSizer(5, 1) buttonSizer2.Add(self.btn['and'], pos=(0, 0)) buttonSizer2.Add(self.btn['andbit'], pos=(1, 0)) buttonSizer2.Add(self.btn['andnull'], pos=(2, 0)) buttonSizer2.Add(self.btn['or'], pos=(0, 1)) buttonSizer2.Add(self.btn['orbit'], pos=(1, 1)) buttonSizer2.Add(self.btn['ornull'], pos=(2, 1)) buttonSizer2.Add(self.btn['lshift'], pos=(3, 0)) buttonSizer2.Add(self.btn['rshift'], pos=(3, 1)) buttonSizer2.Add(self.btn['rshiftu'], pos=(4, 0)) buttonSizer2.Add(self.btn['cond'], pos=(5, 0)) buttonSizer2.Add(self.btn['compl'], pos=(5, 1)) buttonSizer2.Add(self.btn['not'], pos=(4, 1)) outputSizer = wx.StaticBoxSizer(self.outputBox, wx.VERTICAL) outputSizer.Add(self.newmaplabel, flag=wx.ALIGN_CENTER | wx.TOP, border=5) outputSizer.Add(self.newmaptxt, flag=wx.EXPAND | wx.ALL, border=5) operandSizer = wx.StaticBoxSizer(self.operandBox, wx.HORIZONTAL) buttonSizer3 = wx.GridBagSizer(7, 1) buttonSizer3.Add(self.functlabel, pos=(0, 0), span=(1, 2), flag=wx.ALIGN_CENTER | wx.EXPAND) buttonSizer3.Add(self.function, pos=(1, 0), span=(1, 2)) buttonSizer3.Add(self.mapsellabel, pos=(2, 0), span=(1, 2), flag=wx.ALIGN_CENTER) buttonSizer3.Add(self.mapselect, pos=(3, 0), span=(1, 2)) threebutton = wx.GridBagSizer(1, 2) threebutton.Add(self.btn['parenl'], pos=(0, 0), span=(1, 1), flag=wx.ALIGN_LEFT) threebutton.Add(self.btn['parenr'], pos=(0, 1), span=(1, 1), flag=wx.ALIGN_CENTER) threebutton.Add(self.btn_clear, pos=(0, 2), span=(1, 1), flag=wx.ALIGN_RIGHT) buttonSizer3.Add(threebutton, pos=(4, 0), span=(1, 1), flag=wx.ALIGN_CENTER) buttonSizer4 = wx.BoxSizer(wx.HORIZONTAL) buttonSizer4.Add(self.btn_load, flag=wx.ALL, border=5) buttonSizer4.Add(self.btn_save, flag=wx.ALL, border=5) buttonSizer4.Add(self.btn_copy, flag=wx.ALL, border=5) buttonSizer4.AddSpacer(30) buttonSizer4.Add(self.btn_help, flag=wx.ALL, border=5) buttonSizer4.Add(self.btn_run, flag=wx.ALL, border=5) buttonSizer4.Add(self.btn_close, flag=wx.ALL, border=5) operatorSizer.Add(buttonSizer1, proportion=0, flag=wx.ALL | wx.EXPAND, border=5) operatorSizer.Add(buttonSizer2, proportion=0, flag=wx.TOP | wx.BOTTOM | wx.RIGHT | wx.EXPAND, border=5) operandSizer.Add(buttonSizer3, proportion=0, flag=wx.ALL, border=5) controlSizer.Add(operatorSizer, proportion=1, flag=wx.RIGHT | wx.EXPAND, border=5) outOpeSizer.Add(outputSizer, proportion=0, flag=wx.EXPAND) outOpeSizer.Add(operandSizer, proportion=1, flag=wx.EXPAND | wx.TOP, border=5) controlSizer.Add(outOpeSizer, proportion=0, flag=wx.EXPAND) expressSizer = wx.StaticBoxSizer(self.expressBox, wx.HORIZONTAL) expressSizer.Add(self.text_mcalc, proportion=1, flag=wx.EXPAND) sizer.Add(controlSizer, proportion=0, flag=wx.EXPAND | wx.ALL, border=5) sizer.Add(expressSizer, proportion=1, flag=wx.EXPAND | wx.LEFT | wx.RIGHT, border=5) sizer.Add(buttonSizer4, proportion=0, flag=wx.ALIGN_RIGHT | wx.ALL, border=3) randomSizer = wx.BoxSizer(wx.HORIZONTAL) randomSizer.Add(self.randomSeed, proportion=0, flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, border=20) randomSizer.Add(self.randomSeedStaticText, proportion=0, flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, border=5) randomSizer.Add(self.randomSeedText, proportion=0) sizer.Add(randomSizer, proportion=0, flag=wx.LEFT | wx.RIGHT, border=5) sizer.Add(self.overwrite, proportion=0, flag=wx.LEFT | wx.RIGHT, border=5) if self.addbox.IsShown(): sizer.Add(self.addbox, proportion=0, flag=wx.LEFT | wx.RIGHT, border=5) self.panel.SetAutoLayout(True) self.panel.SetSizer(sizer) sizer.Fit(self.panel) self.Layout() def AddMark(self, event): """Sends operators to insertion method """ if event.GetId() == self.btn['compl'].GetId(): mark = "~" elif event.GetId() == self.btn['not'].GetId(): mark = "!" elif event.GetId() == self.btn['pow'].GetId(): mark = "^" elif event.GetId() == self.btn['div'].GetId(): mark = "/" elif event.GetId() == self.btn['add'].GetId(): mark = "+" elif event.GetId() == self.btn['minus'].GetId(): mark = "-" elif event.GetId() == self.btn['mod'].GetId(): mark = "%" elif event.GetId() == self.btn['mult'].GetId(): mark = "*" elif event.GetId() == self.btn['lshift'].GetId(): mark = "<<" elif event.GetId() == self.btn['rshift'].GetId(): mark = ">>" elif event.GetId() == self.btn['rshiftu'].GetId(): mark = ">>>" elif event.GetId() == self.btn['gt'].GetId(): mark = ">" elif event.GetId() == self.btn['gteq'].GetId(): mark = ">=" elif event.GetId() == self.btn['lt'].GetId(): mark = "<" elif event.GetId() == self.btn['lteq'].GetId(): mark = "<=" elif event.GetId() == self.btn['eq'].GetId(): mark = "==" elif event.GetId() == self.btn['noteq'].GetId(): mark = "!=" elif event.GetId() == self.btn['andbit'].GetId(): mark = "&" elif event.GetId() == self.btn['orbit'].GetId(): mark = "|" elif event.GetId() == self.btn['or'].GetId(): mark = "||" elif event.GetId() == self.btn['ornull'].GetId(): mark = "|||" elif event.GetId() == self.btn['and'].GetId(): mark = "&&" elif event.GetId() == self.btn['andnull'].GetId(): mark = "&&&" elif event.GetId() == self.btn['cond'].GetId(): mark = " ? : " elif event.GetId() == self.btn['parenl'].GetId(): mark = "(" elif event.GetId() == self.btn['parenr'].GetId(): mark = ")" self._addSomething(mark) # unused # def OnSelectTextEvt(self, event): # """Checks if user is typing or the event was emited by map selection. # Prevents from changing focus. # """ # item = self.mapselect.GetValue().strip() # if not (abs(len(item) - len(self.lastMapName)) == 1 and \ # self.lastMapName in item or item in self.lastMapName): # self.OnSelect(event) # self.lastMapName = item def OnSelect(self, event): """Gets raster map or function selection and send it to insertion method. Checks for characters which can be in raster map name but the raster map name must be then quoted. """ win = self.FindWindowById(event.GetId()) item = win.GetValue().strip() if any((char in item) for char in self.charactersToQuote): item = '"' + item + '"' self._addSomething(item) win.ChangeValue('') # reset # Map selector likes to keep focus. Set it back to expression input area wx.CallAfter(self.text_mcalc.SetFocus) def OnUpdateStatusBar(self, event): """Update statusbar text""" command = self._getCommand() self.SetStatusText(command) event.Skip() def OnSeedFlag(self, event): checked = self.randomSeed.IsChecked() self.randomSeedText.Enable(not checked) self.randomSeedStaticText.Enable(not checked) event.Skip() def _getCommand(self): """Returns entire command as string.""" expr = self.text_mcalc.GetValue().strip().replace("\n", " ") cmd = 'r.mapcalc' if self.rast3d: cmd = 'r3.mapcalc' overwrite = '' if self.overwrite.IsChecked(): overwrite = ' --overwrite' seed_flag = seed = '' if re.search(pattern="rand *\(.+\)", string=expr): if self.randomSeed.IsChecked(): seed_flag = ' -s' else: seed = " seed={val}".format( val=self.randomSeedText.GetValue().strip()) return ('{cmd} expression="{new} = {expr}"{seed}{seed_flag}{overwrite}' .format(cmd=cmd, expr=expr, new=self.newmaptxt.GetValue(), seed_flag=seed_flag, seed=seed, overwrite=overwrite)) def _addSomething(self, what): """Inserts operators, map names, and functions into text area """ mcalcstr = self.text_mcalc.GetValue() position = self.text_mcalc.GetInsertionPoint() newmcalcstr = mcalcstr[:position] position_offset = 0 try: if newmcalcstr[-1] != ' ': newmcalcstr += ' ' position_offset += 1 except: pass newmcalcstr += what # Do not add extra space if there is already one try: if newmcalcstr[-1] != ' ' and mcalcstr[position] != ' ': newmcalcstr += ' ' except: newmcalcstr += ' ' newmcalcstr += mcalcstr[position:] self.text_mcalc.SetValue(newmcalcstr) if len(what) > 0: match = re.search(pattern="\(.*\)", string=what) if match: position_offset += match.start() + 1 else: position_offset += len(what) try: if newmcalcstr[position + position_offset] == ' ': position_offset += 1 except: pass self.text_mcalc.SetInsertionPoint(position + position_offset) self.text_mcalc.Update() self.text_mcalc.SetFocus() def OnMCalcRun(self, event): """Builds and runs r.mapcalc statement """ name = self.newmaptxt.GetValue().strip() if not name: GError(parent=self, message=_("You must enter the name of " "a new raster map to create.")) return if not (name[0] == '"' and name[-1] == '"') and any( (char in name) for char in self.charactersToQuote): name = '"' + name + '"' expr = self.text_mcalc.GetValue().strip().replace("\n", " ") if not expr: GError(parent=self, message=_("You must enter an expression " "to create a new raster map.")) return seed_flag = seed = None if re.search(pattern="rand *\(.+\)", string=expr): if self.randomSeed.IsChecked(): seed_flag = '-s' else: seed = self.randomSeedText.GetValue().strip() if self.log: cmd = [self.cmd] if seed_flag: cmd.append('-s') if seed: cmd.append("seed={val}".format(val=seed)) if self.overwrite.IsChecked(): cmd.append('--overwrite') cmd.append(str('expression=%s = %s' % (name, expr))) self.log.RunCmd(cmd, onDone=self.OnDone) self.parent.Raise() else: if self.overwrite.IsChecked(): overwrite = True else: overwrite = False params = dict(expression="%s=%s" % (name, expr), overwrite=overwrite) if seed_flag: params['flags'] = 's' if seed: params['seed'] = seed RunCommand(self.cmd, **params) def OnDone(self, event): """Add create map to the layer tree Sends the mapCreated signal from the grass interface. """ if event.returncode != 0: return name = self.newmaptxt.GetValue().strip( ' "') + '@' + grass.gisenv()['MAPSET'] ltype = 'raster' if self.rast3d: ltype = 'raster_3d' self._giface.mapCreated.emit(name=name, ltype=ltype, add=self.addbox.IsChecked()) gisenv = grass.gisenv() self._giface.grassdbChanged.emit(grassdb=gisenv['GISDBASE'], location=gisenv['LOCATION_NAME'], mapset=gisenv['MAPSET'], action='new', map=name.split('@')[0], element=ltype) def OnSaveExpression(self, event): """Saves expression to file """ mctxt = self.newmaptxt.GetValue() + ' = ' + self.text_mcalc.GetValue( ) + os.linesep # dialog dlg = wx.FileDialog( parent=self, message=_("Choose a file name to save the expression"), wildcard=_("Expression file (*)|*"), style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() if not path: dlg.Destroy() return try: fobj = open(path, 'w') fobj.write(mctxt) finally: fobj.close() dlg.Destroy() def OnLoadExpression(self, event): """Load expression from file """ dlg = wx.FileDialog( parent=self, message=_("Choose a file name to load the expression"), wildcard=_("Expression file (*)|*"), style=wx.FD_OPEN) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() if not path: dlg.Destroy() return try: fobj = open(path, 'r') mctxt = fobj.read() finally: fobj.close() try: result, exp = mctxt.split('=', 1) except ValueError: result = '' exp = mctxt self.newmaptxt.SetValue(result.strip()) self.text_mcalc.SetValue(exp.strip()) self.text_mcalc.SetFocus() self.text_mcalc.SetInsertionPointEnd() dlg.Destroy() def OnCopyCommand(self, event): command = self._getCommand() cmddata = wx.TextDataObject() cmddata.SetText(command) if wx.TheClipboard.Open(): wx.TheClipboard.SetData(cmddata) wx.TheClipboard.Close() self.SetStatusText( _("'{cmd}' copied to clipboard").format(cmd=command)) def OnClear(self, event): """Clears text area """ self.text_mcalc.SetValue('') def OnHelp(self, event): """Launches r.mapcalc help """ RunCommand('g.manual', parent=self, entry=self.cmd) def OnClose(self, event): """Close window""" self.Destroy()
class ModelDataDialog(ElementDialog): """!Data item properties dialog""" def __init__(self, parent, shape, id=wx.ID_ANY, title=_("Data properties"), style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER): self.parent = parent self.shape = shape label, etype = self._getLabel() ElementDialog.__init__(self, parent, title, label=label, etype=etype) self.element = Select(parent=self.panel) self.element.SetValue(shape.GetValue()) self.Bind(wx.EVT_BUTTON, self.OnOK, self.btnOK) self.Bind(wx.EVT_BUTTON, self.OnCancel, self.btnCancel) self.PostInit() if shape.GetValue(): self.btnOK.Enable() self._layout() self.SetMinSize(self.GetSize()) def _getLabel(self): etype = False prompt = self.shape.GetPrompt() if prompt == 'raster': label = _('Name of raster map:') elif prompt == 'vector': label = _('Name of vector map:') else: etype = True label = _('Name of element:') return label, etype def _layout(self): """!Do layout""" self.dataSizer.Add(self.element, proportion=0, flag=wx.EXPAND | wx.ALL, border=1) self.panel.SetSizer(self.sizer) self.sizer.Fit(self) def OnOK(self, event): """!Ok pressed""" self.shape.SetValue(self.GetElement()) if self.etype: elem = self.GetType() if elem == 'rast': self.shape.SetPrompt('raster') elif elem == 'vect': self.shape.SetPrompt('raster') self.parent.canvas.Refresh() self.parent.SetStatusText('', 0) self.shape.SetPropDialog(None) if self.IsModal(): event.Skip() else: self.Destroy() def OnCancel(self, event): """!Cancel pressed""" self.shape.SetPropDialog(None) if self.IsModal(): event.Skip() else: self.Destroy()
class OutputPanel(wx.Panel): def __init__(self, parent, giface, settings): wx.Panel.__init__(self, parent) self.giface = giface self.settings = settings self.settingsChanged = Signal('OutputPanel.settingsChanged') if 'output' not in self.settings: self.settings['output'] = {} self.settings['output']['scan'] = 'scan' self.settings['output']['PLY'] = False self.settings['output']['PLY_file'] = '' self.settings['output']['color'] = False self.settings['output']['color_name'] = '' self.settings['output']['blender'] = False self.settings['output']['blender_path'] = '' if self.settings['output']['PLY_file']: initDir = os.path.dirname(self.settings['output']['PLY_file']) else: initDir = "" # scan self.scan_name = wx.TextCtrl(self) self.scan_name.SetValue(self.settings['output']['scan']) self.scan_name.Bind(wx.EVT_TEXT, self.OnChange) bmp = get_show_layer_icon() self.addScan = wx.BitmapButton(self, bitmap=bmp, size=(bmp.GetWidth() + 12, bmp.GetHeight() + 8)) self.addScan.Bind(wx.EVT_BUTTON, lambda evt: self._addLayer('scan')) # color self.ifColor = wx.CheckBox( self, label=_("Save color rasters (with postfixes _r, _g, _b):")) self.ifColor.SetValue(self.settings['output']['color']) self.ifColor.Bind(wx.EVT_CHECKBOX, self.OnChange) self.exportColor = Select(self, size=(-1, -1), type='raster') self.exportColor.SetValue(self.settings['output']['color_name']) self.exportColor.Bind(wx.EVT_TEXT, self.OnChange) bmp = get_show_layer_icon() self.addColor = wx.BitmapButton(self, bitmap=bmp, size=(bmp.GetWidth() + 12, bmp.GetHeight() + 8)) self.addColor.Bind(wx.EVT_BUTTON, lambda evt: self._addLayer('color')) # Blender self.ifBlender = wx.CheckBox(self, label='') self.ifBlender.SetValue(self.settings['output']['blender']) self.ifBlender.Bind(wx.EVT_CHECKBOX, self.OnChange) initDirBlender = '' if self.settings['output']['blender_path']: initDirBlender = self.settings['output']['blender_path'] self.blenderPath = filebrowse.DirBrowseButton( self, labelText="Export folder for Blender coupling:", startDirectory=initDirBlender, newDirectory=True, changeCallback=self.OnChange) # PLY self.ifPLY = wx.CheckBox(self, label="") self.ifPLY.SetValue(self.settings['output']['PLY']) self.ifPLY.Bind(wx.EVT_CHECKBOX, self.OnChange) self.exportPLY = filebrowse.FileBrowseButton( self, labelText="Export PLY:", fileMode=wx.FD_SAVE, startDirectory=initDir, initialValue=self.settings['output']['PLY_file'], changeCallback=self.OnChange) # must be called after all widgets are created self.blenderPath.SetValue(initDirBlender) mainSizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(wx.StaticText(self, label="Name of scanned raster:"), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) sizer.Add(self.scan_name, proportion=1, flag=wx.EXPAND | wx.ALL, border=5) sizer.Add(self.addScan, proportion=0, flag=wx.EXPAND | wx.RIGHT | wx.TOP | wx.BOTTOM, border=5) mainSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.ifColor, flag=wx.ALIGN_CENTER_VERTICAL, border=5) sizer.Add(self.exportColor, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL, border=5) sizer.Add(self.addColor, proportion=0, flag=wx.EXPAND | wx.ALL, border=5) mainSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.ifBlender, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.LEFT, border=3) sizer.Add(self.blenderPath, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, proportion=1, border=0) mainSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.ifPLY, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.LEFT, border=3) sizer.Add(self.exportPLY, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, proportion=1, border=0) mainSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) self.SetSizer(mainSizer) mainSizer.Fit(self) def OnChange(self, event): self.settings['output']['scan'] = self.scan_name.GetValue() self.settings['output']['color'] = self.ifColor.IsChecked() self.settings['output']['color_name'] = self.exportColor.GetValue() self.settings['output']['blender'] = self.ifBlender.IsChecked() self.settings['output']['blender_path'] = self.blenderPath.GetValue() self.settings['output']['PLY'] = self.ifPLY.IsChecked() self.settings['output']['PLY_file'] = self.exportPLY.GetValue() self.settingsChanged.emit() def _addLayer(self, ltype): if not self.giface.GetLayerTree(): return ll = self.giface.GetLayerList() if ltype == 'scan': raster = self.scan_name.GetValue() if not raster: return cmd = ['d.rast', 'map=' + raster] ll.AddLayer('raster', name=raster, checked=True, cmd=cmd) elif ltype == 'color': name = self.exportColor.GetValue() if not name: return cmd = [ 'd.rgb', 'red={m}'.format(m=name + '_r'), 'green={m}'.format(m=name + '_g'), 'blue={m}'.format(m=name + '_b'), '-n' ] ll.AddLayer('rgb', name=name, checked=True, cmd=cmd)
class DrawingPanel(wx.Panel): def __init__(self, parent, giface, settings): wx.Panel.__init__(self, parent) self.giface = giface self.settings = settings self.settingsChanged = Signal('ScanningPanel.settingsChanged') if 'drawing' not in self.settings: self.settings['drawing'] = {} self.settings['drawing']['active'] = False self.settings['drawing']['name'] = '' self.settings['drawing']['type'] = 'point' self.settings['drawing']['append'] = False self.settings['drawing']['appendName'] = '' self.settings['drawing']['threshold'] = 760 mainSizer = wx.BoxSizer(wx.VERTICAL) self.ifDraw = wx.CheckBox(self, label=_("Draw vector:")) self.ifDraw.SetValue(self.settings['drawing']['active']) self.ifDraw.Bind(wx.EVT_CHECKBOX, self.OnDrawChange) self.ifDraw.Bind(wx.EVT_CHECKBOX, self.OnEnableDrawing) self.draw_vector = Select(self, size=(-1, -1), type='vector') self.draw_vector.SetValue(self.settings['drawing']['name']) self.draw_vector.Bind(wx.EVT_TEXT, self.OnDrawChange) self.draw_type = wx.RadioBox(parent=self, label="Vector type", choices=['point', 'line', 'area']) {'point': 0, 'line': 1, 'area': 2}[self.settings['drawing']['type']] self.draw_type.SetSelection({ 'point': 0, 'line': 1, 'area': 2 }[self.settings['drawing']['type']]) self.draw_type.Bind(wx.EVT_RADIOBOX, self.OnDrawChange) self.threshold = wx.SpinCtrl( parent=self, min=0, max=765, initial=int(self.settings['drawing']['threshold'])) self.threshold.SetValue(int(self.settings['drawing']['threshold'])) self.threshold.Bind(wx.EVT_SPINCTRL, self.OnDrawChange) self.append = wx.CheckBox(parent=self, label="Append vector") self.append.SetValue(self.settings['drawing']['append']) self.append.Bind(wx.EVT_CHECKBOX, self.OnDrawChange) self.appendName = Select(self, size=(-1, -1), type='vector') self.appendName.SetValue(self.settings['drawing']['appendName']) self.appendName.Bind(wx.EVT_TEXT, self.OnDrawChange) self.clearBtn = wx.Button(parent=self, label="Clear") self.clearBtn.Bind(wx.EVT_BUTTON, lambda evt: self._newAppendedVector(evt)) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.ifDraw, flag=wx.ALIGN_CENTER_VERTICAL, border=5) sizer.Add(self.draw_vector, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL, border=5) mainSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.draw_type, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL, border=5) mainSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(wx.StaticText(self, label='Brightness threshold:'), proportion=0, flag=wx.ALIGN_CENTER_VERTICAL, border=5) sizer.Add(self.threshold, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL, border=5) mainSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.append, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL, border=5) sizer.Add(self.appendName, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL, border=5) sizer.Add(self.clearBtn, flag=wx.ALIGN_CENTER_VERTICAL, border=5) mainSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) self.SetSizer(mainSizer) mainSizer.Fit(self) self.EnableDrawing(self.ifDraw.IsChecked()) def OnDrawChange(self, event): self.settings['drawing']['active'] = self.ifDraw.GetValue() self.settings['drawing']['name'] = self.draw_vector.GetValue().split( '@')[0] self.settings['drawing']['appendName'] = self.appendName.GetValue( ).split('@')[0] self.settings['drawing']['type'] = ['point', 'line', 'area' ][self.draw_type.GetSelection()] self.settings['drawing']['append'] = self.append.IsChecked() self.settings['drawing']['threshold'] = self.threshold.GetValue() event.Skip() self.settingsChanged.emit() def OnEnableDrawing(self, event): self.EnableDrawing(self.ifDraw.IsChecked()) event.Skip() def EnableDrawing(self, enable): self.draw_vector.Enable(enable) self.appendName.Enable(enable) self.draw_type.Enable(enable) self.append.Enable(enable) self.threshold.Enable(enable) self.clearBtn.Enable(enable) def appendVector(self): if not self.settings['drawing']['append']: return ff = gscript.find_file(self.settings['drawing']['appendName'], element='vector', mapset=gscript.gisenv()['MAPSET']) if not (ff and ff['fullname']): self._newAppendedVector() gscript.run_command('v.patch', input=self.settings['drawing']['name'], output=self.settings['drawing']['appendName'], flags='a', overwrite=True, quiet=True) def _newAppendedVector(self, event=None): gscript.run_command('v.edit', tool='create', map=self.settings['drawing']['appendName'], overwrite=True, quiet=True)
class ColorInteractionPanel(wx.Panel): def __init__(self, parent, giface, settings, scaniface): wx.Panel.__init__(self, parent) self.group = None self.segment = 'segment' self.segment_clump = 'segment_clump' self.signature = 'signature' self.classification = 'classification' self.filtered_classification = 'fclassification' self.reject = 'reject' self.output = 'objects' self.hasSuperpixels = gscript.find_program('i.superpixels.slic', '--help') self.env = None self.giface = giface self.parent = parent self.settings = settings self.scaniface = scaniface self.settingsChanged = Signal('ColorInteractionPanel.settingsChanged') if 'color' not in self.settings: self.settings['color'] = {} self.settings['color']['active'] = False self.settings['color']['name'] = '' self.settings['color']['training'] = '' self.hide = [] self.ifColor = wx.CheckBox(self, label=_("Save color rasters:")) self.ifColor.SetValue(self.settings['color']['active']) self.ifColor.Bind(wx.EVT_CHECKBOX, self.OnChange) self.exportColor = Select(self, size=(-1, -1), type='raster') self.exportColor.SetValue(self.settings['color']['name']) self.exportColor.Bind(wx.EVT_TEXT, self.OnChange) self.hide.append(self.exportColor) if self.settings['color']['name']: self.group = self.settings['color']['name'] self.trainingAreas = Select(self, size=(-1, -1), type='raster') self.trainingAreas.SetValue(self.settings['color']['training']) self.trainingAreas.Bind(wx.EVT_TEXT, self.OnChange) labelTraining = wx.StaticText(self, label=_("Training areas:")) self.hide.append(self.trainingAreas) self.hide.append(labelTraining) calibrateBtn = wx.Button(self, label=_("Calibrate")) calibrateBtn.Bind(wx.EVT_BUTTON, self.OnCalibration) self.hide.append(calibrateBtn) analyzeBtn = wx.Button(self, label=_("Scan and process")) analyzeBtn.Bind(wx.EVT_BUTTON, self.OnAnalysis) self.hide.append(analyzeBtn) self.mainSizer = wx.BoxSizer(wx.VERTICAL) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.ifColor, flag=wx.ALIGN_CENTER_VERTICAL, border=5) sizer.Add(self.exportColor, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL, border=5) self.mainSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(labelTraining, flag=wx.ALIGN_CENTER_VERTICAL, border=5) sizer.Add(self.trainingAreas, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL, border=5) sizer.Add(calibrateBtn, flag=wx.ALIGN_CENTER_VERTICAL, border=5) self.mainSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.AddStretchSpacer() sizer.Add(analyzeBtn, flag=wx.ALIGN_CENTER_VERTICAL, border=5) self.mainSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) self.SetSizer(self.mainSizer) self.mainSizer.Fit(self) self._enable() def OnChange(self, event): self.settings['color']['training'] = self.trainingAreas.GetValue() self.settings['color']['active'] = self.ifColor.IsChecked() self.settings['color']['name'] = self.exportColor.GetValue() self.group = self.settings['color']['name'] self._enable() def _enable(self): for each in self.hide: each.Enable(self.ifColor.IsChecked()) def _defineEnvironment(self): try: gscript.read_command('i.group', flags='g', group=self.group, subgroup=self.group, env=self.env) except CalledModuleError: gscript.run_command('i.group', group=self.group, subgroup=self.group, input=[self.group + '_' + ext for ext in 'r', 'g', 'b'], env=self.env) maps = gscript.read_command('i.group', flags='g', group=self.group, subgroup=self.group).strip() if maps: self.env = get_environment(raster=maps.splitlines()[0]) def OnAnalysis(self, event): self._defineEnvironment() self.Run(self.Analyze) def OnCalibration(self, event): self._defineEnvironment() training = self.trainingAreas.GetValue() if not training: return self.Run(self.Calibrate) def Run(self, func): ll = self.giface.GetLayerList() checked = [] for l in ll: if ll.IsLayerChecked(l): checked.append(l.cmd) ll.CheckLayer(l, False) wx.Yield() if not self.scaniface.IsScanning(): self.scaniface.Scan(continuous=False) self.scaniface.process.wait() self.scaniface.process = None self.scaniface.status.SetLabel("Done.") self.Done(func, checked) elif self.scaniface.pause: pass else: wx.CallLater(3000, self.Done, func, checked) def Done(self, func, checked): func() ll = self.giface.GetLayerList() for l in ll: if l.cmd in checked: ll.CheckLayer(l, True) def Calibrate(self): gscript.run_command('i.gensigset', trainingmap=self.settings['color']['training'], group=self.group, subgroup=self.group, signaturefile=self.signature, env=self.env, overwrite=True) # we need here overwrite=True def Analyze(self): if self.hasSuperpixels: gscript.run_command('i.superpixels.slic', group=self.group, output=self.segment, compactness=2, minsize=50, env=self.env) else: gscript.run_command('i.segment', group=self.group, output=self.segment, threshold=0.3, minsize=50, env=self.env) gscript.run_command('r.clump', input=self.segment, output=self.segment_clump, env=self.env) gscript.run_command('i.smap', group=self.group, subgroup=self.group, signaturefile=self.signature, output=self.classification, goodness=self.reject, env=self.env) percentile = float(gscript.parse_command('r.univar', flags='ge', map=self.reject, env=self.env)['percentile_90']) gscript.mapcalc('{new} = if({classif} < {thres}, {classif}, null())'.format(new=self.filtered_classification, classif=self.classification, thres=percentile), env=self.env) segments = self.segment if self.hasSuperpixels else self.segment_clump gscript.run_command('r.stats.quantile', base=segments, cover=self.filtered_classification, output=self.output, env=self.env)
class AnalysesPanel(wx.Panel): def __init__(self, parent, giface, settings, scaniface): wx.Panel.__init__(self, parent) self.giface = giface self.settings = settings self.scaniface = scaniface self.settingsChanged = Signal('AnalysesPanel.settingsChanged') mainSizer = wx.BoxSizer(wx.VERTICAL) if self.settings['analyses']['file']: path = self.settings['analyses']['file'] initDir = os.path.dirname(path) else: path = initDir = "" topoBox = wx.StaticBox(self, label=' Topographic analyses ') topoSizer = wx.StaticBoxSizer(topoBox, wx.VERTICAL) self.contoursSelect = Select(self, size=(-1, -1), type='vector') self.contoursStepTextCtrl = wx.TextCtrl(self, size=(40, -1)) self.contoursStepTextCtrl.SetToolTipString("Contour step") if 'contours' in self.settings['analyses'] and self.settings['analyses']['contours']: self.contoursStepTextCtrl.SetValue(str(self.settings['analyses']['contours_step'])) self.contoursSelect.SetValue(self.settings['analyses']['contours']) bmp = get_show_layer_icon() self.addContours = wx.BitmapButton(self, bitmap=bmp, size=(bmp.GetWidth() + 12, bmp.GetHeight() + 8)) self.addContours.Bind(wx.EVT_BUTTON, self._addContourLayer) self.contoursSelect.Bind(wx.EVT_TEXT, self.OnAnalysesChange) self.contoursStepTextCtrl.Bind(wx.EVT_TEXT, self.OnAnalysesChange) fileBox = wx.StaticBox(self, label=' Python file with analyses to run ') fileSizer = wx.StaticBoxSizer(fileBox, wx.VERTICAL) self.selectAnalyses = filebrowse.FileBrowseButton(self, labelText="File path:", fileMask="Python file (*.py)|*.py", startDirectory=initDir, initialValue=path, changeCallback=lambda evt: self.SetAnalysesFile(evt.GetString())) if self.settings['analyses']['file']: self.selectAnalyses.SetValue(self.settings['analyses']['file']) newAnalyses = wx.Button(self, label="Create new file with predefined analyses") newAnalyses.Bind(wx.EVT_BUTTON, lambda evt: self.CreateNewFile()) self.selectAnalyses.Bind(wx.EVT_TEXT, self.OnAnalysesChange) if 'color_training' not in self.settings['analyses']: self.settings['analyses']['color_training'] = '' colorBox = wx.StaticBox(self, label=' Color calibration for classification ') colorSizer = wx.StaticBoxSizer(colorBox, wx.VERTICAL) self.trainingAreas = Select(self, size=(-1, -1), type='raster') self.trainingAreas.SetValue(self.settings['analyses']['color_training']) self.trainingAreas.Bind(wx.EVT_TEXT, self.OnAnalysesChange) calibrateBtn = wx.Button(self, label="Calibrate") calibrateBtn.Bind(wx.EVT_BUTTON, self.OnColorCalibration) bmp = get_show_layer_icon() addLayerBtn = wx.BitmapButton(self, bitmap=bmp, size=(bmp.GetWidth()+12, bmp.GetHeight()+8)) addLayerBtn.SetToolTipString("Add layer to display") addLayerBtn.Bind(wx.EVT_BUTTON, self._addCalibLayer) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(wx.StaticText(self, label="Contour map name:"), proportion=0, flag=wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, border=5) sizer.Add(self.contoursSelect, proportion=4, flag=wx.ALIGN_CENTER_VERTICAL, border=5) sizer.Add(self.addContours, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, border=5) sizer.Add(wx.StaticText(self, label="Interval:"), proportion=0, flag=wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, border=5) sizer.Add(self.contoursStepTextCtrl, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL, border=5) topoSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) mainSizer.Add(topoSizer, flag=wx.EXPAND | wx.ALL, border=5) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(self.selectAnalyses, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, border=5) fileSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.AddStretchSpacer() sizer.Add(newAnalyses, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, border=5) fileSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) mainSizer.Add(fileSizer, flag=wx.EXPAND | wx.ALL, border=5) # color training sizer = wx.BoxSizer(wx.HORIZONTAL) sizer.Add(wx.StaticText(self, label="Raster with training areas:"), proportion=0, flag=wx.ALIGN_CENTER_VERTICAL|wx.RIGHT, border=5) sizer.Add(self.trainingAreas, proportion=1, flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, border=1) sizer.Add(addLayerBtn, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL | wx.RIGHT, border=5) sizer.Add(calibrateBtn, proportion=0, flag=wx.ALIGN_CENTER_VERTICAL) colorSizer.Add(sizer, flag=wx.EXPAND | wx.ALL, border=5) mainSizer.Add(colorSizer, flag=wx.EXPAND | wx.ALL, border=5) self.SetSizer(mainSizer) mainSizer.Fit(self) def SetAnalysesFile(self, path): self.settings['analyses']['file'] = path def OnAnalysesChange(self, event): self.settings['analyses']['contours'] = self.contoursSelect.GetValue() self.settings['analyses']['contours_step'] = self.contoursStepTextCtrl.GetValue() self.settings['analyses']['file'] = self.selectAnalyses.GetValue() self.settings['analyses']['color_training'] = self.trainingAreas.GetValue() self.settingsChanged.emit() def CreateNewFile(self): get_lib_path('g.gui.tangible') dlg = wx.FileDialog(self, message="Create a new file with analyses", wildcard="Python source (*.py)|*.py", style=wx.SAVE | wx.FD_OVERWRITE_PROMPT) if dlg.ShowModal() == wx.ID_OK: path = dlg.GetPath() orig = os.path.join(get_lib_path('g.gui.tangible'), 'current_analyses.py') if not os.path.exists(orig): self.giface.WriteError("File with analyses not found: {}".format(orig)) else: copyfile(orig, path) self.selectAnalyses.SetValue(path) self.settings['analyses']['file'] = path dlg.Destroy() def OnColorCalibration(self, event): if self.scaniface.IsScanning(): dlg = wx.MessageDialog(self, 'In order to calibrate, please stop scanning process first.', 'Stop scanning', wx.OK | wx.ICON_WARNING) dlg.ShowModal() dlg.Destroy() return training = self.trainingAreas.GetValue() if not training: return if self.settings['output']['color'] and self.settings['output']['color_name']: self.group = self.settings['output']['color_name'] else: self.group = None dlg = wx.MessageDialog(self, "In order to calibrate colors, please specify name of output color raster in 'Output' tab.", 'Need color output', wx.OK | wx.ICON_WARNING) dlg.ShowModal() dlg.Destroy() return self.CalibrateColor() def CalibrateColor(self): ll = self.giface.GetLayerList() checked = [] for l in ll: if ll.IsLayerChecked(l): checked.append(l.cmd) ll.CheckLayer(l, False) wx.Yield() self.scaniface.Scan(continuous=False) self.scaniface.process.wait() self.scaniface.process = None self.scaniface.status.SetLabel("Done.") self._defineEnvironment() self._calibrateColor() # check the layers back to previous state ll = self.giface.GetLayerList() for l in ll: if l.cmd in checked: ll.CheckLayer(l, True) def _calibrateColor(self): gscript.run_command('i.gensigset', trainingmap=self.settings['analyses']['color_training'], group=self.group, subgroup=self.group, signaturefile='signature', env=self.env, overwrite=True) # we need here overwrite=True def _defineEnvironment(self): self.env = None maps = gscript.read_command('i.group', flags='g', group=self.group, subgroup=self.group, quiet=True).strip() if maps: self.env = get_environment(raster=maps.splitlines()[0]) def _addCalibLayer(self, event): ll = self.giface.GetLayerList() raster = self.trainingAreas.GetValue() if not raster: return cmd = ['d.rast', 'map=' + raster] ll.AddLayer('raster', name=raster, checked=True, cmd=cmd) def _addContourLayer(self, event): ll = self.giface.GetLayerList() vector = self.contoursSelect.GetValue() if not vector: return cmd = ['d.vect', 'map=' + vector] ll.AddLayer('vector', name=vector, checked=True, cmd=cmd)
class ScanningPanel(wx.Panel): def __init__(self, parent, giface, settings, scaniface): wx.Panel.__init__(self, parent) self.giface = giface self.settings = settings self.scaniface = scaniface if 'scan' not in self.settings: self.settings['scan'] = {} self.settings['scan']['elevation'] = '' self.settings['scan']['region'] = '' self.settings['scan']['zexag'] = 1 self.settings['scan']['smooth'] = 8 self.settings['scan']['numscans'] = 1 self.settings['scan']['rotation_angle'] = 180 self.settings['scan']['resolution'] = 2 self.settings['scan']['trim_nsewtb'] = '30,30,30,30,50,150' self.settings['scan']['interpolate'] = False self.settings['scan']['trim_tolerance'] = '' self.settings['scan']['resolution'] = 2 self.scan = self.settings['scan'] self.settingsChanged = Signal('ScanningPanel.settingsChanged') mainSizer = wx.BoxSizer(wx.VERTICAL) # define static boxes before all widgets are defined georefBox = wx.StaticBox(self, label=' Georeferencing ') georefSizer = wx.StaticBoxSizer(georefBox, wx.VERTICAL) geomBox = wx.StaticBox(self, label=' Scan geometry ') geomSizer = wx.StaticBoxSizer(geomBox, wx.VERTICAL) demBox = wx.StaticBox(self, label=' DEM quality ') demSizer = wx.StaticBoxSizer(demBox, wx.VERTICAL) # create widgets self.btnCalibrateTilt = wx.Button(self, label="Calibration 1") self.btnCalibrateTilt.SetToolTipString('Calibrate to remove tilt of the scanner and to set suitable distance from the scanner') self.btnCalibrateExtent = wx.Button(self, label="Calibration 2") self.btnCalibrateExtent.SetToolTipString('Calibrate to identify the extent and position of the scanned object') # widgets for model self.elevInput = Select(self, size=(-1, -1), type='raster') self.elevInput.SetToolTipString('Raster from which we take the georeferencing information') self.regionInput = Select(self, size=(-1, -1), type='region') self.regionInput.SetToolTipString('Saved region from which we take the georeferencing information') self.zexag = wx.TextCtrl(self) self.zexag.SetToolTipString('Set vertical exaggeration of the physical model') self.numscans = wx.SpinCtrl(self, min=1, max=5, initial=1) self.numscans.SetToolTipString('Set number of scans to integrate') self.rotate = wx.SpinCtrl(self, min=0, max=360, initial=180) self.rotate.SetToolTipString('Set angle of rotation of the sensor around Z axis (typically 180 degrees)') self.smooth = wx.TextCtrl(self) self.smooth.SetToolTipString('Set smoothing of the DEM (typically between 7 to 12, higher value means more smoothing)') self.resolution = wx.TextCtrl(self) self.resolution.SetToolTipString('Raster resolution in mm of the ungeoreferenced scan') self.trim = {} for each in 'tbnsew': self.trim[each] = wx.TextCtrl(self, size=(40, -1)) if each in 'tb': self.trim[each].SetToolTipString('Distance from the scanner') else: self.trim[each].SetToolTipString('Distance from the center of scanning to the scanning boundary') self.trim_tolerance = wx.TextCtrl(self) self.trim_tolerance.SetToolTipString('Automatic trimming of the edges for rectangular models') self.interpolate = wx.CheckBox(self, label="Use interpolation instead of binning") self.interpolate.SetToolTipString('Interpolation avoids gaps in the scan, but takes longer') self.elevInput.SetValue(self.scan['elevation']) self.regionInput.SetValue(self.scan['region']) self.zexag.SetValue(str(self.scan['zexag'])) self.rotate.SetValue(self.scan['rotation_angle']) self.numscans.SetValue(self.scan['numscans']) self.interpolate.SetValue(self.scan['interpolate']) for i, each in enumerate('nsewtb'): self.trim[each].SetValue(self.scan['trim_nsewtb'].split(',')[i]) self.smooth.SetValue(str(self.scan['smooth'])) self.resolution.SetValue(str(self.scan['resolution'])) self.trim_tolerance.SetValue(str(self.scan['trim_tolerance'])) # layout # # Geometry box # # rotation hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Rotation angle:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) hSizer.Add(self.rotate, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) geomSizer.Add(hSizer, flag=wx.EXPAND) # trimming hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Trim vertically [cm]:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) for each in 'tb': hSizer.Add(wx.StaticText(self, label=each.upper() + ':'), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=2) hSizer.Add(self.trim[each], flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=2) hSizer.Add(self.btnCalibrateTilt, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=2) geomSizer.Add(hSizer, flag=wx.EXPAND) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Trim horizontally [cm]:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) for each in 'nsew': hSizer.Add(wx.StaticText(self, label=each.upper() + ':'), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=3) hSizer.Add(self.trim[each], flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=2) hSizer.Add(self.btnCalibrateExtent, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=2) geomSizer.Add(hSizer, flag=wx.EXPAND) # automatic trim hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Trim tolerance [0-1]:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) hSizer.Add(self.trim_tolerance, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) geomSizer.Add(hSizer, flag=wx.EXPAND) mainSizer.Add(geomSizer, flag=wx.EXPAND|wx.ALL, border=10) hSizer2 = wx.BoxSizer(wx.HORIZONTAL) # # Georeferencing box # # model parameters hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Reference DEM:"), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) hSizer.Add(self.elevInput, proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) georefSizer.Add(hSizer, flag=wx.EXPAND) # region hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Reference region:"), flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) hSizer.Add(self.regionInput, proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) georefSizer.Add(hSizer, flag=wx.EXPAND) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Z-exaggeration:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) hSizer.Add(self.zexag, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) georefSizer.Add(hSizer, flag=wx.EXPAND) hSizer2.Add(georefSizer, proportion=1, flag=wx.EXPAND|wx.RIGHT, border=10) # # DEM properties box # # number of scans hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Number of scans:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) hSizer.Add(self.numscans, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) demSizer.Add(hSizer, flag=wx.EXPAND) # smooth hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Smooth value:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) hSizer.Add(self.smooth, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) demSizer.Add(hSizer, flag=wx.EXPAND) # resolution hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(wx.StaticText(self, label="Resolution [mm]:"), proportion=1, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) hSizer.Add(self.resolution, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) demSizer.Add(hSizer, flag=wx.EXPAND) hSizer = wx.BoxSizer(wx.HORIZONTAL) hSizer.Add(self.interpolate, flag=wx.ALL | wx.ALIGN_CENTER_VERTICAL, border=5) demSizer.Add(hSizer, flag=wx.EXPAND) hSizer2.Add(demSizer, proportion=1, flag=wx.EXPAND) mainSizer.Add(hSizer2, flag=wx.EXPAND|wx.LEFT|wx.RIGHT|wx.BOTTOM, border=10) self.SetSizer(mainSizer) mainSizer.Fit(self) self.BindModelProperties() def BindModelProperties(self): self.btnCalibrateTilt.Bind(wx.EVT_BUTTON, self.scaniface.Calibrate) self.btnCalibrateExtent.Bind(wx.EVT_BUTTON, self.scaniface.CalibrateModelBBox) # model parameters self.elevInput.Bind(wx.EVT_TEXT, self.OnModelProperties) self.regionInput.Bind(wx.EVT_TEXT, self.OnModelProperties) self.zexag.Bind(wx.EVT_TEXT, self.OnModelProperties) self.rotate.Bind(wx.EVT_SPINCTRL, self.OnModelProperties) self.rotate.Bind(wx.EVT_TEXT, self.OnModelProperties) self.numscans.Bind(wx.EVT_SPINCTRL, self.OnModelProperties) self.numscans.Bind(wx.EVT_TEXT, self.OnModelProperties) self.interpolate.Bind(wx.EVT_CHECKBOX, self.OnModelProperties) self.smooth.Bind(wx.EVT_TEXT, self.OnModelProperties) self.resolution.Bind(wx.EVT_TEXT, self.OnModelProperties) self.trim_tolerance.Bind(wx.EVT_TEXT, self.OnModelProperties) for each in 'nsewtb': self.trim[each].Bind(wx.EVT_TEXT, self.OnModelProperties) def OnModelProperties(self, event): self.scan['elevation'] = self.elevInput.GetValue() self.scan['region'] = self.regionInput.GetValue() self.scan['rotation_angle'] = self.rotate.GetValue() self.scan['numscans'] = self.numscans.GetValue() self.scan['interpolate'] = self.interpolate.IsChecked() self.scan['smooth'] = self.smooth.GetValue() self.scan['resolution'] = self.resolution.GetValue() trim_tol = self.trim_tolerance.GetValue() self.scan['trim_tolerance'] = float(trim_tol) if trim_tol else trim_tol try: self.scan['zexag'] = float(self.zexag.GetValue()) nsewtb_list = [] for each in 'nsewtb': nsewtb_list.append(self.trim[each].GetValue()) self.scan['trim_nsewtb'] = ','.join(nsewtb_list) except ValueError: pass self.settingsChanged.emit()