Beispiel #1
0
def _executeAlgorithm(alg):
    message = alg.checkBeforeOpeningParametersDialog()
    if message:
        dlg = MessageDialog()
        dlg.setTitle(Processing.tr('Missing dependency'))
        dlg.setMessage(
            Processing.tr('<h3>Missing dependency. This algorithm cannot '
                          'be run :-( </h3>\n{0}').format(message))
        dlg.exec_()
        return
    alg = alg.getCopy()
    if (alg.getVisibleParametersCount() + alg.getVisibleOutputsCount()) > 0:
        dlg = alg.getCustomParametersDialog()
        if not dlg:
            dlg = AlgorithmDialog(alg)
        canvas = iface.mapCanvas()
        prevMapTool = canvas.mapTool()
        dlg.show()
        dlg.exec_()
        if canvas.mapTool() != prevMapTool:
            try:
                canvas.mapTool().reset()
            except:
                pass
            canvas.setMapTool(prevMapTool)
    else:
        feedback = MessageBarProgress()
        execute(alg, feedback)
        handleAlgorithmResults(alg, feedback)
        feedback.close()
    def test_check_validity(self):
        """Test that the output invalid contains the error reason"""

        polygon_layer = self._make_layer('Polygon')
        self.assertTrue(polygon_layer.startEditing())
        f = QgsFeature(polygon_layer.fields())
        f.setAttributes([1])
        # Flake!
        f.setGeometry(QgsGeometry.fromWkt(
            'POLYGON ((0 0, 2 2, 0 2, 2 0, 0 0))'))
        self.assertTrue(f.isValid())
        f2 = QgsFeature(polygon_layer.fields())
        f2.setAttributes([1])
        f2.setGeometry(QgsGeometry.fromWkt(
            'POLYGON((1.1 1.1, 1.1 2.1, 2.1 2.1, 2.1 1.1, 1.1 1.1))'))
        self.assertTrue(f2.isValid())
        self.assertTrue(polygon_layer.addFeatures([f, f2]))
        polygon_layer.commitChanges()
        polygon_layer.rollBack()
        self.assertEqual(polygon_layer.featureCount(), 2)

        QgsProject.instance().addMapLayers([polygon_layer])

        alg = self.registry.createAlgorithmById('qgis:checkvalidity')

        context = QgsProcessingContext()
        context.setProject(QgsProject.instance())
        feedback = ConsoleFeedBack()

        self.assertIsNotNone(alg)
        parameters = {}
        parameters['INPUT_LAYER'] = polygon_layer.id()
        parameters['VALID_OUTPUT'] = 'memory:'
        parameters['INVALID_OUTPUT'] = 'memory:'
        parameters['ERROR_OUTPUT'] = 'memory:'

        # QGIS method
        parameters['METHOD'] = 1
        ok, results = execute(
            alg, parameters, context=context, feedback=feedback)
        self.assertTrue(ok)
        invalid_layer = QgsProcessingUtils.mapLayerFromString(
            results['INVALID_OUTPUT'], context)
        self.assertEqual(invalid_layer.fields().names()[-1], '_errors')
        self.assertEqual(invalid_layer.featureCount(), 1)
        f = next(invalid_layer.getFeatures())
        self.assertEqual(f.attributes(), [
                         1, 'segments 0 and 2 of line 0 intersect at 1, 1'])

        # GEOS method
        parameters['METHOD'] = 2
        ok, results = execute(
            alg, parameters, context=context, feedback=feedback)
        self.assertTrue(ok)
        invalid_layer = QgsProcessingUtils.mapLayerFromString(
            results['INVALID_OUTPUT'], context)
        self.assertEqual(invalid_layer.fields().names()[-1], '_errors')
        self.assertEqual(invalid_layer.featureCount(), 1)
        f = next(invalid_layer.getFeatures())
        self.assertEqual(f.attributes(), [1, 'Self-intersection'])
    def executeAlgorithm(self):
        alg = self.algorithmTree.selectedAlgorithm()
        if alg is not None:
            ok, message = alg.canExecute()
            if not ok:
                dlg = MessageDialog()
                dlg.setTitle(self.tr('Error executing algorithm'))
                dlg.setMessage(
                    self.tr('<h3>This algorithm cannot '
                            'be run :-( </h3>\n{0}').format(message))
                dlg.exec_()
                return

            if alg.countVisibleParameters() > 0:
                dlg = alg.createCustomParametersWidget(self)

                if not dlg:
                    dlg = AlgorithmDialog(alg)
                canvas = iface.mapCanvas()
                prevMapTool = canvas.mapTool()
                dlg.show()
                dlg.exec_()
                if canvas.mapTool() != prevMapTool:
                    try:
                        canvas.mapTool().reset()
                    except:
                        pass
                    canvas.setMapTool(prevMapTool)
            else:
                feedback = MessageBarProgress()
                context = dataobjects.createContext(feedback)
                parameters = {}
                ret, results = execute(alg, parameters, context, feedback)
                handleAlgorithmResults(alg, context, feedback)
                feedback.close()
Beispiel #4
0
def _executeAlgorithm(alg):
    ok, message = alg.canExecute()
    if not ok:
        dlg = MessageDialog()
        dlg.setTitle(Processing.tr('Missing dependency'))
        dlg.setMessage(
            Processing.tr('<h3>Missing dependency. This algorithm cannot '
                          'be run :-( </h3>\n{0}').format(message))
        dlg.exec_()
        return

    if (alg.countVisibleParameters()) > 0:
        dlg = alg.createCustomParametersWidget(None)
        if not dlg:
            dlg = AlgorithmDialog(alg)
        canvas = iface.mapCanvas()
        prevMapTool = canvas.mapTool()
        dlg.show()
        dlg.exec_()
        if canvas.mapTool() != prevMapTool:
            try:
                canvas.mapTool().reset()
            except:
                pass
            canvas.setMapTool(prevMapTool)
    else:
        feedback = MessageBarProgress()
        context = dataobjects.createContext(feedback)
        parameters = {}
        ret, results = execute(alg, parameters, context, feedback)
        handleAlgorithmResults(alg, context, feedback)
        feedback.close()
Beispiel #5
0
    def executeAlgorithm(self):
        item = self.algorithmTree.currentItem()
        if isinstance(item, TreeAlgorithmItem):
            alg = QgsApplication.processingRegistry().createAlgorithmById(item.alg.id())
            if not alg:
                return

            ok, message = alg.canExecute()
            if not ok:
                dlg = MessageDialog()
                dlg.setTitle(self.tr('Error executing algorithm'))
                dlg.setMessage(
                    self.tr('<h3>This algorithm cannot '
                            'be run :-( </h3>\n{0}').format(message))
                dlg.exec_()
                return

            if alg.countVisibleParameters() > 0:
                dlg = alg.createCustomParametersWidget(self)

                if not dlg:
                    dlg = AlgorithmDialog(alg)
                canvas = iface.mapCanvas()
                prevMapTool = canvas.mapTool()
                dlg.show()
                dlg.exec_()
                if canvas.mapTool() != prevMapTool:
                    try:
                        canvas.mapTool().reset()
                    except:
                        pass
                    canvas.setMapTool(prevMapTool)
                if dlg.executed:
                    showRecent = ProcessingConfig.getSetting(
                        ProcessingConfig.SHOW_RECENT_ALGORITHMS)
                    if showRecent:
                        self.addRecentAlgorithms(True)
                # have to manually delete the dialog - otherwise it's owned by the
                # iface mainWindow and never deleted
                dlg.deleteLater()
            else:
                feedback = MessageBarProgress()
                context = dataobjects.createContext(feedback)
                parameters = {}
                ret, results = execute(alg, parameters, context, feedback)
                handleAlgorithmResults(alg, context, feedback)
                feedback.close()
        if isinstance(item, TreeActionItem):
            action = item.action
            action.setData(self)
            action.execute()
    def accept(self):
        keepOpen = ProcessingConfig.getSetting(ProcessingConfig.KEEP_DIALOG_OPEN)
        parameters = self.getParamValues()
        if parameters:
            with OverrideCursor(Qt.WaitCursor):
                context = dataobjects.createContext()
                ProcessingLog.addToLog(self.alg.asPythonCommand(parameters, context))

                self.executed, results = execute(self.alg, parameters, context, self.feedback)
                if self.executed:
                    handleAlgorithmResults(self.alg,
                                           context,
                                           self.feedback,
                                           not keepOpen)
                if not keepOpen:
                    QDialog.reject(self)
    def accept(self):
        keepOpen = ProcessingConfig.getSetting(ProcessingConfig.KEEP_DIALOG_OPEN)
        try:
            if self.setParamValues():
                QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
                ProcessingLog.addToLog(ProcessingLog.LOG_ALGORITHM,
                                       self.alg.getAsCommand())

                self.executed = execute(self.alg, self.feedback)
                if self.executed:
                    handleAlgorithmResults(self.alg,
                                           self.feedback,
                                           not keepOpen)
                if not keepOpen:
                    QDialog.reject(self)
        finally:
            QApplication.restoreOverrideCursor()
Beispiel #8
0
    def executeAlgorithm(self):
        alg = self.algorithmTree.selectedAlgorithm().create() if self.algorithmTree.selectedAlgorithm() is not None else None
        if alg is not None:
            ok, message = alg.canExecute()
            if not ok:
                dlg = MessageDialog()
                dlg.setTitle(self.tr('Error executing algorithm'))
                dlg.setMessage(
                    self.tr('<h3>This algorithm cannot '
                            'be run :-( </h3>\n{0}').format(message))
                dlg.exec_()
                return

            if self.in_place_mode and not [d for d in alg.parameterDefinitions() if d.name() not in ('INPUT', 'OUTPUT')]:
                parameters = {}
                feedback = MessageBarProgress(algname=alg.displayName())
                ok, results = execute_in_place(alg, parameters, feedback=feedback)
                if ok:
                    iface.messageBar().pushSuccess('', self.tr('{} complete').format(alg.displayName()))
                feedback.close()
                # MessageBarProgress handles errors
                return

            if alg.countVisibleParameters() > 0:
                dlg = alg.createCustomParametersWidget(self)

                if not dlg:
                    dlg = AlgorithmDialog(alg, self.in_place_mode, iface.mainWindow())
                dlg.setAttribute(Qt.WA_DeleteOnClose)
                canvas = iface.mapCanvas()
                prevMapTool = canvas.mapTool()
                dlg.show()
                dlg.exec_()
                if canvas.mapTool() != prevMapTool:
                    try:
                        canvas.mapTool().reset()
                    except:
                        pass
                    canvas.setMapTool(prevMapTool)
            else:
                feedback = MessageBarProgress(algname=alg.displayName())
                context = dataobjects.createContext(feedback)
                parameters = {}
                ret, results = execute(alg, parameters, context, feedback)
                handleAlgorithmResults(alg, context, feedback)
                feedback.close()
    def test_import(self):
        """Test algorithm with CamelCaseSchema"""

        alg = self.registry.createAlgorithmById("qgis:importintopostgis")
        self.assertIsNotNone(alg)

        table_name = 'out_TestPyQgsExportToPostgis'

        parameters = {
            'CREATEINDEX': True,
            'DATABASE': 'qgis_test',
            'DROP_STRING_LENGTH': False,
            'ENCODING': 'UTF-8',
            'FORCE_SINGLEPART': False,
            'GEOMETRY_COLUMN': 'geom',
            'INPUT': unitTestDataPath() + '/points.shp',
            'LOWERCASE_NAMES': True,
            'OVERWRITE': True,
            'PRIMARY_KEY': None,
            'SCHEMA': 'CamelCaseSchema',
            'TABLENAME': table_name
        }

        feedback = ConsoleFeedBack()
        context = QgsProcessingContext()
        # Note: the following returns true also in case of errors ...
        self.assertTrue(execute(alg, parameters, context, feedback))
        # ... so we check the log
        self.assertEqual(feedback._errors, [])

        # Check that data have been imported correctly
        exported = QgsVectorLayer(unitTestDataPath() + '/points.shp', 'exported')
        self.assertTrue(exported.isValid())
        imported = QgsVectorLayer("service='qgis_test' dbname=\'qgis_test\' table=\"CamelCaseSchema\".\"%s\" (geom)" % table_name, 'imported', 'postgres')
        self.assertTrue(imported.isValid())
        imported_fields = [f.name() for f in imported.fields()]
        for f in exported.fields():
            self.assertTrue(f.name().lower() in imported_fields)

        # Check data
        imported_f = next(imported.getFeatures("class = 'Jet' AND heading = 85"))
        self.assertTrue(imported_f.isValid())
        exported_f = next(exported.getFeatures("class = 'Jet' AND heading = 85"))
        self.assertTrue(exported_f.isValid())
        self.assertEqual(exported_f.geometry().asWkt(), imported_f.geometry().asWkt())
Beispiel #10
0
def _executeAlgorithm(alg_id):
    alg = QgsApplication.processingRegistry().createAlgorithmById(alg_id)
    if alg is None:
        dlg = MessageDialog()
        dlg.setTitle(Processing.tr('Missing Algorithm'))
        dlg.setMessage(
            Processing.tr('The algorithm "{}" is no longer available. (Perhaps a plugin was uninstalled?)').format(alg_id))
        dlg.exec_()
        return

    ok, message = alg.canExecute()
    if not ok:
        dlg = MessageDialog()
        dlg.setTitle(Processing.tr('Missing Dependency'))
        dlg.setMessage(
            Processing.tr('<h3>Missing dependency. This algorithm cannot '
                          'be run :-( </h3>\n{0}').format(message))
        dlg.exec_()
        return

    if (alg.countVisibleParameters()) > 0:
        dlg = alg.createCustomParametersWidget(parent=iface.mainWindow())
        if not dlg:
            dlg = AlgorithmDialog(alg, parent=iface.mainWindow())
        canvas = iface.mapCanvas()
        prevMapTool = canvas.mapTool()
        dlg.show()
        dlg.exec_()
        if canvas.mapTool() != prevMapTool:
            try:
                canvas.mapTool().reset()
            except:
                pass
            canvas.setMapTool(prevMapTool)
    else:
        feedback = MessageBarProgress()
        context = dataobjects.createContext(feedback)
        parameters = {}
        ret, results = execute(alg, parameters, context, feedback)
        handleAlgorithmResults(alg, context, feedback)
        feedback.close()
Beispiel #11
0
    def accept(self):
        keepOpen = ProcessingConfig.getSetting(ProcessingConfig.KEEP_DIALOG_OPEN)
        parameters = self.getParamValues()
        if parameters:
            with OverrideCursor(Qt.WaitCursor):
                self.feedback = FieldCalculatorFeedback(self)
                self.feedback.progressChanged.connect(self.setPercentage)

                context = dataobjects.createContext()
                ProcessingLog.addToLog(self.alg.asPythonCommand(parameters, context))

                self.executed, results = execute(self.alg, parameters, context, self.feedback)
                self.setPercentage(0)

                if self.executed:
                    handleAlgorithmResults(self.alg,
                                           context,
                                           self.feedback,
                                           not keepOpen)
                self._wasExecuted = self.executed or self._wasExecuted
                if not keepOpen:
                    QDialog.reject(self)
Beispiel #12
0
    def runAlgorithm(algOrName, onFinish, *args, **kwargs):
        if isinstance(algOrName, GeoAlgorithm):
            alg = algOrName
        else:
            alg = QgsApplication.processingRegistry().algorithmById(algOrName)
        if alg is None:
            # fix_print_with_import
            print('Error: Algorithm not found\n')
            QgsMessageLog.logMessage(Processing.tr('Error: Algorithm {0} not found\n').format(algOrName),
                                     Processing.tr("Processing"))
            return

        parameters = {}
        if len(args) == 1 and isinstance(args[0], dict):
            # Set params by name and try to run the alg even if not all parameter values are provided,
            # by using the default values instead.
            for (name, value) in list(args[0].items()):
                param = alg.parameterDefinition(name)
                if param:
                    parameters[param.name()] = value
                    continue
                # fix_print_with_import
                print('Error: Wrong parameter value %s for parameter %s.' % (value, name))
                QgsMessageLog.logMessage(
                    Processing.tr('Error: Wrong parameter value {0} for parameter {1}.').format(value, name),
                    Processing.tr("Processing"))
                QgsMessageLog.logMessage(Processing.tr('Error in {0}. Wrong parameter value {1} for parameter {2}.').format(
                    alg.name(), value, name
                ), Processing.tr("Processing"),
                    QgsMessageLog.CRITICAL
                )
                return
            # check for any manadatory parameters which were not specified
            for param in alg.parameterDefinitions():
                if param.name() not in parameters:
                    if not param.flags() & QgsProcessingParameterDefinition.FlagOptional:
                        # fix_print_with_import
                        print('Error: Missing parameter value for parameter %s.' % param.name())
                        QgsMessageLog.logMessage(
                            Processing.tr('Error: Missing parameter value for parameter {0}.').format(param.name()),
                            Processing.tr("Processing"))
                        return
        else:
            if len(args) != alg.countVisibleParameters():
                # fix_print_with_import
                print('Error: Wrong number of parameters')
                QgsMessageLog.logMessage(Processing.tr('Error: Wrong number of parameters'),
                                         Processing.tr("Processing"))
                processing.algorithmHelp(algOrName)
                return
            i = 0
            for param in alg.parameterDefinitions():
                if not param.flags() & QgsProcessingParameterDefinition.FlagHidden:
                    if not True: # TODO param.setValue(args[i]):
                        # fix_print_with_import
                        print('Error: Wrong parameter value: ' + str(args[i]))
                        QgsMessageLog.logMessage(Processing.tr('Error: Wrong parameter value: ') + str(args[i]),
                                                 Processing.tr("Processing"))
                        return
                    else:
                        parameters[param.name()] = args[i]
                    i = i + 1

            for output in alg.outputs:
                if not output.flags() & QgsProcessingParameterDefinition.FlagHidden:
                    if not output.setValue(args[i]):
                        # fix_print_with_import
                        print('Error: Wrong output value: ' + str(args[i]))
                        QgsMessageLog.logMessage(Processing.tr('Error: Wrong output value: ') + str(args[i]),
                                                 Processing.tr("Processing"))
                        return
                    i = i + 1

        context = None
        if kwargs is not None and 'context' in list(kwargs.keys()):
            context = kwargs["context"]
        else:
            context = dataobjects.createContext()

        ok, msg = alg.checkParameterValues(parameters, context)
        if not ok:
            # fix_print_with_import
            print('Unable to execute algorithm\n' + str(msg))
            QgsMessageLog.logMessage(Processing.tr('Unable to execute algorithm\n{0}').format(msg),
                                     Processing.tr("Processing"))
            return

        if not alg.validateInputCrs(parameters, context):
            print('Warning: Not all input layers use the same CRS.\n' +
                  'This can cause unexpected results.')
            QgsMessageLog.logMessage(
                Processing.tr('Warning: Not all input layers use the same CRS.\nThis can cause unexpected results.'),
                Processing.tr("Processing"))

        # Don't set the wait cursor twice, because then when you
        # restore it, it will still be a wait cursor.
        overrideCursor = False
        if iface is not None:
            cursor = QApplication.overrideCursor()
            if cursor is None or cursor == 0:
                QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
                overrideCursor = True
            elif cursor.shape() != Qt.WaitCursor:
                QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
                overrideCursor = True

        feedback = None
        if kwargs is not None and "feedback" in list(kwargs.keys()):
            feedback = kwargs["feedback"]
        elif iface is not None:
            feedback = MessageBarProgress(alg.displayName())

        ret, results = execute(alg, parameters, context, feedback)
        if ret:
            if onFinish is not None:
                onFinish(alg, context, feedback)
        else:
            QgsMessageLog.logMessage(Processing.tr("There were errors executing the algorithm."),
                                     Processing.tr("Processing"))

        if overrideCursor:
            QApplication.restoreOverrideCursor()
        if isinstance(feedback, MessageBarProgress):
            feedback.close()
        return results
Beispiel #13
0
    def accept(self):
        self.algs = []
        self.load = []
        self.canceled = False

        for row in range(self.mainWidget.tblParameters.rowCount()):
            alg = self.alg.getCopy()
            col = 0
            for param in alg.parameters:
                if param.hidden:
                    continue
                wrapper = self.mainWidget.wrappers[row][col]
                if not self.mainWidget.setParamValue(param, wrapper, alg):
                    self.bar.pushMessage("", self.tr('Wrong or missing parameter value: {0} (row {1})').format(
                                         param.description, row + 1),
                                         level=QgsMessageBar.WARNING, duration=5)
                    self.algs = None
                    return
                col += 1
            for out in alg.outputs:
                if out.hidden:
                    continue

                widget = self.mainWidget.tblParameters.cellWidget(row, col)
                text = widget.getValue()
                if text.strip() != '':
                    out.value = text
                    col += 1
                else:
                    self.bar.pushMessage("", self.tr('Wrong or missing output value: {0} (row {1})').format(
                                         out.description, row + 1),
                                         level=QgsMessageBar.WARNING, duration=5)
                    self.algs = None
                    return

            self.algs.append(alg)
            if self.alg.getVisibleOutputsCount():
                widget = self.mainWidget.tblParameters.cellWidget(row, col)
                self.load.append(widget.currentIndex() == 0)
            else:
                self.load.append(False)

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        self.mainWidget.setEnabled(False)

        self.progressBar.setMaximum(len(self.algs))
        # Make sure the Log tab is visible before executing the algorithm
        try:
            self.tabWidget.setCurrentIndex(1)
            self.repaint()
        except:
            pass

        for count, alg in enumerate(self.algs):
            self.setText(self.tr('\nProcessing algorithm {0}/{1}...').format(count + 1, len(self.algs)))
            self.setInfo(self.tr('<b>Algorithm {0} starting...</b>').format(alg.displayName()))
            if execute(alg, self.feedback) and not self.canceled:
                if self.load[count]:
                    handleAlgorithmResults(alg, self.feedback, False)
                self.setInfo(self.tr('Algorithm {0} correctly executed...').format(alg.displayName()))
            else:
                QApplication.restoreOverrideCursor()
                return

        self.finish()
Beispiel #14
0
    def runAlgorithm(self):
        self.feedback = self.createFeedback()
        self.context = dataobjects.createContext(self.feedback)
        self.context.setLogLevel(self.logLevel())

        checkCRS = ProcessingConfig.getSetting(
            ProcessingConfig.WARN_UNMATCHING_CRS)
        try:
            parameters = self.createProcessingParameters()

            if checkCRS and not self.algorithm().validateInputCrs(
                    parameters, self.context):
                reply = QMessageBox.question(
                    self, self.tr("Unmatching CRS's"),
                    self.tr('Parameters do not all use the same CRS. This can '
                            'cause unexpected results.\nDo you want to '
                            'continue?'), QMessageBox.Yes | QMessageBox.No,
                    QMessageBox.No)
                if reply == QMessageBox.No:
                    return
            ok, msg = self.algorithm().checkParameterValues(
                parameters, self.context)
            if not ok:
                QMessageBox.warning(self,
                                    self.tr('Unable to execute algorithm'),
                                    msg)
                return

            self.blockControlsWhileRunning()
            self.setExecutedAnyResult(True)
            self.cancelButton().setEnabled(False)

            self.iterateParam = None

            for param in self.algorithm().parameterDefinitions():
                if isinstance(
                        parameters.get(param.name(), None),
                        QgsProcessingFeatureSourceDefinition
                ) and parameters[param.name(
                )].flags & QgsProcessingFeatureSourceDefinition.FlagCreateIndividualOutputPerInputFeature:
                    self.iterateParam = param.name()
                    break

            self.clearProgress()
            self.feedback.pushVersionInfo(self.algorithm().provider())
            if self.algorithm().provider().warningMessage():
                self.feedback.reportError(
                    self.algorithm().provider().warningMessage())

            self.setProgressText(
                QCoreApplication.translate('AlgorithmDialog',
                                           'Processing algorithm…'))

            self.setInfo(QCoreApplication.translate(
                'AlgorithmDialog',
                '<b>Algorithm \'{0}\' starting&hellip;</b>').format(
                    self.algorithm().displayName()),
                         escapeHtml=False)

            self.feedback.pushInfo(self.tr('Input parameters:'))
            display_params = []
            for k, v in parameters.items():
                display_params.append("'" + k + "' : " + self.algorithm(
                ).parameterDefinition(k).valueAsPythonString(v, self.context))
            self.feedback.pushCommandInfo('{ ' + ', '.join(display_params) +
                                          ' }')
            self.feedback.pushInfo('')
            start_time = time.time()

            def elapsed_time(start_time, result):
                delta_t = time.time() - start_time
                hours = int(delta_t / 3600)
                minutes = int((delta_t % 3600) / 60)
                seconds = delta_t - hours * 3600 - minutes * 60

                str_hours = [self.tr("hour"), self.tr("hours")][hours > 1]
                str_minutes = [self.tr("minute"),
                               self.tr("minutes")][minutes > 1]
                str_seconds = [self.tr("second"),
                               self.tr("seconds")][seconds != 1]

                if hours > 0:
                    elapsed = '{0} {1:0.2f} {2} ({3} {4} {5} {6} {7:0.0f} {2})'.format(
                        result, delta_t, str_seconds, hours, str_hours,
                        minutes, str_minutes, seconds)
                elif minutes > 0:
                    elapsed = '{0} {1:0.2f} {2} ({3} {4} {5:0.0f} {2})'.format(
                        result, delta_t, str_seconds, minutes, str_minutes,
                        seconds)
                else:
                    elapsed = '{0} {1:0.2f} {2}'.format(
                        result, delta_t, str_seconds)

                return (elapsed)

            if self.iterateParam:
                # Make sure the Log tab is visible before executing the algorithm
                try:
                    self.showLog()
                    self.repaint()
                except:
                    pass

                self.cancelButton().setEnabled(
                    self.algorithm().flags()
                    & QgsProcessingAlgorithm.FlagCanCancel)
                if executeIterating(self.algorithm(), parameters,
                                    self.iterateParam, self.context,
                                    self.feedback):
                    self.feedback.pushInfo(
                        self.tr(
                            elapsed_time(start_time,
                                         'Execution completed in')))
                    self.cancelButton().setEnabled(False)
                    self.finish(True, parameters, self.context, self.feedback)
                else:
                    self.cancelButton().setEnabled(False)
                    self.resetGui()
            else:
                command = self.algorithm().asPythonCommand(
                    parameters, self.context)
                if command:
                    ProcessingLog.addToLog(command)
                QgsGui.instance().processingRecentAlgorithmLog().push(
                    self.algorithm().id())
                self.cancelButton().setEnabled(
                    self.algorithm().flags()
                    & QgsProcessingAlgorithm.FlagCanCancel)

                def on_complete(ok, results):
                    if ok:
                        self.feedback.pushInfo(
                            self.tr(
                                elapsed_time(start_time,
                                             'Execution completed in')))
                        self.feedback.pushInfo(self.tr('Results:'))
                        r = {
                            k: v
                            for k, v in results.items()
                            if k not in ('CHILD_RESULTS', 'CHILD_INPUTS')
                        }
                        self.feedback.pushCommandInfo(pformat(r))
                    else:
                        self.feedback.reportError(
                            self.tr(
                                elapsed_time(start_time,
                                             'Execution failed after')))
                    self.feedback.pushInfo('')

                    if self.feedback_dialog is not None:
                        self.feedback_dialog.close()
                        self.feedback_dialog.deleteLater()
                        self.feedback_dialog = None

                    self.cancelButton().setEnabled(False)

                    self.finish(ok,
                                results,
                                self.context,
                                self.feedback,
                                in_place=self.in_place)

                    self.feedback = None
                    self.context = None

                if not self.in_place and not (
                        self.algorithm().flags()
                        & QgsProcessingAlgorithm.FlagNoThreading):
                    # Make sure the Log tab is visible before executing the algorithm
                    self.showLog()

                    task = QgsProcessingAlgRunnerTask(self.algorithm(),
                                                      parameters, self.context,
                                                      self.feedback)
                    if task.isCanceled():
                        on_complete(False, {})
                    else:
                        task.executed.connect(on_complete)
                        self.setCurrentTask(task)
                else:
                    self.proxy_progress = QgsProxyProgressTask(
                        QCoreApplication.translate(
                            "AlgorithmDialog", "Executing “{}”").format(
                                self.algorithm().displayName()))
                    QgsApplication.taskManager().addTask(self.proxy_progress)
                    self.feedback.progressChanged.connect(
                        self.proxy_progress.setProxyProgress)
                    self.feedback_dialog = self.createProgressDialog()
                    self.feedback_dialog.show()
                    if self.in_place:
                        ok, results = execute_in_place(self.algorithm(),
                                                       parameters,
                                                       self.context,
                                                       self.feedback)
                    else:
                        ok, results = execute(self.algorithm(), parameters,
                                              self.context, self.feedback)
                    self.feedback.progressChanged.disconnect()
                    self.proxy_progress.finalize(ok)
                    on_complete(ok, results)

        except AlgorithmDialogBase.InvalidParameterValue as e:
            try:
                self.buttonBox().accepted.connect(
                    lambda e=e: e.widget.setPalette(QPalette()))
                palette = e.widget.palette()
                palette.setColor(QPalette.Base, QColor(255, 255, 0))
                e.widget.setPalette(palette)
            except:
                pass
            self.messageBar().clearWidgets()
            self.messageBar().pushMessage(
                "",
                self.tr("Wrong or missing parameter value: {0}").format(
                    e.parameter.description()),
                level=Qgis.Warning,
                duration=5)
        except AlgorithmDialogBase.InvalidOutputExtension as e:
            try:
                self.buttonBox().accepted.connect(
                    lambda e=e: e.widget.setPalette(QPalette()))
                palette = e.widget.palette()
                palette.setColor(QPalette.Base, QColor(255, 255, 0))
                e.widget.setPalette(palette)
            except:
                pass
            self.messageBar().clearWidgets()
            self.messageBar().pushMessage("",
                                          e.message,
                                          level=Qgis.Warning,
                                          duration=5)
Beispiel #15
0
    def runAlgorithm(self):
        alg_parameters = []

        feedback = self.createFeedback()

        load_layers = self.mainWidget().checkLoadLayersOnCompletion.isChecked()
        project = QgsProject.instance() if load_layers else None

        for row in range(self.mainWidget().batchRowCount()):
            parameters = self.mainWidget().parametersForRow(
                row, destinationProject=project, warnOnInvalid=True)
            alg_parameters.append(parameters)

        task = QgsScopedProxyProgressTask(
            self.tr('Batch Processing - {0}').format(
                self.algorithm().displayName()))
        multi_feedback = QgsProcessingMultiStepFeedback(
            len(alg_parameters), feedback)
        feedback.progressChanged.connect(task.setProgress)

        with OverrideCursor(Qt.WaitCursor):

            self.mainWidget().setEnabled(False)
            self.cancelButton().setEnabled(True)

            # Make sure the Log tab is visible before executing the algorithm
            try:
                self.showLog()
                self.repaint()
            except:
                pass

            start_time = time.time()

            algorithm_results = []
            for count, parameters in enumerate(alg_parameters):
                if feedback.isCanceled():
                    break
                self.setProgressText(
                    QCoreApplication.translate(
                        'BatchAlgorithmDialog',
                        '\nProcessing algorithm {0}/{1}…').format(
                            count + 1, len(alg_parameters)))
                self.setInfo(
                    self.tr('<b>Algorithm {0} starting&hellip;</b>').format(
                        self.algorithm().displayName()),
                    escapeHtml=False)
                multi_feedback.setCurrentStep(count)

                parameters = self.algorithm().preprocessParameters(parameters)

                feedback.pushInfo(self.tr('Input parameters:'))
                feedback.pushCommandInfo(pformat(parameters))
                feedback.pushInfo('')

                # important - we create a new context for each iteration
                # this avoids holding onto resources and layers from earlier iterations,
                # and allows batch processing of many more items then is possible
                # if we hold on to these layers
                context = dataobjects.createContext(feedback)

                alg_start_time = time.time()
                ret, results = execute(self.algorithm(), parameters, context,
                                       multi_feedback)
                if ret:
                    self.setInfo(QCoreApplication.translate(
                        'BatchAlgorithmDialog',
                        'Algorithm {0} correctly executed…').format(
                            self.algorithm().displayName()),
                                 escapeHtml=False)
                    feedback.pushInfo(
                        self.tr(
                            'Execution completed in {0:0.2f} seconds'.format(
                                time.time() - alg_start_time)))
                    feedback.pushInfo(self.tr('Results:'))
                    feedback.pushCommandInfo(pformat(results))
                    feedback.pushInfo('')
                    algorithm_results.append(results)
                else:
                    break

                handleAlgorithmResults(self.algorithm(), context,
                                       multi_feedback, False, parameters)

        feedback.pushInfo(
            self.tr('Batch execution completed in {0:0.2f} seconds'.format(
                time.time() - start_time)))
        task = None

        self.finish(algorithm_results)
        self.cancelButton().setEnabled(False)
Beispiel #16
0
    def accept(self):
        self.algs = []
        self.load = []
        self.canceled = False

        for row in range(self.mainWidget.tblParameters.rowCount()):
            alg = self.alg.getCopy()
            # hack - remove when getCopy is removed
            alg.setProvider(self.alg.provider())
            col = 0
            for param in alg.parameters:
                if param.hidden:
                    continue
                wrapper = self.mainWidget.wrappers[row][col]
                if not self.mainWidget.setParamValue(param, wrapper, alg):
                    self.bar.pushMessage(
                        "",
                        self.tr(
                            'Wrong or missing parameter value: {0} (row {1})').
                        format(param.description, row + 1),
                        level=QgsMessageBar.WARNING,
                        duration=5)
                    self.algs = None
                    return
                col += 1
            for out in alg.outputs:
                if out.hidden:
                    continue

                widget = self.mainWidget.tblParameters.cellWidget(row, col)
                text = widget.getValue()
                if text.strip() != '':
                    out.value = text
                    col += 1
                else:
                    self.bar.pushMessage(
                        "",
                        self.tr('Wrong or missing output value: {0} (row {1})'
                                ).format(out.description, row + 1),
                        level=QgsMessageBar.WARNING,
                        duration=5)
                    self.algs = None
                    return

            self.algs.append(alg)
            if self.alg.getVisibleOutputsCount():
                widget = self.mainWidget.tblParameters.cellWidget(row, col)
                self.load.append(widget.currentIndex() == 0)
            else:
                self.load.append(False)

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        self.mainWidget.setEnabled(False)

        self.progressBar.setMaximum(len(self.algs))
        # Make sure the Log tab is visible before executing the algorithm
        try:
            self.tabWidget.setCurrentIndex(1)
            self.repaint()
        except:
            pass

        context = dataobjects.createContext()

        for count, alg in enumerate(self.algs):
            self.setText(
                self.tr('\nProcessing algorithm {0}/{1}...').format(
                    count + 1, len(self.algs)))
            self.setInfo(
                self.tr('<b>Algorithm {0} starting...</b>').format(
                    alg.displayName()))
            if execute(alg, context, self.feedback) and not self.canceled:
                if self.load[count]:
                    handleAlgorithmResults(alg, context, self.feedback, False)
                self.setInfo(
                    self.tr('Algorithm {0} correctly executed...').format(
                        alg.displayName()))
            else:
                QApplication.restoreOverrideCursor()
                return

        self.finish()
Beispiel #17
0
    def runAlgorithm(self):
        self.feedback = self.createFeedback()
        self.context = dataobjects.createContext(self.feedback)

        checkCRS = ProcessingConfig.getSetting(ProcessingConfig.WARN_UNMATCHING_CRS)
        try:
            parameters = self.getParameterValues()

            if checkCRS and not self.algorithm().validateInputCrs(parameters, self.context):
                reply = QMessageBox.question(self, self.tr("Unmatching CRS's"),
                                             self.tr('Parameters do not all use the same CRS. This can '
                                                     'cause unexpected results.\nDo you want to '
                                                     'continue?'),
                                             QMessageBox.Yes | QMessageBox.No,
                                             QMessageBox.No)
                if reply == QMessageBox.No:
                    return
            ok, msg = self.algorithm().checkParameterValues(parameters, self.context)
            if not ok:
                QMessageBox.warning(
                    self, self.tr('Unable to execute algorithm'), msg)
                return
            self.runButton().setEnabled(False)
            self.cancelButton().setEnabled(False)
            buttons = self.mainWidget().iterateButtons
            self.iterateParam = None

            for i in range(len(list(buttons.values()))):
                button = list(buttons.values())[i]
                if button.isChecked():
                    self.iterateParam = list(buttons.keys())[i]
                    break

            self.clearProgress()
            self.setProgressText(QCoreApplication.translate('AlgorithmDialog', 'Processing algorithm…'))

            self.setInfo(
                QCoreApplication.translate('AlgorithmDialog', '<b>Algorithm \'{0}\' starting&hellip;</b>').format(self.algorithm().displayName()), escapeHtml=False)

            self.feedback.pushInfo(self.tr('Input parameters:'))
            display_params = []
            for k, v in parameters.items():
                display_params.append("'" + k + "' : " + self.algorithm().parameterDefinition(k).valueAsPythonString(v, self.context))
            self.feedback.pushCommandInfo('{ ' + ', '.join(display_params) + ' }')
            self.feedback.pushInfo('')
            start_time = time.time()

            if self.iterateParam:
                # Make sure the Log tab is visible before executing the algorithm
                try:
                    self.showLog()
                    self.repaint()
                except:
                    pass

                self.cancelButton().setEnabled(self.algorithm().flags() & QgsProcessingAlgorithm.FlagCanCancel)
                if executeIterating(self.algorithm(), parameters, self.iterateParam, self.context, self.feedback):
                    self.feedback.pushInfo(
                        self.tr('Execution completed in {0:0.2f} seconds').format(time.time() - start_time))
                    self.cancelButton().setEnabled(False)
                    self.finish(True, parameters, self.context, self.feedback)
                else:
                    self.cancelButton().setEnabled(False)
                    self.resetGui()
            else:
                command = self.algorithm().asPythonCommand(parameters, self.context)
                if command:
                    ProcessingLog.addToLog(command)
                QgsGui.instance().processingRecentAlgorithmLog().push(self.algorithm().id())
                self.cancelButton().setEnabled(self.algorithm().flags() & QgsProcessingAlgorithm.FlagCanCancel)

                def on_complete(ok, results):
                    if ok:
                        self.feedback.pushInfo(self.tr('Execution completed in {0:0.2f} seconds').format(time.time() - start_time))
                        self.feedback.pushInfo(self.tr('Results:'))
                        self.feedback.pushCommandInfo(pformat(results))
                    else:
                        self.feedback.reportError(
                            self.tr('Execution failed after {0:0.2f} seconds').format(time.time() - start_time))
                    self.feedback.pushInfo('')

                    if self.feedback_dialog is not None:
                        self.feedback_dialog.close()
                        self.feedback_dialog.deleteLater()
                        self.feedback_dialog = None

                    self.cancelButton().setEnabled(False)

                    if not self.in_place:
                        self.finish(ok, results, self.context, self.feedback)
                    elif ok:
                        self.close()

                    self.feedback = None
                    self.context = None

                if not self.in_place and not (self.algorithm().flags() & QgsProcessingAlgorithm.FlagNoThreading):
                    # Make sure the Log tab is visible before executing the algorithm
                    self.showLog()

                    task = QgsProcessingAlgRunnerTask(self.algorithm(), parameters, self.context, self.feedback)
                    if task.isCanceled():
                        on_complete(False, {})
                    else:
                        task.executed.connect(on_complete)
                        self.setCurrentTask(task)
                else:
                    self.proxy_progress = QgsProxyProgressTask(QCoreApplication.translate("AlgorithmDialog", "Executing “{}”").format(self.algorithm().displayName()))
                    QgsApplication.taskManager().addTask(self.proxy_progress)
                    self.feedback.progressChanged.connect(self.proxy_progress.setProxyProgress)
                    self.feedback_dialog = self.createProgressDialog()
                    self.feedback_dialog.show()
                    if self.in_place:
                        ok, results = execute_in_place(self.algorithm(), parameters, self.context, self.feedback)
                    else:
                        ok, results = execute(self.algorithm(), parameters, self.context, self.feedback)
                    self.feedback.progressChanged.disconnect()
                    self.proxy_progress.finalize(ok)
                    on_complete(ok, results)

        except AlgorithmDialogBase.InvalidParameterValue as e:
            try:
                self.buttonBox().accepted.connect(lambda e=e:
                                                  e.widget.setPalette(QPalette()))
                palette = e.widget.palette()
                palette.setColor(QPalette.Base, QColor(255, 255, 0))
                e.widget.setPalette(palette)
            except:
                pass
            self.messageBar().clearWidgets()
            self.messageBar().pushMessage("", self.tr("Wrong or missing parameter value: {0}").format(e.parameter.description()),
                                          level=Qgis.Warning, duration=5)
        except AlgorithmDialogBase.InvalidOutputExtension as e:
            try:
                self.buttonBox().accepted.connect(lambda e=e:
                                                  e.widget.setPalette(QPalette()))
                palette = e.widget.palette()
                palette.setColor(QPalette.Base, QColor(255, 255, 0))
                e.widget.setPalette(palette)
            except:
                pass
            self.messageBar().clearWidgets()
            self.messageBar().pushMessage("", e.message,
                                          level=Qgis.Warning, duration=5)
Beispiel #18
0
    def accept(self):
        self.settings.setValue("/Processing/dialogBase", self.saveGeometry())

        checkCRS = ProcessingConfig.getSetting(
            ProcessingConfig.WARN_UNMATCHING_CRS)
        try:
            self.setParamValues()
            if checkCRS and not self.alg.checkInputCRS():
                reply = QMessageBox.question(
                    self, self.tr("Unmatching CRS's"),
                    self.tr('Layers do not all use the same CRS. This can '
                            'cause unexpected results.\nDo you want to '
                            'continue?'), QMessageBox.Yes | QMessageBox.No,
                    QMessageBox.No)
                if reply == QMessageBox.No:
                    return
            checkExtentCRS = ProcessingConfig.getSetting(
                ProcessingConfig.WARN_UNMATCHING_EXTENT_CRS)
            if checkExtentCRS and self.checkExtentCRS():
                reply = QMessageBox.question(
                    self, self.tr("Extent CRS"),
                    self.
                    tr('Extent parameters must use the same CRS as the input layers.\n'
                       'Your input layers do not have the same extent as the project, '
                       'so the extent might be in a wrong CRS if you have selected it from the canvas.\n'
                       'Do you want to continue?'),
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                if reply == QMessageBox.No:
                    return
            msg = self.alg._checkParameterValuesBeforeExecuting()
            if msg:
                QMessageBox.warning(self,
                                    self.tr('Unable to execute algorithm'),
                                    msg)
                return
            self.btnRun.setEnabled(False)
            self.btnClose.setEnabled(False)
            buttons = self.mainWidget.iterateButtons
            self.iterateParam = None

            for i in range(len(list(buttons.values()))):
                button = list(buttons.values())[i]
                if button.isChecked():
                    self.iterateParam = list(buttons.keys())[i]
                    break

            self.progressBar.setMaximum(0)
            self.lblProgress.setText(self.tr('Processing algorithm...'))
            # Make sure the Log tab is visible before executing the algorithm
            try:
                self.tabWidget.setCurrentIndex(1)
                self.repaint()
            except:
                pass

            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

            self.setInfo(
                self.tr('<b>Algorithm {0} starting...</b>').format(
                    self.alg.name))

            if self.iterateParam:
                if executeIterating(self.alg, self.iterateParam,
                                    self.feedback):
                    self.finish()
                else:
                    QApplication.restoreOverrideCursor()
                    self.resetGUI()
            else:
                command = self.alg.getAsCommand()
                if command:
                    ProcessingLog.addToLog(ProcessingLog.LOG_ALGORITHM,
                                           command)
                if execute(self.alg, self.feedback):
                    self.finish()
                else:
                    QApplication.restoreOverrideCursor()
                    self.resetGUI()
        except AlgorithmDialogBase.InvalidParameterValue as e:
            try:
                self.buttonBox.accepted.connect(
                    lambda e=e: e.widget.setPalette(QPalette()))
                palette = e.widget.palette()
                palette.setColor(QPalette.Base, QColor(255, 255, 0))
                e.widget.setPalette(palette)
            except:
                pass
            self.bar.clearWidgets()
            self.bar.pushMessage(
                "",
                self.tr("Wrong or missing parameter value: {0}").format(
                    e.parameter.description),
                level=QgsMessageBar.WARNING,
                duration=5)
Beispiel #19
0
    def runAlgorithm(algOrName, parameters, onFinish=None, feedback=None, context=None):
        if isinstance(algOrName, QgsProcessingAlgorithm):
            alg = algOrName
        else:
            alg = QgsApplication.processingRegistry().createAlgorithmById(algOrName)

        if feedback is None:
            feedback = MessageBarProgress(alg.displayName() if alg else Processing.tr('Processing'))

        if alg is None:
            # fix_print_with_import
            print('Error: Algorithm not found\n')
            msg = Processing.tr('Error: Algorithm {0} not found\n').format(algOrName)
            feedback.reportError(msg)
            raise QgsProcessingException(msg)

        # check for any mandatory parameters which were not specified
        for param in alg.parameterDefinitions():
            if param.name() not in parameters:
                if not param.flags() & QgsProcessingParameterDefinition.FlagOptional:
                    # fix_print_with_import
                    msg = Processing.tr('Error: Missing parameter value for parameter {0}.').format(param.name())
                    print('Error: Missing parameter value for parameter %s.' % param.name())
                    feedback.reportError(msg)
                    raise QgsProcessingException(msg)

        if context is None:
            context = dataobjects.createContext(feedback)

        ok, msg = alg.checkParameterValues(parameters, context)
        if not ok:
            # fix_print_with_import
            print('Unable to execute algorithm\n' + str(msg))
            msg = Processing.tr('Unable to execute algorithm\n{0}').format(msg)
            feedback.reportError(msg)
            raise QgsProcessingException(msg)

        if not alg.validateInputCrs(parameters, context):
            print('Warning: Not all input layers use the same CRS.\n' +
                  'This can cause unexpected results.')
            feedback.pushInfo(
                Processing.tr('Warning: Not all input layers use the same CRS.\nThis can cause unexpected results.'))

        ret, results = execute(alg, parameters, context, feedback)
        if ret:
            feedback.pushInfo(
                Processing.tr('Results: {}').format(results))

            if onFinish is not None:
                onFinish(alg, context, feedback)
            else:
                # auto convert layer references in results to map layers
                for out in alg.outputDefinitions():
                    if isinstance(out, (QgsProcessingOutputVectorLayer, QgsProcessingOutputRasterLayer, QgsProcessingOutputMapLayer)):
                        result = results[out.name()]
                        if not isinstance(result, QgsMapLayer):
                            layer = context.takeResultLayer(result) # transfer layer ownership out of context
                            if layer:
                                results[out.name()] = layer # replace layer string ref with actual layer (+ownership)
        else:
            msg = Processing.tr("There were errors executing the algorithm.")
            feedback.reportError(msg)
            raise QgsProcessingException(msg)

        if isinstance(feedback, MessageBarProgress):
            feedback.close()
        return results
Beispiel #20
0
    def accept(self):
        alg_parameters = []
        load = []

        feedback = self.createFeedback()
        context = dataobjects.createContext(feedback)

        for row in range(self.mainWidget.tblParameters.rowCount()):
            col = 0
            parameters = {}
            for param in self.alg.parameterDefinitions():
                if param.flags() & QgsProcessingParameterDefinition.FlagHidden or param.isDestination():
                    continue
                wrapper = self.mainWidget.wrappers[row][col]
                parameters[param.name()] = wrapper.value()
                if not param.checkValueIsAcceptable(wrapper.value(), context):
                    self.bar.pushMessage("", self.tr('Wrong or missing parameter value: {0} (row {1})').format(
                                         param.description(), row + 1),
                                         level=QgsMessageBar.WARNING, duration=5)
                    return
                col += 1
            count_visible_outputs = 0
            for out in self.alg.destinationParameterDefinitions():
                if out.flags() & QgsProcessingParameterDefinition.FlagHidden:
                    continue

                count_visible_outputs += 1
                widget = self.mainWidget.tblParameters.cellWidget(row, col)
                text = widget.getValue()
                if param.checkValueIsAcceptable(text, context):
                    if isinstance(out, (QgsProcessingParameterRasterDestination,
                                        QgsProcessingParameterFeatureSink)):
                        # load rasters and sinks on completion
                        parameters[out.name()] = QgsProcessingOutputLayerDefinition(text, context.project())
                    else:
                        parameters[out.name()] = text
                    col += 1
                else:
                    self.bar.pushMessage("", self.tr('Wrong or missing output value: {0} (row {1})').format(
                                         out.description(), row + 1),
                                         level=QgsMessageBar.WARNING, duration=5)
                    return

            alg_parameters.append(parameters)

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        self.mainWidget.setEnabled(False)
        self.buttonCancel.setEnabled(True)

        # Make sure the Log tab is visible before executing the algorithm
        try:
            self.tabWidget.setCurrentIndex(1)
            self.repaint()
        except:
            pass

        start_time = time.time()

        algorithm_results = []
        for count, parameters in enumerate(alg_parameters):
            if feedback.isCanceled():
                break
            self.setText(self.tr('\nProcessing algorithm {0}/{1}...').format(count + 1, len(alg_parameters)))
            self.setInfo(self.tr('<b>Algorithm {0} starting...</b>').format(self.alg.displayName()), escape_html=False)

            feedback.pushInfo(self.tr('Input parameters:'))
            feedback.pushCommandInfo(pformat(parameters))
            feedback.pushInfo('')

            alg_start_time = time.time()
            ret, results = execute(self.alg, parameters, context, feedback)
            if ret:
                self.setInfo(self.tr('Algorithm {0} correctly executed...').format(self.alg.displayName()), escape_html=False)
                feedback.setProgress(100)
                feedback.pushInfo(
                    self.tr('Execution completed in {0:0.2f} seconds'.format(time.time() - alg_start_time)))
                feedback.pushInfo(self.tr('Results:'))
                feedback.pushCommandInfo(pformat(results))
                feedback.pushInfo('')
                algorithm_results.append(results)
            else:
                break

        feedback.pushInfo(self.tr('Batch execution completed in {0:0.2f} seconds'.format(time.time() - start_time)))

        handleAlgorithmResults(self.alg, context, feedback, False)

        self.finish(algorithm_results)
        self.buttonCancel.setEnabled(False)
Beispiel #21
0
    def accept(self):
        alg_parameters = []

        feedback = self.createFeedback()

        load_layers = self.mainWidget().checkLoadLayersOnCompletion.isChecked()
        project = QgsProject.instance() if load_layers else None

        for row in range(self.mainWidget().tblParameters.rowCount()):
            col = 0
            parameters = {}
            for param in self.algorithm().parameterDefinitions():
                if param.flags(
                ) & QgsProcessingParameterDefinition.FlagHidden or param.isDestination(
                ):
                    continue
                wrapper = self.mainWidget().wrappers[row][col]
                parameters[param.name()] = wrapper.value()
                if not param.checkValueIsAcceptable(wrapper.value()):
                    self.messageBar().pushMessage(
                        "",
                        self.tr(
                            'Wrong or missing parameter value: {0} (row {1})').
                        format(param.description(), row + 1),
                        level=Qgis.Warning,
                        duration=5)
                    return
                col += 1
            count_visible_outputs = 0
            for out in self.algorithm().destinationParameterDefinitions():
                if out.flags() & QgsProcessingParameterDefinition.FlagHidden:
                    continue

                count_visible_outputs += 1
                widget = self.mainWidget().tblParameters.cellWidget(row, col)
                text = widget.getValue()
                if out.checkValueIsAcceptable(text):
                    if isinstance(out,
                                  (QgsProcessingParameterRasterDestination,
                                   QgsProcessingParameterFeatureSink)):
                        # load rasters and sinks on completion
                        parameters[
                            out.name()] = QgsProcessingOutputLayerDefinition(
                                text, project)
                    else:
                        parameters[out.name()] = text
                    col += 1
                else:
                    self.messageBar().pushMessage(
                        "",
                        self.tr('Wrong or missing output value: {0} (row {1})'
                                ).format(out.description(), row + 1),
                        level=Qgis.Warning,
                        duration=5)
                    return

            alg_parameters.append(parameters)

        with OverrideCursor(Qt.WaitCursor):

            self.mainWidget().setEnabled(False)
            self.cancelButton().setEnabled(True)

            # Make sure the Log tab is visible before executing the algorithm
            try:
                self.showLog()
                self.repaint()
            except:
                pass

            start_time = time.time()

            algorithm_results = []
            for count, parameters in enumerate(alg_parameters):
                if feedback.isCanceled():
                    break
                self.setProgressText(
                    QCoreApplication.translate(
                        'BatchAlgorithmDialog',
                        '\nProcessing algorithm {0}/{1}…').format(
                            count + 1, len(alg_parameters)))
                self.setInfo(
                    self.tr('<b>Algorithm {0} starting&hellip;</b>').format(
                        self.algorithm().displayName()),
                    escapeHtml=False)

                parameters = self.algorithm().preprocessParameters(parameters)

                feedback.pushInfo(self.tr('Input parameters:'))
                feedback.pushCommandInfo(pformat(parameters))
                feedback.pushInfo('')

                # important - we create a new context for each iteration
                # this avoids holding onto resources and layers from earlier iterations,
                # and allows batch processing of many more items then is possible
                # if we hold on to these layers
                context = dataobjects.createContext(feedback)

                alg_start_time = time.time()
                ret, results = execute(self.algorithm(), parameters, context,
                                       feedback)
                if ret:
                    self.setInfo(QCoreApplication.translate(
                        'BatchAlgorithmDialog',
                        'Algorithm {0} correctly executed…').format(
                            self.algorithm().displayName()),
                                 escapeHtml=False)
                    feedback.setProgress(100)
                    feedback.pushInfo(
                        self.tr(
                            'Execution completed in {0:0.2f} seconds'.format(
                                time.time() - alg_start_time)))
                    feedback.pushInfo(self.tr('Results:'))
                    feedback.pushCommandInfo(pformat(results))
                    feedback.pushInfo('')
                    algorithm_results.append(results)
                else:
                    break

                handleAlgorithmResults(self.algorithm(), context, feedback,
                                       False)

        feedback.pushInfo(
            self.tr('Batch execution completed in {0:0.2f} seconds'.format(
                time.time() - start_time)))

        self.finish(algorithm_results)
        self.cancelButton().setEnabled(False)
Beispiel #22
0
    def runAlgorithm(algOrName, onFinish, *args, **kwargs):
        if isinstance(algOrName, GeoAlgorithm):
            alg = algOrName
        else:
            alg = QgsApplication.processingRegistry().algorithmById(algOrName)
        if alg is None:
            # fix_print_with_import
            print('Error: Algorithm not found\n')
            QgsMessageLog.logMessage(
                Processing.tr('Error: Algorithm {0} not found\n').format(
                    algOrName), Processing.tr("Processing"))
            return

        parameters = {}
        if len(args) == 1 and isinstance(args[0], dict):
            # Set params by name and try to run the alg even if not all parameter values are provided,
            # by using the default values instead.
            for (name, value) in list(args[0].items()):
                param = alg.parameterDefinition(name)
                if param:
                    parameters[param.name()] = value
                    continue
                # fix_print_with_import
                print('Error: Wrong parameter value %s for parameter %s.' %
                      (value, name))
                QgsMessageLog.logMessage(
                    Processing.tr(
                        'Error: Wrong parameter value {0} for parameter {1}.').
                    format(value, name), Processing.tr("Processing"))
                QgsMessageLog.logMessage(
                    Processing.
                    tr('Error in {0}. Wrong parameter value {1} for parameter {2}.'
                       ).format(alg.name(), value, name),
                    Processing.tr("Processing"), QgsMessageLog.CRITICAL)
                return
            # check for any manadatory parameters which were not specified
            for param in alg.parameterDefinitions():
                if param.name() not in parameters:
                    if not param.flags(
                    ) & QgsProcessingParameterDefinition.FlagOptional:
                        # fix_print_with_import
                        print(
                            'Error: Missing parameter value for parameter %s.'
                            % param.name())
                        QgsMessageLog.logMessage(
                            Processing.
                            tr('Error: Missing parameter value for parameter {0}.'
                               ).format(param.name()),
                            Processing.tr("Processing"))
                        return
        else:
            if len(args) != alg.countVisibleParameters():
                # fix_print_with_import
                print('Error: Wrong number of parameters')
                QgsMessageLog.logMessage(
                    Processing.tr('Error: Wrong number of parameters'),
                    Processing.tr("Processing"))
                processing.algorithmHelp(algOrName)
                return
            i = 0
            for param in alg.parameterDefinitions():
                if not param.flags(
                ) & QgsProcessingParameterDefinition.FlagHidden:
                    if not True:  # TODO param.setValue(args[i]):
                        # fix_print_with_import
                        print('Error: Wrong parameter value: ' + str(args[i]))
                        QgsMessageLog.logMessage(
                            Processing.tr('Error: Wrong parameter value: ') +
                            str(args[i]), Processing.tr("Processing"))
                        return
                    else:
                        parameters[param.name()] = args[i]
                    i = i + 1

            for output in alg.outputs:
                if not output.flags(
                ) & QgsProcessingParameterDefinition.FlagHidden:
                    if not output.setValue(args[i]):
                        # fix_print_with_import
                        print('Error: Wrong output value: ' + str(args[i]))
                        QgsMessageLog.logMessage(
                            Processing.tr('Error: Wrong output value: ') +
                            str(args[i]), Processing.tr("Processing"))
                        return
                    i = i + 1

        context = None
        if kwargs is not None and 'context' in list(kwargs.keys()):
            context = kwargs["context"]
        else:
            context = dataobjects.createContext()

        ok, msg = alg.checkParameterValues(parameters, context)
        if not ok:
            # fix_print_with_import
            print('Unable to execute algorithm\n' + str(msg))
            QgsMessageLog.logMessage(
                Processing.tr('Unable to execute algorithm\n{0}').format(msg),
                Processing.tr("Processing"))
            return

        if not alg.validateInputCrs(parameters, context):
            print('Warning: Not all input layers use the same CRS.\n' +
                  'This can cause unexpected results.')
            QgsMessageLog.logMessage(
                Processing.
                tr('Warning: Not all input layers use the same CRS.\nThis can cause unexpected results.'
                   ), Processing.tr("Processing"))

        # Don't set the wait cursor twice, because then when you
        # restore it, it will still be a wait cursor.
        overrideCursor = False
        if iface is not None:
            cursor = QApplication.overrideCursor()
            if cursor is None or cursor == 0:
                QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
                overrideCursor = True
            elif cursor.shape() != Qt.WaitCursor:
                QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
                overrideCursor = True

        feedback = None
        if kwargs is not None and "feedback" in list(kwargs.keys()):
            feedback = kwargs["feedback"]
        elif iface is not None:
            feedback = MessageBarProgress(alg.displayName())

        ret, results = execute(alg, parameters, context, feedback)
        if ret:
            if onFinish is not None:
                onFinish(alg, context, feedback)
        else:
            QgsMessageLog.logMessage(
                Processing.tr("There were errors executing the algorithm."),
                Processing.tr("Processing"))

        if overrideCursor:
            QApplication.restoreOverrideCursor()
        if isinstance(feedback, MessageBarProgress):
            feedback.close()
        return results
Beispiel #23
0
    def executeAlgorithm(self):
        config = {}
        if self.in_place_mode:
            config['IN_PLACE'] = True
        alg = self.algorithmTree.selectedAlgorithm().create(
            config) if self.algorithmTree.selectedAlgorithm(
            ) is not None else None
        if alg is not None:
            ok, message = alg.canExecute()
            if not ok:
                dlg = MessageDialog()
                dlg.setTitle(self.tr('Error executing algorithm'))
                dlg.setMessage(
                    self.tr('<h3>This algorithm cannot '
                            'be run :-( </h3>\n{0}').format(message))
                dlg.exec_()
                return

            if self.in_place_mode and not [
                    d for d in alg.parameterDefinitions()
                    if d.name() not in ('INPUT', 'OUTPUT')
            ]:
                parameters = {}
                feedback = MessageBarProgress(algname=alg.displayName())
                ok, results = execute_in_place(alg,
                                               parameters,
                                               feedback=feedback)
                if ok:
                    iface.messageBar().pushSuccess(
                        '',
                        self.tr(
                            '{algname} completed. %n feature(s) processed.',
                            n=results['__count']).format(
                                algname=alg.displayName()))
                feedback.close()
                # MessageBarProgress handles errors
                return

            if alg.countVisibleParameters() > 0:
                dlg = alg.createCustomParametersWidget(self)

                if not dlg:
                    dlg = AlgorithmDialog(alg, self.in_place_mode,
                                          iface.mainWindow())
                canvas = iface.mapCanvas()
                prevMapTool = canvas.mapTool()
                dlg.show()
                dlg.exec_()
                if canvas.mapTool() != prevMapTool:
                    try:
                        canvas.mapTool().reset()
                    except:
                        pass
                    canvas.setMapTool(prevMapTool)
            else:
                feedback = MessageBarProgress(algname=alg.displayName())
                context = dataobjects.createContext(feedback)
                parameters = {}
                ret, results = execute(alg, parameters, context, feedback)
                handleAlgorithmResults(alg, context, feedback)
                feedback.close()
Beispiel #24
0
    def runAlgorithm(algOrName, onFinish, *args, **kwargs):
        if isinstance(algOrName, GeoAlgorithm):
            alg = algOrName
        else:
            alg = QgsApplication.processingRegistry().algorithmById(algOrName)
        if alg is None:
            # fix_print_with_import
            print('Error: Algorithm not found\n')
            QgsMessageLog.logMessage(
                Processing.tr('Error: Algorithm {0} not found\n').format(
                    algOrName), Processing.tr("Processing"))
            return
        # hack - remove when getCopy is removed
        provider = alg.provider()
        alg = alg.getCopy()
        #hack pt2
        alg.setProvider(provider)

        if len(args) == 1 and isinstance(args[0], dict):
            # Set params by name and try to run the alg even if not all parameter values are provided,
            # by using the default values instead.
            setParams = []
            for (name, value) in list(args[0].items()):
                param = alg.getParameterFromName(name)
                if param and param.setValue(value):
                    setParams.append(name)
                    continue
                output = alg.getOutputFromName(name)
                if output and output.setValue(value):
                    continue
                # fix_print_with_import
                print('Error: Wrong parameter value %s for parameter %s.' %
                      (value, name))
                QgsMessageLog.logMessage(
                    Processing.tr(
                        'Error: Wrong parameter value {0} for parameter {1}.').
                    format(value, name), Processing.tr("Processing"))
                QgsMessageLog.logMessage(
                    Processing.
                    tr('Error in {0}. Wrong parameter value {1} for parameter {2}.'
                       ).format(alg.name(), value, name),
                    Processing.tr("Processing"), QgsMessageLog.CRITICAL)
                return
            # fill any missing parameters with default values if allowed
            for param in alg.parameters:
                if param.name not in setParams:
                    if not param.setDefaultValue():
                        # fix_print_with_import
                        print(
                            'Error: Missing parameter value for parameter %s.'
                            % param.name)
                        QgsMessageLog.logMessage(
                            Processing.
                            tr('Error: Missing parameter value for parameter {0}.'
                               ).format(param.name),
                            Processing.tr("Processing"))
                        return
        else:
            if len(args) != alg.getVisibleParametersCount(
            ) + alg.getVisibleOutputsCount():
                # fix_print_with_import
                print('Error: Wrong number of parameters')
                QgsMessageLog.logMessage(
                    Processing.tr('Error: Wrong number of parameters'),
                    Processing.tr("Processing"))
                processing.algorithmHelp(algOrName)
                return
            i = 0
            for param in alg.parameters:
                if not param.hidden:
                    if not param.setValue(args[i]):
                        # fix_print_with_import
                        print('Error: Wrong parameter value: ' + str(args[i]))
                        QgsMessageLog.logMessage(
                            Processing.tr('Error: Wrong parameter value: ') +
                            str(args[i]), Processing.tr("Processing"))
                        return
                    i = i + 1

            for output in alg.outputs:
                if not output.hidden:
                    if not output.setValue(args[i]):
                        # fix_print_with_import
                        print('Error: Wrong output value: ' + str(args[i]))
                        QgsMessageLog.logMessage(
                            Processing.tr('Error: Wrong output value: ') +
                            str(args[i]), Processing.tr("Processing"))
                        return
                    i = i + 1

        context = None
        if kwargs is not None and 'context' in list(kwargs.keys()):
            context = kwargs["context"]
        else:
            context = dataobjects.createContext()

        msg = alg._checkParameterValuesBeforeExecuting(context)
        if msg:
            # fix_print_with_import
            print('Unable to execute algorithm\n' + str(msg))
            QgsMessageLog.logMessage(
                Processing.tr('Unable to execute algorithm\n{0}').format(msg),
                Processing.tr("Processing"))
            return

        if not alg.checkInputCRS(context):
            print('Warning: Not all input layers use the same CRS.\n' +
                  'This can cause unexpected results.')
            QgsMessageLog.logMessage(
                Processing.
                tr('Warning: Not all input layers use the same CRS.\nThis can cause unexpected results.'
                   ), Processing.tr("Processing"))

        # Don't set the wait cursor twice, because then when you
        # restore it, it will still be a wait cursor.
        overrideCursor = False
        if iface is not None:
            cursor = QApplication.overrideCursor()
            if cursor is None or cursor == 0:
                QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
                overrideCursor = True
            elif cursor.shape() != Qt.WaitCursor:
                QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
                overrideCursor = True

        feedback = None
        if kwargs is not None and "feedback" in list(kwargs.keys()):
            feedback = kwargs["feedback"]
        elif iface is not None:
            feedback = MessageBarProgress(alg.displayName())

        ret = execute(alg, context, feedback)
        if ret:
            if onFinish is not None:
                onFinish(alg, context, feedback)
        else:
            QgsMessageLog.logMessage(
                Processing.tr("There were errors executing the algorithm."),
                Processing.tr("Processing"))

        if overrideCursor:
            QApplication.restoreOverrideCursor()
        if isinstance(feedback, MessageBarProgress):
            feedback.close()
        return alg
Beispiel #25
0
    def accept(self):
        alg_parameters = []
        load = []

        feedback = self.createFeedback()
        context = dataobjects.createContext(feedback)

        for row in range(self.mainWidget.tblParameters.rowCount()):
            col = 0
            parameters = {}
            for param in self.alg.parameterDefinitions():
                if param.flags() & QgsProcessingParameterDefinition.FlagHidden or param.isDestination():
                    continue
                wrapper = self.mainWidget.wrappers[row][col]
                parameters[param.name()] = wrapper.value()
                if not param.checkValueIsAcceptable(wrapper.value(), context):
                    self.bar.pushMessage("", self.tr('Wrong or missing parameter value: {0} (row {1})').format(
                                         param.description(), row + 1),
                                         level=QgsMessageBar.WARNING, duration=5)
                    return
                col += 1
            count_visible_outputs = 0
            for out in self.alg.destinationParameterDefinitions():
                if out.flags() & QgsProcessingParameterDefinition.FlagHidden:
                    continue

                count_visible_outputs += 1
                widget = self.mainWidget.tblParameters.cellWidget(row, col)
                text = widget.getValue()
                if param.checkValueIsAcceptable(text, context):
                    if isinstance(out, (QgsProcessingParameterRasterDestination,
                                        QgsProcessingParameterFeatureSink)):
                        # load rasters and sinks on completion
                        parameters[out.name()] = QgsProcessingOutputLayerDefinition(text, context.project())
                    else:
                        parameters[out.name()] = text
                    col += 1
                else:
                    self.bar.pushMessage("", self.tr('Wrong or missing output value: {0} (row {1})').format(
                                         out.description(), row + 1),
                                         level=QgsMessageBar.WARNING, duration=5)
                    return

            alg_parameters.append(parameters)

        QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
        self.mainWidget.setEnabled(False)
        self.buttonCancel.setEnabled(True)

        # Make sure the Log tab is visible before executing the algorithm
        try:
            self.tabWidget.setCurrentIndex(1)
            self.repaint()
        except:
            pass

        start_time = time.time()

        algorithm_results = []
        for count, parameters in enumerate(alg_parameters):
            if feedback.isCanceled():
                break
            self.setText(self.tr('\nProcessing algorithm {0}/{1}...').format(count + 1, len(alg_parameters)))
            self.setInfo(self.tr('<b>Algorithm {0} starting...</b>').format(self.alg.displayName()), escape_html=False)

            feedback.pushInfo(self.tr('Input parameters:'))
            feedback.pushCommandInfo(pformat(parameters))
            feedback.pushInfo('')

            alg_start_time = time.time()
            ret, results = execute(self.alg, parameters, context, feedback)
            if ret:
                self.setInfo(self.tr('Algorithm {0} correctly executed...').format(self.alg.displayName()), escape_html=False)
                feedback.setProgress(100)
                feedback.pushInfo(
                    self.tr('Execution completed in {0:0.2f} seconds'.format(time.time() - alg_start_time)))
                feedback.pushInfo(self.tr('Results:'))
                feedback.pushCommandInfo(pformat(results))
                feedback.pushInfo('')
                algorithm_results.append(results)
            else:
                break

        feedback.pushInfo(self.tr('Batch execution completed in {0:0.2f} seconds'.format(time.time() - start_time)))

        handleAlgorithmResults(self.alg, context, feedback, False)

        self.finish(algorithm_results)
        self.buttonCancel.setEnabled(False)
Beispiel #26
0
    def runAlgorithm(self):
        self.feedback = self.createFeedback()
        self.context = dataobjects.createContext(self.feedback)
        self.context.setLogLevel(self.logLevel())

        checkCRS = ProcessingConfig.getSetting(
            ProcessingConfig.WARN_UNMATCHING_CRS)
        try:
            # messy as all heck, but we don't want to call the dialog's implementation of
            # createProcessingParameters as we want to catch the exceptions raised by the
            # parameter panel instead...
            parameters = {} if self.mainWidget() is None else self.mainWidget(
            ).createProcessingParameters()

            if checkCRS and not self.algorithm().validateInputCrs(
                    parameters, self.context):
                reply = QMessageBox.question(
                    self, self.tr("Unmatching CRS's"),
                    self.tr('Parameters do not all use the same CRS. This can '
                            'cause unexpected results.\nDo you want to '
                            'continue?'), QMessageBox.Yes | QMessageBox.No,
                    QMessageBox.No)
                if reply == QMessageBox.No:
                    return
            ok, msg = self.algorithm().checkParameterValues(
                parameters, self.context)
            if not ok:
                QMessageBox.warning(self,
                                    self.tr('Unable to execute algorithm'),
                                    msg)
                return

            self.blockControlsWhileRunning()
            self.setExecutedAnyResult(True)
            self.cancelButton().setEnabled(False)

            self.iterateParam = None

            for param in self.algorithm().parameterDefinitions():
                if isinstance(
                        parameters.get(param.name(), None),
                        QgsProcessingFeatureSourceDefinition
                ) and parameters[param.name(
                )].flags & QgsProcessingFeatureSourceDefinition.FlagCreateIndividualOutputPerInputFeature:
                    self.iterateParam = param.name()
                    break

            self.clearProgress()
            self.feedback.pushVersionInfo(self.algorithm().provider())
            if self.algorithm().provider().warningMessage():
                self.feedback.reportError(
                    self.algorithm().provider().warningMessage())

            self.feedback.pushInfo(
                QCoreApplication.translate('AlgorithmDialog',
                                           'Algorithm started at: {}').format(
                                               datetime.datetime.now().replace(
                                                   microsecond=0).isoformat()))

            self.setInfo(QCoreApplication.translate(
                'AlgorithmDialog',
                '<b>Algorithm \'{0}\' starting&hellip;</b>').format(
                    self.algorithm().displayName()),
                         escapeHtml=False)

            self.feedback.pushInfo(self.tr('Input parameters:'))
            display_params = []
            for k, v in parameters.items():
                display_params.append("'" + k + "' : " + self.algorithm(
                ).parameterDefinition(k).valueAsPythonString(v, self.context))
            self.feedback.pushCommandInfo('{ ' + ', '.join(display_params) +
                                          ' }')
            self.feedback.pushInfo('')
            start_time = time.time()

            def elapsed_time(start_time, result):
                delta_t = time.time() - start_time
                hours = int(delta_t / 3600)
                minutes = int((delta_t % 3600) / 60)
                seconds = delta_t - hours * 3600 - minutes * 60

                str_hours = [self.tr("hour"), self.tr("hours")][hours > 1]
                str_minutes = [self.tr("minute"),
                               self.tr("minutes")][minutes > 1]
                str_seconds = [self.tr("second"),
                               self.tr("seconds")][seconds != 1]

                if hours > 0:
                    elapsed = '{0} {1:0.2f} {2} ({3} {4} {5} {6} {7:0.0f} {2})'.format(
                        result, delta_t, str_seconds, hours, str_hours,
                        minutes, str_minutes, seconds)
                elif minutes > 0:
                    elapsed = '{0} {1:0.2f} {2} ({3} {4} {5:0.0f} {2})'.format(
                        result, delta_t, str_seconds, minutes, str_minutes,
                        seconds)
                else:
                    elapsed = '{0} {1:0.2f} {2}'.format(
                        result, delta_t, str_seconds)

                return elapsed

            if self.iterateParam:
                # Make sure the Log tab is visible before executing the algorithm
                try:
                    self.showLog()
                    self.repaint()
                except:
                    pass

                self.cancelButton().setEnabled(
                    self.algorithm().flags()
                    & QgsProcessingAlgorithm.FlagCanCancel)
                if executeIterating(self.algorithm(), parameters,
                                    self.iterateParam, self.context,
                                    self.feedback):
                    self.feedback.pushInfo(
                        self.tr(
                            elapsed_time(start_time,
                                         'Execution completed in')))
                    self.cancelButton().setEnabled(False)
                    self.finish(True, parameters, self.context, self.feedback)
                else:
                    self.cancelButton().setEnabled(False)
                    self.resetGui()
            else:
                self.history_details = {
                    'python_command':
                    self.algorithm().asPythonCommand(parameters, self.context),
                    'algorithm_id':
                    self.algorithm().id(),
                    'parameters':
                    self.algorithm().asMap(parameters, self.context)
                }
                process_command, command_ok = self.algorithm(
                ).asQgisProcessCommand(parameters, self.context)
                if command_ok:
                    self.history_details['process_command'] = process_command
                self.history_log_id, _ = QgsGui.historyProviderRegistry(
                ).addEntry('processing', self.history_details)

                QgsGui.instance().processingRecentAlgorithmLog().push(
                    self.algorithm().id())
                self.cancelButton().setEnabled(
                    self.algorithm().flags()
                    & QgsProcessingAlgorithm.FlagCanCancel)

                def on_complete(ok, results):
                    if ok:
                        self.feedback.pushInfo(
                            self.tr(
                                elapsed_time(start_time,
                                             'Execution completed in')))
                        self.feedback.pushInfo(self.tr('Results:'))
                        r = {
                            k: v
                            for k, v in results.items()
                            if k not in ('CHILD_RESULTS', 'CHILD_INPUTS')
                        }
                        self.feedback.pushCommandInfo(pformat(r))
                    else:
                        self.feedback.reportError(
                            self.tr(
                                elapsed_time(start_time,
                                             'Execution failed after')))
                    self.feedback.pushInfo('')

                    if self.history_log_id is not None:
                        # can't deepcopy this!
                        self.history_details['results'] = {
                            k: v
                            for k, v in results.items() if k != 'CHILD_INPUTS'
                        }

                        QgsGui.historyProviderRegistry().updateEntry(
                            self.history_log_id, self.history_details)

                    if self.feedback_dialog is not None:
                        self.feedback_dialog.close()
                        self.feedback_dialog.deleteLater()
                        self.feedback_dialog = None

                    self.cancelButton().setEnabled(False)

                    self.finish(ok,
                                results,
                                self.context,
                                self.feedback,
                                in_place=self.in_place)

                    self.feedback = None
                    self.context = None

                if not self.in_place and not (
                        self.algorithm().flags()
                        & QgsProcessingAlgorithm.FlagNoThreading):
                    # Make sure the Log tab is visible before executing the algorithm
                    self.showLog()

                    task = QgsProcessingAlgRunnerTask(self.algorithm(),
                                                      parameters, self.context,
                                                      self.feedback)
                    if task.isCanceled():
                        on_complete(False, {})
                    else:
                        task.executed.connect(on_complete)
                        self.setCurrentTask(task)
                else:
                    self.proxy_progress = QgsProxyProgressTask(
                        QCoreApplication.translate(
                            "AlgorithmDialog", "Executing “{}”").format(
                                self.algorithm().displayName()))
                    QgsApplication.taskManager().addTask(self.proxy_progress)
                    self.feedback.progressChanged.connect(
                        self.proxy_progress.setProxyProgress)
                    self.feedback_dialog = self.createProgressDialog()
                    self.feedback_dialog.show()
                    if self.in_place:
                        ok, results = execute_in_place(self.algorithm(),
                                                       parameters,
                                                       self.context,
                                                       self.feedback)
                    else:
                        ok, results = execute(self.algorithm(), parameters,
                                              self.context, self.feedback)
                    self.feedback.progressChanged.disconnect()
                    self.proxy_progress.finalize(ok)
                    on_complete(ok, results)

        except AlgorithmDialogBase.InvalidParameterValue as e:
            self.flag_invalid_parameter_value(e.parameter.description(),
                                              e.widget)
        except AlgorithmDialogBase.InvalidOutputExtension as e:
            self.flag_invalid_output_extension(e.message, e.widget)
Beispiel #27
0
    def runAlgorithm(algOrName, onFinish, *args, **kwargs):
        if isinstance(algOrName, GeoAlgorithm):
            alg = algOrName
        else:
            alg = QgsApplication.processingRegistry().algorithmById(algOrName)
        if alg is None:
            # fix_print_with_import
            print('Error: Algorithm not found\n')
            QgsMessageLog.logMessage(Processing.tr('Error: Algorithm {0} not found\n').format(algOrName),
                                     Processing.tr("Processing"))
            return
        alg = alg.getCopy()

        if len(args) == 1 and isinstance(args[0], dict):
            # Set params by name and try to run the alg even if not all parameter values are provided,
            # by using the default values instead.
            setParams = []
            for (name, value) in list(args[0].items()):
                param = alg.getParameterFromName(name)
                if param and param.setValue(value):
                    setParams.append(name)
                    continue
                output = alg.getOutputFromName(name)
                if output and output.setValue(value):
                    continue
                # fix_print_with_import
                print('Error: Wrong parameter value %s for parameter %s.' % (value, name))
                QgsMessageLog.logMessage(
                    Processing.tr('Error: Wrong parameter value {0} for parameter {1}.').format(value, name),
                    Processing.tr("Processing"))
                ProcessingLog.addToLog(
                    ProcessingLog.LOG_ERROR,
                    Processing.tr('Error in {0}. Wrong parameter value {1} for parameter {2}.').format(
                        alg.name(), value, name
                    )
                )
                return
            # fill any missing parameters with default values if allowed
            for param in alg.parameters:
                if param.name not in setParams:
                    if not param.setDefaultValue():
                        # fix_print_with_import
                        print('Error: Missing parameter value for parameter %s.' % param.name)
                        QgsMessageLog.logMessage(
                            Processing.tr('Error: Missing parameter value for parameter {0}.').format(param.name),
                            Processing.tr("Processing"))
                        ProcessingLog.addToLog(
                            ProcessingLog.LOG_ERROR,
                            Processing.tr('Error in {0}. Missing parameter value for parameter {1}.').format(
                                alg.name(), param.name)
                        )
                        return
        else:
            if len(args) != alg.getVisibleParametersCount() + alg.getVisibleOutputsCount():
                # fix_print_with_import
                print('Error: Wrong number of parameters')
                QgsMessageLog.logMessage(Processing.tr('Error: Wrong number of parameters'),
                                         Processing.tr("Processing"))
                processing.algorithmHelp(algOrName)
                return
            i = 0
            for param in alg.parameters:
                if not param.hidden:
                    if not param.setValue(args[i]):
                        # fix_print_with_import
                        print('Error: Wrong parameter value: ' + str(args[i]))
                        QgsMessageLog.logMessage(Processing.tr('Error: Wrong parameter value: ') + str(args[i]),
                                                 Processing.tr("Processing"))
                        return
                    i = i + 1

            for output in alg.outputs:
                if not output.hidden:
                    if not output.setValue(args[i]):
                        # fix_print_with_import
                        print('Error: Wrong output value: ' + str(args[i]))
                        QgsMessageLog.logMessage(Processing.tr('Error: Wrong output value: ') + str(args[i]),
                                                 Processing.tr("Processing"))
                        return
                    i = i + 1

        msg = alg._checkParameterValuesBeforeExecuting()
        if msg:
            # fix_print_with_import
            print('Unable to execute algorithm\n' + str(msg))
            QgsMessageLog.logMessage(Processing.tr('Unable to execute algorithm\n{0}').format(msg),
                                     Processing.tr("Processing"))
            return

        if not alg.checkInputCRS():
            print('Warning: Not all input layers use the same CRS.\n' +
                  'This can cause unexpected results.')
            QgsMessageLog.logMessage(
                Processing.tr('Warning: Not all input layers use the same CRS.\nThis can cause unexpected results.'),
                Processing.tr("Processing"))

        # Don't set the wait cursor twice, because then when you
        # restore it, it will still be a wait cursor.
        overrideCursor = False
        if iface is not None:
            cursor = QApplication.overrideCursor()
            if cursor is None or cursor == 0:
                QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
                overrideCursor = True
            elif cursor.shape() != Qt.WaitCursor:
                QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
                overrideCursor = True

        feedback = None
        if kwargs is not None and "feedback" in list(kwargs.keys()):
            feedback = kwargs["feedback"]
        elif iface is not None:
            feedback = MessageBarProgress(alg.displayName())

        ret = execute(alg, feedback)
        if ret:
            if onFinish is not None:
                onFinish(alg, feedback)
        else:
            QgsMessageLog.logMessage(Processing.tr("There were errors executing the algorithm."),
                                     Processing.tr("Processing"))

        if overrideCursor:
            QApplication.restoreOverrideCursor()
        if isinstance(feedback, MessageBarProgress):
            feedback.close()
        return alg
Beispiel #28
0
    def runAlgorithm(algOrName, parameters, onFinish=None, feedback=None, context=None):
        if isinstance(algOrName, QgsProcessingAlgorithm):
            alg = algOrName
        else:
            alg = QgsApplication.processingRegistry().createAlgorithmById(algOrName)

        if feedback is None:
            feedback = QgsProcessingFeedback()

        if alg is None:
            msg = Processing.tr('Error: Algorithm {0} not found\n').format(algOrName)
            feedback.reportError(msg)
            raise QgsProcessingException(msg)

        if context is None:
            context = dataobjects.createContext(feedback)

        if context.feedback() is None:
            context.setFeedback(feedback)

        ok, msg = alg.checkParameterValues(parameters, context)
        if not ok:
            msg = Processing.tr('Unable to execute algorithm\n{0}').format(msg)
            feedback.reportError(msg)
            raise QgsProcessingException(msg)

        if not alg.validateInputCrs(parameters, context):
            feedback.pushInfo(
                Processing.tr('Warning: Not all input layers use the same CRS.\nThis can cause unexpected results.'))

        ret, results = execute(alg, parameters, context, feedback)
        if ret:
            feedback.pushInfo(
                Processing.tr('Results: {}').format(results))

            if onFinish is not None:
                onFinish(alg, context, feedback)
            else:
                # auto convert layer references in results to map layers
                for out in alg.outputDefinitions():
                    if out.name() not in results:
                        continue

                    if isinstance(out, (QgsProcessingOutputVectorLayer, QgsProcessingOutputRasterLayer, QgsProcessingOutputMapLayer)):
                        result = results[out.name()]
                        if not isinstance(result, QgsMapLayer):
                            layer = context.takeResultLayer(result) # transfer layer ownership out of context
                            if layer:
                                results[out.name()] = layer # replace layer string ref with actual layer (+ownership)
                    elif isinstance(out, QgsProcessingOutputMultipleLayers):
                        result = results[out.name()]
                        if result:
                            layers_result = []
                            for l in result:
                                if not isinstance(result, QgsMapLayer):
                                    layer = context.takeResultLayer(l) # transfer layer ownership out of context
                                    if layer:
                                        layers_result.append(layer)
                                    else:
                                        layers_result.append(l)
                                else:
                                    layers_result.append(l)

                            results[out.name()] = layers_result # replace layers strings ref with actual layers (+ownership)

        else:
            msg = Processing.tr("There were errors executing the algorithm.")
            feedback.reportError(msg)
            raise QgsProcessingException(msg)

        if isinstance(feedback, MessageBarProgress):
            feedback.close()
        return results
Beispiel #29
0
    def executeAlgorithm(self, alg_id, parent, in_place=False, as_batch=False):
        """Executes a project model with GUI interaction if needed.

        :param alg_id: algorithm id
        :type alg_id: string
        :param parent: parent widget
        :type parent: QWidget
        :param in_place: in place flag, defaults to False
        :type in_place: bool, optional
        :param as_batch: execute as batch flag, defaults to False
        :type as_batch: bool, optional
        """

        config = {}
        if in_place:
            config['IN_PLACE'] = True

        alg = QgsApplication.instance().processingRegistry(
        ).createAlgorithmById(alg_id, config)

        if alg is not None:

            ok, message = alg.canExecute()
            if not ok:
                dlg = MessageDialog()
                dlg.setTitle(self.tr('Error executing algorithm'))
                dlg.setMessage(
                    self.tr('<h3>This algorithm cannot '
                            'be run :-( </h3>\n{0}').format(message))
                dlg.exec_()
                return

            if as_batch:
                dlg = BatchAlgorithmDialog(alg, iface.mainWindow())
                dlg.setAttribute(Qt.WA_DeleteOnClose)
                dlg.show()
                dlg.exec_()
            else:
                in_place_input_parameter_name = 'INPUT'
                if hasattr(alg, 'inputParameterName'):
                    in_place_input_parameter_name = alg.inputParameterName()

                if in_place and not [
                        d
                        for d in alg.parameterDefinitions() if d.name() not in
                    (in_place_input_parameter_name, 'OUTPUT')
                ]:
                    parameters = {}
                    feedback = MessageBarProgress(algname=alg.displayName())
                    ok, results = execute_in_place(alg,
                                                   parameters,
                                                   feedback=feedback)
                    if ok:
                        iface.messageBar().pushSuccess(
                            '',
                            self.
                            tr('{algname} completed. %n feature(s) processed.',
                               n=results['__count']).format(
                                   algname=alg.displayName()))
                    feedback.close()
                    # MessageBarProgress handles errors
                    return

                if alg.countVisibleParameters() > 0:
                    dlg = alg.createCustomParametersWidget(parent)

                    if not dlg:
                        dlg = AlgorithmDialog(alg, in_place,
                                              iface.mainWindow())
                    canvas = iface.mapCanvas()
                    prevMapTool = canvas.mapTool()
                    dlg.show()
                    dlg.exec_()
                    if canvas.mapTool() != prevMapTool:
                        try:
                            canvas.mapTool().reset()
                        except Exception:
                            pass
                        canvas.setMapTool(prevMapTool)
                else:
                    feedback = MessageBarProgress(algname=alg.displayName())
                    context = dataobjects.createContext(feedback)
                    parameters = {}
                    ret, results = execute(alg, parameters, context, feedback)
                    handleAlgorithmResults(alg, context, feedback)
                    feedback.close()
Beispiel #30
0
    def test_check_validity(self):
        """Test that the output invalid contains the error reason"""

        polygon_layer = self._make_layer('Polygon')
        self.assertTrue(polygon_layer.startEditing())
        f = QgsFeature(polygon_layer.fields())
        f.setAttributes([1])
        # Flake!
        f.setGeometry(
            QgsGeometry.fromWkt('POLYGON ((0 0, 2 2, 0 2, 2 0, 0 0))'))
        self.assertTrue(f.isValid())
        f2 = QgsFeature(polygon_layer.fields())
        f2.setAttributes([1])
        f2.setGeometry(
            QgsGeometry.fromWkt(
                'POLYGON((1.1 1.1, 1.1 2.1, 2.1 2.1, 2.1 1.1, 1.1 1.1))'))
        self.assertTrue(f2.isValid())
        self.assertTrue(polygon_layer.addFeatures([f, f2]))
        polygon_layer.commitChanges()
        polygon_layer.rollBack()
        self.assertEqual(polygon_layer.featureCount(), 2)

        QgsProject.instance().addMapLayers([polygon_layer])

        alg = self.registry.createAlgorithmById('qgis:checkvalidity')

        context = QgsProcessingContext()
        context.setProject(QgsProject.instance())
        feedback = ConsoleFeedBack()

        self.assertIsNotNone(alg)
        parameters = {}
        parameters['INPUT_LAYER'] = polygon_layer.id()
        parameters['VALID_OUTPUT'] = 'memory:'
        parameters['INVALID_OUTPUT'] = 'memory:'
        parameters['ERROR_OUTPUT'] = 'memory:'

        # QGIS method
        parameters['METHOD'] = 1
        ok, results = execute(alg,
                              parameters,
                              context=context,
                              feedback=feedback)
        self.assertTrue(ok)
        invalid_layer = QgsProcessingUtils.mapLayerFromString(
            results['INVALID_OUTPUT'], context)
        self.assertEqual(invalid_layer.fields().names()[-1], '_errors')
        self.assertEqual(invalid_layer.featureCount(), 1)
        f = next(invalid_layer.getFeatures())
        self.assertEqual(f.attributes(), [
            1,
            'segments 0 and 2 of line 0 intersect at 1, 1\nGeometry has 1 errors.'
        ])

        # GEOS method
        parameters['METHOD'] = 2
        ok, results = execute(alg,
                              parameters,
                              context=context,
                              feedback=feedback)
        self.assertTrue(ok)
        invalid_layer = QgsProcessingUtils.mapLayerFromString(
            results['INVALID_OUTPUT'], context)
        self.assertEqual(invalid_layer.fields().names()[-1], '_errors')
        self.assertEqual(invalid_layer.featureCount(), 1)
        f = next(invalid_layer.getFeatures())
        self.assertEqual(f.attributes(), [1, 'Self-intersection'])
Beispiel #31
0
    def runAlgorithm(self):
        alg_parameters = []

        feedback = self.createFeedback()

        load_layers = self.mainWidget().checkLoadLayersOnCompletion.isChecked()
        project = QgsProject.instance() if load_layers else None

        for row in range(self.mainWidget().tblParameters.rowCount()):
            col = 0
            parameters = {}
            for param in self.algorithm().parameterDefinitions():
                if param.flags() & QgsProcessingParameterDefinition.FlagHidden or param.isDestination():
                    continue
                wrapper = self.mainWidget().wrappers[row][col]
                parameters[param.name()] = wrapper.parameterValue()
                if not param.checkValueIsAcceptable(wrapper.parameterValue()):
                    self.messageBar().pushMessage("", self.tr('Wrong or missing parameter value: {0} (row {1})').format(
                        param.description(), row + 1),
                        level=Qgis.Warning, duration=5)
                    return
                col += 1
            count_visible_outputs = 0
            for out in self.algorithm().destinationParameterDefinitions():
                if out.flags() & QgsProcessingParameterDefinition.FlagHidden:
                    continue

                count_visible_outputs += 1
                widget = self.mainWidget().tblParameters.cellWidget(row, col)
                text = widget.getValue()
                if out.checkValueIsAcceptable(text):
                    if isinstance(out, (QgsProcessingParameterRasterDestination,
                                        QgsProcessingParameterVectorDestination,
                                        QgsProcessingParameterFeatureSink)):
                        # load rasters and sinks on completion
                        parameters[out.name()] = QgsProcessingOutputLayerDefinition(text, project)
                    else:
                        parameters[out.name()] = text
                    col += 1
                else:
                    self.messageBar().pushMessage("", self.tr('Wrong or missing output value: {0} (row {1})').format(
                        out.description(), row + 1),
                        level=Qgis.Warning, duration=5)
                    return

            alg_parameters.append(parameters)

        task = QgsScopedProxyProgressTask(self.tr('Batch Processing - {0}').format(self.algorithm().displayName()))
        multi_feedback = QgsProcessingMultiStepFeedback(len(alg_parameters), feedback)
        feedback.progressChanged.connect(task.setProgress)

        with OverrideCursor(Qt.WaitCursor):

            self.mainWidget().setEnabled(False)
            self.cancelButton().setEnabled(True)

            # Make sure the Log tab is visible before executing the algorithm
            try:
                self.showLog()
                self.repaint()
            except:
                pass

            start_time = time.time()

            algorithm_results = []
            for count, parameters in enumerate(alg_parameters):
                if feedback.isCanceled():
                    break
                self.setProgressText(QCoreApplication.translate('BatchAlgorithmDialog', '\nProcessing algorithm {0}/{1}…').format(count + 1, len(alg_parameters)))
                self.setInfo(self.tr('<b>Algorithm {0} starting&hellip;</b>').format(self.algorithm().displayName()), escapeHtml=False)
                multi_feedback.setCurrentStep(count)

                parameters = self.algorithm().preprocessParameters(parameters)

                feedback.pushInfo(self.tr('Input parameters:'))
                feedback.pushCommandInfo(pformat(parameters))
                feedback.pushInfo('')

                # important - we create a new context for each iteration
                # this avoids holding onto resources and layers from earlier iterations,
                # and allows batch processing of many more items then is possible
                # if we hold on to these layers
                context = dataobjects.createContext(feedback)

                alg_start_time = time.time()
                ret, results = execute(self.algorithm(), parameters, context, multi_feedback)
                if ret:
                    self.setInfo(QCoreApplication.translate('BatchAlgorithmDialog', 'Algorithm {0} correctly executed…').format(self.algorithm().displayName()), escapeHtml=False)
                    feedback.pushInfo(
                        self.tr('Execution completed in {0:0.2f} seconds'.format(time.time() - alg_start_time)))
                    feedback.pushInfo(self.tr('Results:'))
                    feedback.pushCommandInfo(pformat(results))
                    feedback.pushInfo('')
                    algorithm_results.append(results)
                else:
                    break

                handleAlgorithmResults(self.algorithm(), context, multi_feedback, False)

        feedback.pushInfo(self.tr('Batch execution completed in {0:0.2f} seconds'.format(time.time() - start_time)))
        task = None

        self.finish(algorithm_results)
        self.cancelButton().setEnabled(False)
Beispiel #32
0
    def runAlgorithm(self):
        self.feedback = self.createFeedback()
        self.context = dataobjects.createContext(self.feedback)

        checkCRS = ProcessingConfig.getSetting(ProcessingConfig.WARN_UNMATCHING_CRS)
        try:
            parameters = self.getParameterValues()

            if checkCRS and not self.algorithm().validateInputCrs(parameters, self.context):
                reply = QMessageBox.question(self, self.tr("Unmatching CRS's"),
                                             self.tr('Parameters do not all use the same CRS. This can '
                                                     'cause unexpected results.\nDo you want to '
                                                     'continue?'),
                                             QMessageBox.Yes | QMessageBox.No,
                                             QMessageBox.No)
                if reply == QMessageBox.No:
                    return
            ok, msg = self.algorithm().checkParameterValues(parameters, self.context)
            if not ok:
                QMessageBox.warning(
                    self, self.tr('Unable to execute algorithm'), msg)
                return
            self.runButton().setEnabled(False)
            self.cancelButton().setEnabled(False)
            buttons = self.mainWidget().iterateButtons
            self.iterateParam = None

            for i in range(len(list(buttons.values()))):
                button = list(buttons.values())[i]
                if button.isChecked():
                    self.iterateParam = list(buttons.keys())[i]
                    break

            self.clearProgress()
            self.setProgressText(QCoreApplication.translate('AlgorithmDialog', 'Processing algorithm…'))

            self.setInfo(
                QCoreApplication.translate('AlgorithmDialog', '<b>Algorithm \'{0}\' starting&hellip;</b>').format(self.algorithm().displayName()), escapeHtml=False)

            self.feedback.pushInfo(self.tr('Input parameters:'))
            display_params = []
            for k, v in parameters.items():
                display_params.append("'" + k + "' : " + self.algorithm().parameterDefinition(k).valueAsPythonString(v, self.context))
            self.feedback.pushCommandInfo('{ ' + ', '.join(display_params) + ' }')
            self.feedback.pushInfo('')
            start_time = time.time()

            if self.iterateParam:
                # Make sure the Log tab is visible before executing the algorithm
                try:
                    self.showLog()
                    self.repaint()
                except:
                    pass

                self.cancelButton().setEnabled(self.algorithm().flags() & QgsProcessingAlgorithm.FlagCanCancel)
                if executeIterating(self.algorithm(), parameters, self.iterateParam, self.context, self.feedback):
                    self.feedback.pushInfo(
                        self.tr('Execution completed in {0:0.2f} seconds').format(time.time() - start_time))
                    self.cancelButton().setEnabled(False)
                    self.finish(True, parameters, self.context, self.feedback)
                else:
                    self.cancelButton().setEnabled(False)
                    self.resetGui()
            else:
                command = self.algorithm().asPythonCommand(parameters, self.context)
                if command:
                    ProcessingLog.addToLog(command)
                QgsGui.instance().processingRecentAlgorithmLog().push(self.algorithm().id())
                self.cancelButton().setEnabled(self.algorithm().flags() & QgsProcessingAlgorithm.FlagCanCancel)

                def on_complete(ok, results):
                    if ok:
                        self.feedback.pushInfo(self.tr('Execution completed in {0:0.2f} seconds').format(time.time() - start_time))
                        self.feedback.pushInfo(self.tr('Results:'))
                        self.feedback.pushCommandInfo(pformat(results))
                    else:
                        self.feedback.reportError(
                            self.tr('Execution failed after {0:0.2f} seconds').format(time.time() - start_time))
                    self.feedback.pushInfo('')

                    if self.feedback_dialog is not None:
                        self.feedback_dialog.close()
                        self.feedback_dialog.deleteLater()
                        self.feedback_dialog = None

                    self.cancelButton().setEnabled(False)

                    if not self.in_place:
                        self.finish(ok, results, self.context, self.feedback)
                    elif ok:
                        self.close()

                    self.feedback = None
                    self.context = None

                if not self.in_place and not (self.algorithm().flags() & QgsProcessingAlgorithm.FlagNoThreading):
                    # Make sure the Log tab is visible before executing the algorithm
                    self.showLog()

                    task = QgsProcessingAlgRunnerTask(self.algorithm(), parameters, self.context, self.feedback)
                    if task.isCanceled():
                        on_complete(False, {})
                    else:
                        task.executed.connect(on_complete)
                        self.setCurrentTask(task)
                else:
                    self.proxy_progress = QgsProxyProgressTask(QCoreApplication.translate("AlgorithmDialog", "Executing “{}”").format(self.algorithm().displayName()))
                    QgsApplication.taskManager().addTask(self.proxy_progress)
                    self.feedback.progressChanged.connect(self.proxy_progress.setProxyProgress)
                    self.feedback_dialog = self.createProgressDialog()
                    self.feedback_dialog.show()
                    if self.in_place:
                        ok, results = execute_in_place(self.algorithm(), parameters, self.context, self.feedback)
                    else:
                        ok, results = execute(self.algorithm(), parameters, self.context, self.feedback)
                    self.feedback.progressChanged.disconnect()
                    self.proxy_progress.finalize(ok)
                    on_complete(ok, results)

        except AlgorithmDialogBase.InvalidParameterValue as e:
            try:
                self.buttonBox().accepted.connect(lambda e=e:
                                                  e.widget.setPalette(QPalette()))
                palette = e.widget.palette()
                palette.setColor(QPalette.Base, QColor(255, 255, 0))
                e.widget.setPalette(palette)
            except:
                pass
            self.messageBar().clearWidgets()
            self.messageBar().pushMessage("", self.tr("Wrong or missing parameter value: {0}").format(e.parameter.description()),
                                          level=Qgis.Warning, duration=5)
        except AlgorithmDialogBase.InvalidOutputExtension as e:
            try:
                self.buttonBox().accepted.connect(lambda e=e:
                                                  e.widget.setPalette(QPalette()))
                palette = e.widget.palette()
                palette.setColor(QPalette.Base, QColor(255, 255, 0))
                e.widget.setPalette(palette)
            except:
                pass
            self.messageBar().clearWidgets()
            self.messageBar().pushMessage("", e.message,
                                          level=Qgis.Warning, duration=5)
Beispiel #33
0
    def runAlgorithm(algOrName, parameters, onFinish=None, feedback=None, context=None):
        if isinstance(algOrName, QgsProcessingAlgorithm):
            alg = algOrName
        else:
            alg = QgsApplication.processingRegistry().createAlgorithmById(algOrName)

        if feedback is None:
            feedback = QgsProcessingFeedback()

        if alg is None:
            msg = Processing.tr('Error: Algorithm {0} not found\n').format(algOrName)
            feedback.reportError(msg)
            raise QgsProcessingException(msg)

        if context is None:
            context = dataobjects.createContext(feedback)

        if context.feedback() is None:
            context.setFeedback(feedback)

        ok, msg = alg.checkParameterValues(parameters, context)
        if not ok:
            msg = Processing.tr('Unable to execute algorithm\n{0}').format(msg)
            feedback.reportError(msg)
            raise QgsProcessingException(msg)

        if not alg.validateInputCrs(parameters, context):
            feedback.pushInfo(
                Processing.tr('Warning: Not all input layers use the same CRS.\nThis can cause unexpected results.'))

        ret, results = execute(alg, parameters, context, feedback)
        if ret:
            feedback.pushInfo(
                Processing.tr('Results: {}').format(results))

            if onFinish is not None:
                onFinish(alg, context, feedback)
            else:
                # auto convert layer references in results to map layers
                for out in alg.outputDefinitions():
                    if out.name() not in results:
                        continue

                    if isinstance(out, (QgsProcessingOutputVectorLayer, QgsProcessingOutputRasterLayer, QgsProcessingOutputMapLayer)):
                        result = results[out.name()]
                        if not isinstance(result, QgsMapLayer):
                            layer = context.takeResultLayer(result) # transfer layer ownership out of context
                            if layer:
                                results[out.name()] = layer # replace layer string ref with actual layer (+ownership)
                    elif isinstance(out, QgsProcessingOutputMultipleLayers):
                        result = results[out.name()]
                        if result:
                            layers_result = []
                            for l in result:
                                if not isinstance(result, QgsMapLayer):
                                    layer = context.takeResultLayer(l) # transfer layer ownership out of context
                                    if layer:
                                        layers_result.append(layer)
                                    else:
                                        layers_result.append(l)
                                else:
                                    layers_result.append(l)

                            results[out.name()] = layers_result # replace layers strings ref with actual layers (+ownership)

        else:
            msg = Processing.tr("There were errors executing the algorithm.")
            feedback.reportError(msg)
            raise QgsProcessingException(msg)

        if isinstance(feedback, MessageBarProgress):
            feedback.close()
        return results
Beispiel #34
0
    def runAlgorithm(self):
        alg_parameters = []

        feedback = self.createFeedback()

        load_layers = self.mainWidget().checkLoadLayersOnCompletion.isChecked()
        project = QgsProject.instance() if load_layers else None

        for row in range(self.mainWidget().batchRowCount()):
            parameters = self.mainWidget().parametersForRow(row, destinationProject=project, warnOnInvalid=True)
            alg_parameters.append(parameters)

        task = QgsScopedProxyProgressTask(self.tr('Batch Processing - {0}').format(self.algorithm().displayName()))
        multi_feedback = QgsProcessingMultiStepFeedback(len(alg_parameters), feedback)
        feedback.progressChanged.connect(task.setProgress)

        with OverrideCursor(Qt.WaitCursor):

            self.mainWidget().setEnabled(False)
            self.cancelButton().setEnabled(True)

            # Make sure the Log tab is visible before executing the algorithm
            try:
                self.showLog()
                self.repaint()
            except:
                pass

            start_time = time.time()

            algorithm_results = []
            for count, parameters in enumerate(alg_parameters):
                if feedback.isCanceled():
                    break
                self.setProgressText(
                    QCoreApplication.translate('BatchAlgorithmDialog', '\nProcessing algorithm {0}/{1}…').format(
                        count + 1, len(alg_parameters)))
                self.setInfo(self.tr('<b>Algorithm {0} starting&hellip;</b>').format(self.algorithm().displayName()),
                             escapeHtml=False)
                multi_feedback.setCurrentStep(count)

                parameters = self.algorithm().preprocessParameters(parameters)

                feedback.pushInfo(self.tr('Input parameters:'))
                feedback.pushCommandInfo(pformat(parameters))
                feedback.pushInfo('')

                # important - we create a new context for each iteration
                # this avoids holding onto resources and layers from earlier iterations,
                # and allows batch processing of many more items then is possible
                # if we hold on to these layers
                context = dataobjects.createContext(feedback)

                alg_start_time = time.time()
                ret, results = execute(self.algorithm(), parameters, context, multi_feedback)
                if ret:
                    self.setInfo(
                        QCoreApplication.translate('BatchAlgorithmDialog', 'Algorithm {0} correctly executed…').format(
                            self.algorithm().displayName()), escapeHtml=False)
                    feedback.pushInfo(
                        self.tr('Execution completed in {0:0.2f} seconds'.format(time.time() - alg_start_time)))
                    feedback.pushInfo(self.tr('Results:'))
                    feedback.pushCommandInfo(pformat(results))
                    feedback.pushInfo('')
                    algorithm_results.append(results)
                else:
                    break

                handleAlgorithmResults(self.algorithm(), context, multi_feedback, False, parameters)

        feedback.pushInfo(self.tr('Batch execution completed in {0:0.2f} seconds'.format(time.time() - start_time)))
        task = None

        self.finish(algorithm_results)
        self.cancelButton().setEnabled(False)
Beispiel #35
0
    def runAlgorithm(algOrName,
                     parameters,
                     onFinish=None,
                     feedback=None,
                     context=None):
        if isinstance(algOrName, QgsProcessingAlgorithm):
            alg = algOrName
        else:
            alg = QgsApplication.processingRegistry().createAlgorithmById(
                algOrName)

        if feedback is None:
            feedback = MessageBarProgress(
                alg.displayName() if alg else Processing.tr('Processing'))

        if alg is None:
            # fix_print_with_import
            print('Error: Algorithm not found\n')
            msg = Processing.tr('Error: Algorithm {0} not found\n').format(
                algOrName)
            feedback.reportError(msg)
            raise QgsProcessingException(msg)

        # check for any mandatory parameters which were not specified
        for param in alg.parameterDefinitions():
            if param.name() not in parameters:
                if not param.flags(
                ) & QgsProcessingParameterDefinition.FlagOptional:
                    # fix_print_with_import
                    msg = Processing.tr(
                        'Error: Missing parameter value for parameter {0}.'
                    ).format(param.name())
                    print('Error: Missing parameter value for parameter %s.' %
                          param.name())
                    feedback.reportError(msg)
                    raise QgsProcessingException(msg)

        if context is None:
            context = dataobjects.createContext(feedback)

        ok, msg = alg.checkParameterValues(parameters, context)
        if not ok:
            # fix_print_with_import
            print('Unable to execute algorithm\n' + str(msg))
            msg = Processing.tr('Unable to execute algorithm\n{0}').format(msg)
            feedback.reportError(msg)
            raise QgsProcessingException(msg)

        if not alg.validateInputCrs(parameters, context):
            print('Warning: Not all input layers use the same CRS.\n' +
                  'This can cause unexpected results.')
            feedback.pushInfo(
                Processing.
                tr('Warning: Not all input layers use the same CRS.\nThis can cause unexpected results.'
                   ))

        ret, results = execute(alg, parameters, context, feedback)
        if ret:
            feedback.pushInfo(Processing.tr('Results: {}').format(results))

            if onFinish is not None:
                onFinish(alg, context, feedback)
            else:
                # auto convert layer references in results to map layers
                for out in alg.outputDefinitions():
                    if isinstance(out, (QgsProcessingOutputVectorLayer,
                                        QgsProcessingOutputRasterLayer,
                                        QgsProcessingOutputMapLayer)):
                        result = results[out.name()]
                        if not isinstance(result, QgsMapLayer):
                            layer = context.takeResultLayer(
                                result
                            )  # transfer layer ownership out of context
                            if layer:
                                results[out.name(
                                )] = layer  # replace layer string ref with actual layer (+ownership)
        else:
            msg = Processing.tr("There were errors executing the algorithm.")
            feedback.reportError(msg)
            raise QgsProcessingException(msg)

        if isinstance(feedback, MessageBarProgress):
            feedback.close()
        return results
Beispiel #36
0
    def accept(self):
        feedback = self.createFeedback()
        context = dataobjects.createContext(feedback)

        checkCRS = ProcessingConfig.getSetting(
            ProcessingConfig.WARN_UNMATCHING_CRS)
        try:
            parameters = self.getParameterValues()

            if checkCRS and not self.algorithm().validateInputCrs(
                    parameters, context):
                reply = QMessageBox.question(
                    self, self.tr("Unmatching CRS's"),
                    self.tr('Layers do not all use the same CRS. This can '
                            'cause unexpected results.\nDo you want to '
                            'continue?'), QMessageBox.Yes | QMessageBox.No,
                    QMessageBox.No)
                if reply == QMessageBox.No:
                    return
            checkExtentCRS = ProcessingConfig.getSetting(
                ProcessingConfig.WARN_UNMATCHING_EXTENT_CRS)
            # TODO
            if False and checkExtentCRS and self.checkExtentCRS():
                reply = QMessageBox.question(
                    self, self.tr("Extent CRS"),
                    self.
                    tr('Extent parameters must use the same CRS as the input layers.\n'
                       'Your input layers do not have the same extent as the project, '
                       'so the extent might be in a wrong CRS if you have selected it from the canvas.\n'
                       'Do you want to continue?'),
                    QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
                if reply == QMessageBox.No:
                    return
            ok, msg = self.algorithm().checkParameterValues(
                parameters, context)
            if msg:
                QMessageBox.warning(self,
                                    self.tr('Unable to execute algorithm'),
                                    msg)
                return
            self.runButton().setEnabled(False)
            self.cancelButton().setEnabled(False)
            buttons = self.mainWidget().iterateButtons
            self.iterateParam = None

            for i in range(len(list(buttons.values()))):
                button = list(buttons.values())[i]
                if button.isChecked():
                    self.iterateParam = list(buttons.keys())[i]
                    break

            self.clearProgress()
            self.setProgressText(self.tr('Processing algorithm...'))

            self.setInfo(
                self.tr('<b>Algorithm \'{0}\' starting...</b>').format(
                    self.algorithm().displayName()),
                escapeHtml=False)

            feedback.pushInfo(self.tr('Input parameters:'))
            display_params = []
            for k, v in parameters.items():
                display_params.append("'" + k + "' : " +
                                      self.algorithm().parameterDefinition(
                                          k).valueAsPythonString(v, context))
            feedback.pushCommandInfo('{ ' + ', '.join(display_params) + ' }')
            feedback.pushInfo('')
            start_time = time.time()

            if self.iterateParam:
                # Make sure the Log tab is visible before executing the algorithm
                try:
                    self.showLog()
                    self.repaint()
                except:
                    pass

                self.cancelButton().setEnabled(
                    self.algorithm().flags()
                    & QgsProcessingAlgorithm.FlagCanCancel)
                if executeIterating(self.algorithm(), parameters,
                                    self.iterateParam, context, feedback):
                    feedback.pushInfo(
                        self.tr(
                            'Execution completed in {0:0.2f} seconds'.format(
                                time.time() - start_time)))
                    self.cancelButton().setEnabled(False)
                    self.finish(True, parameters, context, feedback)
                else:
                    self.cancelButton().setEnabled(False)
                    self.resetGui()
            else:
                command = self.algorithm().asPythonCommand(parameters, context)
                if command:
                    ProcessingLog.addToLog(command)
                self.cancelButton().setEnabled(
                    self.algorithm().flags()
                    & QgsProcessingAlgorithm.FlagCanCancel)

                def on_complete(ok, results):
                    if ok:
                        feedback.pushInfo(
                            self.tr('Execution completed in {0:0.2f} seconds'.
                                    format(time.time() - start_time)))
                        feedback.pushInfo(self.tr('Results:'))
                        feedback.pushCommandInfo(pformat(results))
                    else:
                        feedback.reportError(
                            self.tr('Execution failed after {0:0.2f} seconds'.
                                    format(time.time() - start_time)))
                    feedback.pushInfo('')

                    if self.feedback_dialog is not None:
                        self.feedback_dialog.close()
                        self.feedback_dialog.deleteLater()
                        self.feedback_dialog = None

                    self.cancelButton().setEnabled(False)

                    self.finish(ok, results, context, feedback)

                if not (self.algorithm().flags()
                        & QgsProcessingAlgorithm.FlagNoThreading):
                    # Make sure the Log tab is visible before executing the algorithm
                    self.showLog()

                    task = QgsProcessingAlgRunnerTask(self.algorithm(),
                                                      parameters, context,
                                                      feedback)
                    task.executed.connect(on_complete)
                    self.setCurrentTask(task)
                else:
                    self.feedback_dialog = self.createProgressDialog()
                    self.feedback_dialog.show()
                    ok, results = execute(self.algorithm(), parameters,
                                          context, feedback)
                    on_complete(ok, results)

        except AlgorithmDialogBase.InvalidParameterValue as e:
            try:
                self.buttonBox().accepted.connect(
                    lambda e=e: e.widget.setPalette(QPalette()))
                palette = e.widget.palette()
                palette.setColor(QPalette.Base, QColor(255, 255, 0))
                e.widget.setPalette(palette)
            except:
                pass
            self.messageBar().clearWidgets()
            self.messageBar().pushMessage(
                "",
                self.tr("Wrong or missing parameter value: {0}").format(
                    e.parameter.description()),
                level=Qgis.Warning,
                duration=5)