class StandaloneGrassInterface(GrassInterface): """@implements GrassInterface""" def __init__(self): # Signal when some map is created or updated by a module. # Used for adding/refreshing displayed layers. # attributes: name: map name, ltype: map type, # add: if map should be added to layer tree (questionable attribute) self.mapCreated = Signal("StandaloneGrassInterface.mapCreated") # Signal for communicating current mapset has been switched self.currentMapsetChanged = Signal( "StandaloneGrassInterface.currentMapsetChanged") # Signal for communicating something in current grassdb has changed. # Parameters: # action: required, is one of 'new', 'rename', 'delete' # element: required, can be one of 'grassdb', 'location', 'mapset', 'raster', 'vector' and 'raster_3d' # grassdb: path to grass db, required # location: location name, required # mapset: mapset name, required when element is 'mapset', 'raster', 'vector' or 'raster_3d' # map: map name, required when element is 'raster', 'vector' or 'raster_3d' # newname: new name (of mapset, map), required with action='rename' self.grassdbChanged = Signal("StandaloneGrassInterface.grassdbChanged") # Signal emitted to request updating of map self.updateMap = Signal("StandaloneGrassInterface.updateMap") # Signal emitted when workspace is changed self.workspaceChanged = Signal( "StandaloneGrassInterface.workspaceChanged") # workaround, standalone grass interface should be moved to sep. file from core.gconsole import GConsole, EVT_CMD_OUTPUT, EVT_CMD_PROGRESS self._gconsole = GConsole() self._gconsole.Bind(EVT_CMD_PROGRESS, self._onCmdProgress) self._gconsole.Bind(EVT_CMD_OUTPUT, self._onCmdOutput) self._gconsole.writeLog.connect(self.WriteLog) self._gconsole.writeCmdLog.connect(self.WriteCmdLog) self._gconsole.writeWarning.connect(self.WriteWarning) self._gconsole.writeError.connect(self.WriteError) def _onCmdOutput(self, event): """Print command output""" message = event.text style = event.type if style == "warning": self.WriteWarning(message) elif style == "error": self.WriteError(message) else: self.WriteLog(message) event.Skip() def _onCmdProgress(self, event): """Update progress message info""" grass.percent(event.value, 100, 1) event.Skip() def RunCmd( self, command, compReg=True, env=None, skipInterface=False, onDone=None, onPrepare=None, userData=None, addLayer=None, notification=Notification.MAKE_VISIBLE, ): self._gconsole.RunCmd( command=command, compReg=compReg, env=env, skipInterface=skipInterface, onDone=onDone, onPrepare=onPrepare, userData=userData, addLayer=addLayer, notification=notification, ) def Help(self, entry): self._gconsole.RunCmd(["g.manual", "entry=%s" % entry]) def WriteLog(self, text, wrap=None, notification=Notification.HIGHLIGHT): self._write(grass.message, text) def WriteCmdLog(self, text, pid=None, notification=Notification.MAKE_VISIBLE): if pid: text = "(" + str(pid) + ") " + text self._write(grass.message, text) def WriteWarning(self, text): self._write(grass.warning, text) def WriteError(self, text): self._write(grass.error, text) def _write(self, function, text): orig = os.getenv("GRASS_MESSAGE_FORMAT") os.environ["GRASS_MESSAGE_FORMAT"] = "standard" function(text) os.environ["GRASS_MESSAGE_FORMAT"] = orig def GetLog(self, err=False): if err: return sys.stdout return sys.stderr def GetLayerList(self): return [] def GetLayerTree(self): return None def GetMapDisplay(self): """Get current map display.""" return None def GetAllMapDisplays(self): """Get list of all map displays.""" return [] def GetMapWindow(self): raise NotImplementedError() def GetProgress(self): # TODO: implement some progress with same inface as gui one # (probably using g.message or similarly to Write... functions) raise NotImplementedError() def UpdateCmdHistory(self, cmd): """There is no history displayed to the user, doing nothing""" pass
class VNETManager: def __init__(self, guiparent, giface): self.data = {} self.guiparent = guiparent self.giface = giface self.mapWin = giface.GetMapWindow() self.goutput = GConsole(guiparent=guiparent) self.vnet_data = VNETData(guiparent=guiparent, mapWin=self.mapWin) self.results = { "analysis": None, "vect_map": None } # TODO more results # this class instance manages all temporary vector maps created during # life of VNETDialog self.tmp_maps = VNETTmpVectMaps(parent=guiparent, mapWin=self.mapWin) # initialization of History class used for saving and reading data from file # it is used for browsing analysis results self.history = VNETHistory(self.guiparent, self.vnet_data, self.tmp_maps) self.analyses = VNETAnalyses(self.vnet_data, self.RunAnDone, self.goutput, self.tmp_maps) self.snap_nodes = SnappingNodes(self.giface, self.vnet_data, self.tmp_maps, self.mapWin) self.ttbCreated = Signal('VNETManager.ttbCreated') self.analysisDone = Signal('VNETManager.analysisDone') self.pointsChanged = self.vnet_data.pointsChanged self.parametersChanged = self.vnet_data.parametersChanged self.snapping = self.snap_nodes.snapping self.pointsChanged.connect(self.PointsChanged) def __del__(self): self.CleanUp() def CleanUp(self): """Removes temp layers, unregisters handlers and graphics""" update = self.tmp_maps.DeleteAllTmpMaps() self.vnet_data.CleanUp() if update: self.giface.updateMap.emit(render=True, renderVector=True) else: self.giface.updateMap.emit(render=False, renderVector=False) def GetPointsManager(self): return self.vnet_data.GetPointsData() def GetGlobalTurnsData(self): return self.vnet_data.GetGlobalTurnsData() def RunAnalysis(self): analysis, valid = self.vnet_data.GetParam("analysis") params, err_params, flags = self.vnet_data.GetParams() relevant_params = self.vnet_data.GetRelevantParams(analysis) if not relevant_params: return -1 if not self.vnet_data.InputsErrorMsgs(_("Unable to perform analysis."), analysis, params, flags, err_params, relevant_params): return -2 if self.results["vect_map"]: self.results["vect_map"].DeleteRenderLayer() # history - delete data in buffer for hist step self.history.DeleteNewHistStepData() # create new map (included to history) for result of analysis self.results["vect_map"] = self.history.NewTmpVectMapToHist( 'vnet_tmp_result') if not self.results["vect_map"]: return False # for case there is some map with same name # (when analysis does not produce any map, this map would have been shown as result) RunCommand('g.remove', flags='f', type='vector', name=self.results["vect_map"].GetVectMapName()) # save data from self.history._saveAnInputToHist(analysis, params, flags) ret = self.analyses.RunAnalysis( self.results["vect_map"].GetVectMapName(), params, flags) if not ret: return -3 else: return 1 def RunAnDone(self, cmd, returncode, results): self.results["analysis"] = cmd[0] self.results["vect_map"].SaveVectMapState() cmd, cmd_colors = self.vnet_data.GetLayerStyle() self.results["vect_map"].AddRenderLayer(cmd, cmd_colors) self.history.SaveHistStep() self.analysisDone.emit() def ShowResult(self, show): # TODO can be more results e. g. smallest cut if show: self._checkResultMapChanged(self.results["vect_map"]) cmd, cmd_colors = self.vnet_data.GetLayerStyle() self.results["vect_map"].AddRenderLayer(cmd, cmd_colors) else: self.results["vect_map"].DeleteRenderLayer() self.giface.updateMap.emit(render=True, renderVector=True) def GetAnalysisProperties(self, analysis=None): return self.vnet_data.GetAnalysisProperties(analysis=analysis) def GetResults(self): return self.results["vect_map"] def Undo(self): self._updateDataForHistStep(self.history.Undo()) # SetUpdateMap TODO return self.history.GetHistStep() def Redo(self): self._updateDataForHistStep(self.history.Redo()) # SetUpdateMap return self.history.GetHistStep() def _updateDataForHistStep(self, data): if not data: return analysis, resultMapName, params, flags = data self.results["analysis"] = analysis self.vnet_data.SetParams(params, flags) self.results["vect_map"].DeleteRenderLayer() self.results["vect_map"] = self.tmp_maps.GetTmpVectMap(resultMapName) self._checkResultMapChanged(self.results["vect_map"]) cmd, cmd_colors = self.vnet_data.GetLayerStyle() self.results["vect_map"].AddRenderLayer(cmd, cmd_colors) self.giface.updateMap.emit(render=True, renderVector=True) def GetHistStep(self): return self.history.GetHistStep() def SetParams(self, params, flags): self.vnet_data.SetParams(params, flags) def GetParams(self): params, inv_params, flags = self.vnet_data.GetParams() return params, inv_params, flags def GetParam(self, param): return self.vnet_data.GetParam(param) def _checkResultMapChanged(self, resultVectMap): """Check if map was modified outside""" if resultVectMap.VectMapState() == 0: dlg = wx.MessageDialog( parent=self, message=_("Temporary map '%s' with result " + "was changed outside vector network analysis tool.\n" + "Showed result may not correspond " + "original analysis result.") % resultVectMap.GetVectMapName(), caption=_("Result changed outside"), style=wx.ICON_INFORMATION | wx.CENTRE) dlg.ShowModal() dlg.Destroy() def IsSnappingActive(self): return self.vnet_data.GetSnapping() def Snapping(self, activate): self.snap_nodes.ComputeNodes(activate) def GetAnalyses(self): return self.vnet_data.GetAnalyses() def SettingsUpdated(self): self.vnet_data.GetPointsData().SetPointDrawSettings() if not self.results["vect_map"] or not self.tmp_maps.HasTmpVectMap( self.results["vect_map"].GetVectMapName()): self.giface.updateMap.emit(render=False, renderVector=False) elif self.results["vect_map"].GetRenderLayer(): cmd, cmd_colors = self.vnet_data.GetLayerStyle() self.results["vect_map"].AddRenderLayer(cmd, cmd_colors) self.giface.updateMap.emit(render=True, renderVector=True) # TODO optimization else: self.giface.updateMap.emit(render=False, renderVector=False) def PointsChanged(self, method, kwargs): self.giface.updateMap.emit(render=False, renderVector=False) def CreateTttb(self, params): outputMap = params["output"] mapName, mapSet = ParseMapStr(outputMap) if mapSet != grass.gisenv()['MAPSET']: GMessage(parent=self, message=_("Map can be created only in current mapset")) return False existsMap = grass.find_file(name=mapName, element='vector', mapset=grass.gisenv()['MAPSET']) if existsMap["name"]: dlg = wx.MessageDialog(parent=self.guiparent, message=_("Vector map %s already exists. " + "Do you want to overwrite it?") % (existsMap["fullname"]), caption=_("Overwrite vector map"), style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION | wx.CENTRE) ret = dlg.ShowModal() dlg.Destroy() if ret == wx.ID_NO: return False cmdTtb = [ "v.net.turntable", "input=" + params["input"], "output=" + params["output"], "arc_layer=" + params["arc_layer"], "turn_layer=" + params["turn_layer"], "turn_cat_layer=" + params["turn_cat_layer"], "--overwrite", ] self.goutput.RunCmd(command=cmdTtb, onDone=self._createTtbDone) return True def _createTtbDone(self, event): if event.returncode != 0: GMessage(parent=self.guiparent, message=_("Creation of turntable failed.")) return else: params = {} for c in event.cmd: spl_c = c.split("=") if len(spl_c) != 2: continue if spl_c[0] and spl_c != "input": params[spl_c[0]] = spl_c[1] if spl_c[0] == "output": params["input"] = spl_c[1] self.vnet_data.SetParams(params, {}) self.ttbCreated.emit(returncode=event.returncode) def SaveTmpLayer(self, layer_name): """Permanently saves temporary map of analysis result""" msg = _("Vector map with analysis result does not exist.") if not hasattr(self.results["vect_map"], "GetVectMapName"): GMessage(parent=self.guiparent, message=msg) return mapToAdd = self.results["vect_map"].GetVectMapName() mapToAddEx = grass.find_file(name=mapToAdd, element='vector', mapset=grass.gisenv()['MAPSET']) if not mapToAddEx["name"]: GMessage(parent=self.guiparent, message=msg) return addedMap = layer_name mapName, mapSet = ParseMapStr(addedMap) if mapSet != grass.gisenv()['MAPSET']: GMessage( parent=self.guiparent, message=_("Map can be saved only to currently set mapset")) return existsMap = grass.find_file(name=mapName, element='vector', mapset=grass.gisenv()['MAPSET']) if existsMap["name"]: dlg = wx.MessageDialog(parent=self.guiparent, message=_("Vector map %s already exists. " + "Do you want to overwrite it?") % (existsMap["fullname"]), caption=_("Overwrite vector map"), style=wx.YES_NO | wx.NO_DEFAULT | wx.ICON_QUESTION | wx.CENTRE) ret = dlg.ShowModal() if ret == wx.ID_NO: dlg.Destroy() return dlg.Destroy() RunCommand("g.copy", overwrite=True, vector=[self.results["vect_map"].GetVectMapName(), mapName]) if len(self.giface.GetLayerList().GetLayersByName(mapName)) == 0: # TODO: get rid of insert cmd, cmd_colors = self.vnet_data.GetLayerStyle() cmd.insert(0, 'd.vect') cmd.append('map=%s' % mapName) self.giface.GetLayerList().AddLayer(ltype="vector", name=mapName, cmd=cmd, checked=True) if cmd_colors: layerStyleVnetColors = cmdlist_to_tuple(cmd_colors) RunCommand(layerStyleVnetColors[0], **layerStyleVnetColors[1]) else: self.giface.updateMap.emit(render=True, renderVector=True)
class StandaloneGrassInterface(): """@implements GrassInterface""" def __init__(self): # Signal when some map is created or updated by a module. # attributes: name: map name, ltype: map type, # add: if map should be added to layer tree (questionable attribute) self.mapCreated = Signal('StandaloneGrassInterface.mapCreated') # Signal emitted to request updating of map self.updateMap = Signal('StandaloneGrassInterface.updateMap') # workaround, standalone grass interface should be moved to sep. file from core.gconsole import GConsole, \ EVT_CMD_OUTPUT, EVT_CMD_PROGRESS self._gconsole = GConsole() self._gconsole.Bind(EVT_CMD_PROGRESS, self._onCmdProgress) self._gconsole.Bind(EVT_CMD_OUTPUT, self._onCmdOutput) self._gconsole.writeLog.connect(self.WriteLog) self._gconsole.writeCmdLog.connect(self.WriteCmdLog) self._gconsole.writeWarning.connect(self.WriteWarning) self._gconsole.writeError.connect(self.WriteError) def _onCmdOutput(self, event): """Print command output""" message = event.text style = event.type if style == 'warning': self.WriteWarning(message) elif style == 'error': self.WriteError(message) else: self.WriteLog(message) event.Skip() def _onCmdProgress(self, event): """Update progress message info""" grass.percent(event.value, 100, 1) event.Skip() def RunCmd(self, command, compReg=True, skipInterface=False, onDone=None, onPrepare=None, userData=None, notification=Notification.MAKE_VISIBLE): self._gconsole.RunCmd(command=command, compReg=compReg, skipInterface=skipInterface, onDone=onDone, onPrepare=onPrepare, userData=userData, notification=notification) def Help(self, entry): self._gconsole.RunCmd(['g.manual', 'entry=%s' % entry]) def WriteLog(self, text, wrap=None, notification=Notification.HIGHLIGHT): self._write(grass.message, text) def WriteCmdLog(self, text, pid=None, notification=Notification.MAKE_VISIBLE): if pid: text = '(' + str(pid) + ') ' + text self._write(grass.message, text) def WriteWarning(self, text): self._write(grass.warning, text) def WriteError(self, text): self._write(grass.error, text) def _write(self, function, text): orig = os.getenv("GRASS_MESSAGE_FORMAT") os.environ["GRASS_MESSAGE_FORMAT"] = 'standard' function(text) os.environ["GRASS_MESSAGE_FORMAT"] = orig def GetLayerList(self): raise NotImplementedError() def GetLayerTree(self): return None def GetMapDisplay(self): """Get current map display. """ return None def GetAllMapDisplays(self): """Get list of all map displays. """ return [] def GetMapWindow(self): raise NotImplementedError() def GetProgress(self): # TODO: implement some progress with same inface as gui one # (probably using g.message or similarly to Write... functions) raise NotImplementedError() def UpdateCmdHistory(self, cmd): raise NotImplementedError()