Exemple #1
0
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
Exemple #2
0
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)
Exemple #3
0
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()