def create_styles_to_attributes_tasks(
    task_wrappers: List[TaskWrapper], completed: Callable
) -> None:
    tasks = []
    if len(task_wrappers) == 0:
        # TODO: custom execption
        raise ValueError()
    for task_wrapper in task_wrappers:
        alg = QgsApplication.processingRegistry().algorithmById(
            f"{SpatialDataPackageProcessingProvider.ID}:{StyleToAttributesAlg.ID}"
        )
        task = QgsProcessingAlgRunnerTask(
            alg, task_wrapper.params, task_wrapper.context, task_wrapper.feedback
        )
        task.setDependentLayers([task_wrapper.layer])
        # noinspection PyUnresolvedReferences
        task.executed.connect(
            partial(
                task_wrapper.executed,
                task_wrapper.layer,
                task_wrapper.context,
                task_wrapper.id,
            )
        )
        # noinspection PyUnresolvedReferences
        task.taskCompleted.connect(completed)
        tasks.append(task)

    main_task = tasks[0]
    for i in range(1, len(tasks)):
        main_task.addSubTask(tasks[i])

    QgsApplication.taskManager().addTask(main_task)
Exemple #2
0
    def test_bad_script_dont_crash(self):  # spellok
        """Test regression #21270 (segfault)"""

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

        task = QgsProcessingAlgRunnerTask(CrashingProcessingAlgorithm(), {}, context=context, feedback=feedback)
        self.assertTrue(task.isCanceled())
        self.assertIn('name \'ExampleProcessingAlgorithm\' is not defined', feedback._error)
    def test_bad_script_dont_crash(self):  # spellok
        """Test regression #21270 (segfault)"""

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

        task = QgsProcessingAlgRunnerTask(CrashingProcessingAlgorithm(), {}, context=context, feedback=feedback)
        self.assertTrue(task.isCanceled())
        self.assertIn('name \'ExampleProcessingAlgorithm\' is not defined', feedback._error)
 def handle_report(self):
     task = QgsProcessingAlgRunnerTask(
         self.algorithm, self.params, self.context, self.feedback
     )
     task.executed.connect(self.task_finished)
     task_manager = QgsApplication.taskManager()
     task_manager.addTask(task)
 def perform_automation(self):
     task = QgsProcessingAlgRunnerTask(self.algorithm, self.params,
                                       self.context, self.feedback)
     utils.log_message(f"self.algorithm: {self.algorithm}")
     utils.log_message(f"self.params: {self.params}")
     utils.log_message(
         f"self.params types: {[(k, type(v)) for k,v in self.params.items()]}"
     )
     utils.log_message(
         f"self.params values: {[(k, v) for k,v in self.params.items()]}")
     task.executed.connect(self.task_finished)
     task_manager = QgsApplication.taskManager()
     task_manager.addTask(task)
Exemple #6
0
 def run_import_command(self):
     """Adds the polygonize script to a QgsTask"""
     self.s_tbl = "{schema}.{file_name}".format(file_name=self.file_name,
                                                schema=self.schema)
     input_ = self.file_name_with_path
     params = {
         'INPUT': input_,
         'BAND': 1,
         'OUTPUT': self.plugin_dir + '/temp.shp',
         'FIELD': 'raster_value'
     }
     alg = QgsApplication.processingRegistry().algorithmById(
         u'gdal:polygonize')
     context = QgsProcessingContext()
     task = QgsProcessingAlgRunnerTask(alg, params, context)
     task.executed.connect(partial(self.task_finished, context))
     self.tsk_mngr.addTask(task)
 def start_task(self, input_layer, field, max_iterations, max_average_error):
     self.context = QgsProcessingContext()
     self.feedback = QgsProcessingFeedback()
     self.task = QgsProcessingAlgRunnerTask(
         QgsApplication.processingRegistry().algorithmById("cartogram3:compute_cartogram"),
         {
             "INPUT": input_layer,
             "FIELD": field,
             "MAX_ITERATIONS": max_iterations,
             "MAX_AVERAGE_ERROR": max_average_error,
             "OUTPUT": "memory:"
         },
         self.context,
         self.feedback
     )
     self.task.executed.connect(self.task_finished)
     self.feedback.progressChanged.connect(self.update_progress)
     QgsApplication.taskManager().addTask(self.task)
 def uploadSingleLayer(self):
     '''Uploads a single input layer to database'''
     alg = QgsApplication.processingRegistry().algorithmById(
         'gdal:importvectorintopostgisdatabasenewconnection')
     params = {
         'A_SRS': QgsCoordinateReferenceSystem('EPSG:3067'),
         'T_SRS': None,
         'S_SRS': None,
         'HOST': self.connParams['host'],
         'PORT': self.connParams['port'],
         'USER': self.connParams['user'],
         'DBNAME': self.connParams['database'],
         'PASSWORD': self.connParams['password'],
         'SCHEMA': 'user_input',
         'PK': 'fid',
         'PRIMARY_KEY': None,
         'PROMOTETOMULTI': False
     }
     context = QgsProcessingContext()
     feedback = QgsProcessingFeedback()
     layer = self.inputLayers[self.layerUploadIndex]
     if not layer:
         self.tableNames[layer] = False
         self.uploadNextLayer()
     params['INPUT'] = layer
     tableName = self.sessionParams['uuid'] + '_' + layer.name()
     tableName = tableName.replace('-', '_')
     params['TABLE'] = tableName[:49]  # truncate tablename to under 63c
     self.tableNames[layer] = params['TABLE']
     if layer.geometryType() == 0:  # point
         params['GTYPE'] = 3
     elif layer.geometryType() == 2:  # polygon
         params['GTYPE'] = 8
     task = QgsProcessingAlgRunnerTask(alg, params, context, feedback)
     task.executed.connect(partial(self.uploadFinished, context))
     QgsApplication.taskManager().addTask(task)
     self.iface.messageBar().pushMessage('Ladataan tasoa tietokantaan',
                                         layer.name(),
                                         Qgis.Info,
                                         duration=3)
Exemple #9
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)
Exemple #10
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 self.algorithm().flags() & QgsProcessingAlgorithm.FlagCanRunInBackground:
                    # 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=QgsMessageBar.WARNING, duration=5)
Exemple #11
0
    def accept(self):
        super(AlgorithmDialog, self)._saveGeometry()

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

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

            if checkCRS and not self.alg.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.alg.checkParameterValues(parameters, context)
            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

            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('')
            start_time = time.time()

            if self.iterateParam:
                self.buttonCancel.setEnabled(
                    self.alg.flags() & QgsProcessingAlgorithm.FlagCanCancel)
                if executeIterating(self.alg, parameters, self.iterateParam,
                                    context, feedback):
                    feedback.pushInfo(
                        self.tr(
                            'Execution completed in {0:0.2f} seconds'.format(
                                time.time() - start_time)))
                    self.buttonCancel.setEnabled(False)
                    self.finish(True, parameters, context, feedback)
                else:
                    self.buttonCancel.setEnabled(False)
                    self.resetGUI()
            else:
                command = self.alg.asPythonCommand(parameters, context)
                if command:
                    ProcessingLog.addToLog(command)
                self.buttonCancel.setEnabled(
                    self.alg.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('')

                    self.buttonCancel.setEnabled(False)
                    self.finish(ok, results, context, feedback)

                task = QgsProcessingAlgRunnerTask(self.alg, parameters,
                                                  context, feedback)
                task.executed.connect(on_complete)
                QgsApplication.taskManager().addTask(task)

        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)
Exemple #12
0
    def union_executed(self, context, iteration, ok, result):
        #self.showInfo("Union executed: " + str(iteration) + ', OK: ' + str(ok) + ', Res: ' + str(result))
        if not ok:
            self.showInfo("Union failed - " + str(iteration))
            return
        # Get the result (polygon) dataset from the union algorithm
        unionlayer = QgsProcessingUtils.mapLayerFromString(
            result['OUTPUT'], context)
        # Add attributes
        provider = unionlayer.dataProvider()
        provider.addAttributes([QgsField('Area', QVariant.Double)])
        provider.addAttributes([QgsField('Combined', QVariant.String, len=40)])
        unionlayer.updateFields()
        unionlayer.startEditing()
        area_field_index = unionlayer.fields().lookupField('Area')  # OK
        #self.showInfo('union, area field index: ' + str(area_field_index))
        combined_field_index = unionlayer.fields().lookupField(
            'Combined')  # OK
        #self.showInfo('union, combined field index: ' + str(combined_field_index))
        # Update the attributes
        for f in provider.getFeatures():
            #self.showInfo('Feature: ' + str(f))
            area = f.geometry().area()
            unionlayer.changeAttributeValue(f.id(), area_field_index, area)
            iidx = unionlayer.fields().lookupField('InputB')
            ridx = unionlayer.fields().lookupField('RefB')
            i = f.attributes()[iidx]
            r = f.attributes()[ridx]
            # Set the 'Combined' attribute value to show the combination
            comb = ''
            if i is not None:
                if r is not None:
                    comb = str(i) + str(r)
                else:
                    comb = str(i)
            else:
                if r is not None:
                    comb = str(r)
                else:
                    comb = None
            #self.showInfo('Combination: ' + str(comb))
            unionlayer.changeAttributeValue(f.id(), combined_field_index, comb)
        unionlayer.commitChanges()

        # Do multipart to singlepart: # OK
        params = {
            #'INPUT': QgsProcessingUtils.mapLayerFromString(result['OUTPUT'], context),
            'INPUT': unionlayer,
            #'INPUT': result['OUTPUT'],
            'OUTPUT': 'memory:Singlepart'
        }
        task = QgsProcessingAlgRunnerTask(self.multitosinglealg, params,
                                          context)
        # Add extra parameters (context, iteration) using "partial"
        task.executed.connect(
            partial(self.tosingle_executed, context, iteration))
        QgsApplication.taskManager().addTask(task)
        #self.showInfo('Start MultipartToSinglepart: ' + str(iteration))

        # Do the statistics
        params = {
            'INPUT': unionlayer,
            'VALUES_FIELD_NAME': 'Area',
            'CATEGORIES_FIELD_NAME': 'Combined',
            #'OUTPUT':'/home/havatv/stats.csv'
            'OUTPUT': 'memory:Statistics'
        }
        task = QgsProcessingAlgRunnerTask(self.statalg, params, context)
        # Add extra parameters (context, iteration) using "partial"
        task.executed.connect(partial(self.stats_executed, context, iteration))
        QgsApplication.taskManager().addTask(task)
Exemple #13
0
    def buffer_executed(self, context, iteration, kind, ok, result):
        #self.showInfo("Buffer executed (" + str(kind) + '): ' +
        #              str(iteration) + ', OK: ' + str(ok) +
        #              ', Res: ' + str(result))
        self.tcmutex.acquire()
        try:
            self.testcounter = self.testcounter + 1
            self.showInfo("Buffer finished: " + str(iteration) + ' - ' +
                          str(kind) + ' ' + str(self.testcounter) + ' ' +
                          str(QgsApplication.taskManager().count()))
        finally:
            self.tcmutex.release()
        #return

        if not ok:
            self.showInfo("Buffer failed - " + str(iteration) + ' ' +
                          str(kind))
            return
        #blayer = result['OUTPUT'] ## blayer blir string!
        # Get the result (line) dataset from the buffer algorithm
        blayer = QgsProcessingUtils.mapLayerFromString(result['OUTPUT'],
                                                       context)
        # Add attribute
        provider = blayer.dataProvider()
        newfield = QgsField('InputB', QVariant.String, len=5)
        if kind == self.REF:
            newfield = QgsField('RefB', QVariant.String, len=5)
        provider.addAttributes([newfield])
        blayer.updateFields()
        # Update the attribute
        blayer.startEditing()
        field_index = blayer.fields().lookupField('InputB')
        if kind == self.REF:
            field_index = blayer.fields().lookupField('RefB')
        #self.showInfo('refb, field index: ' + str(field_index))
        for f in provider.getFeatures():
            #self.showInfo('Feature (refb): ' + str(f))
            if kind == self.REF:
                # Set the attribute value to 'R'
                blayer.changeAttributeValue(f.id(), field_index, 'R')
            else:
                # Set the attribute value to 'I'
                blayer.changeAttributeValue(f.id(), field_index, 'I')
        blayer.commitChanges()

        if kind == self.INPUT:
            self.ibmutex.acquire(
            )  # Important to acquire ibmutex first (deadlock)
            try:
                self.inputbuffers[iteration] = result['OUTPUT']
            finally:
                self.ibmutex.release()
        elif kind == self.REF:
            self.rbmutex.acquire()
            try:
                self.referencebuffers[iteration] = result['OUTPUT']
            finally:
                self.rbmutex.release()
        else:
            self.showInfo("Strange kind of buffer: " + str(kind))
        # Do line overlay:  # Works!
        if kind == self.INPUT:
            reflayercopy = QgsVectorLayer(self.reflayer.source(),
                                          'refint' + str(iteration),
                                          self.reflayer.providerType())
            #reflayercopy = self.copylayer(self.reflayer, 'refint' + str(iteration))
            params = {
                'INPUT': reflayercopy,
                #'INPUT': self.reflayer,
                #'OVERLAY': result['OUTPUT'],
                'OVERLAY': blayer,
                #'OVERLAY': QgsProcessingUtils.mapLayerFromString(result['OUTPUT'], context),
                'OUTPUT': 'memory:Intersection'
            }
            task = QgsProcessingAlgRunnerTask(self.intersectionalg, params,
                                              context)
            # Add a few extra parameters (context, radius) using "partial"
            task.executed.connect(
                partial(self.intersection_executed, context, iteration))
            QgsApplication.taskManager().addTask(task)
            #self.showInfo('Start Intersection: ' + str(iteration))
        elif kind == self.REF:
            # The reference buffer is used to remove parts of the input layer
            inlayercopy = QgsVectorLayer(self.inputlayer.source(),
                                         'indiff' + str(iteration),
                                         self.inputlayer.providerType())
            #inlayercopy = self.copylayer(self.inputlayer, 'indiff' + str(iteration))
            params = {
                'INPUT': inlayercopy,
                #'INPUT': self.inputlayer,
                'OVERLAY': blayer,
                'OUTPUT': 'memory:Difference'
            }
            task = QgsProcessingAlgRunnerTask(self.differencealg, params,
                                              context)
            # Add a few extra parameters (context, radius) using "partial"
            task.executed.connect(
                partial(self.difference_executed, context, iteration))
            QgsApplication.taskManager().addTask(task)
            #self.showInfo('Start Difference: ' + str(iteration))

        todelete = []  # buffer sizes to remove (after handling)
        # Do union, if possible
        # Check if both buffers are available:
        self.ibmutex.acquire()  # Important to acquire ibmutex first (deadlock)
        try:
            self.rbmutex.acquire()
            try:
                for key in self.inputbuffers:
                    if key in self.referencebuffers:
                        # Union input  # Does not work!
                        params = {
                            #'INPUT': self.inputbuffers[key],
                            'INPUT':
                            QgsProcessingUtils.mapLayerFromString(
                                self.inputbuffers[key], context),
                            #'OVERLAY': self.referencebuffers[key],
                            'OVERLAY':
                            QgsProcessingUtils.mapLayerFromString(
                                self.referencebuffers[key], context),
                            'OUTPUT':
                            'memory:Union'
                        }
                        task = QgsProcessingAlgRunnerTask(
                            self.unionalg, params, context)
                        # Add a few extra parameters (context, radius) using "partial"
                        task.executed.connect(
                            partial(self.union_executed, context, iteration))
                        QgsApplication.taskManager().addTask(task)
                        #self.showInfo('Start Union: ' + str(iteration))
                        todelete.append(key)
                        #del self.inputbuffers[key]
                        #del self.referencebuffers[key]
                for key in todelete:
                    del self.inputbuffers[key]
                    del self.referencebuffers[key]
                    #self.showInfo('Removed key: ' + str(key))
            finally:
                self.rbmutex.release()
        finally:
            self.ibmutex.release()
Exemple #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:
            # 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:
                        self.history_details['results'] = results
                        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)
Exemple #15
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)
Exemple #16
0
    def startWorker(self):
        """Initialises and starts."""
        self.inputbuffers = {}
        self.referencebuffers = {}
        self.polycount = {}
        self.completeness = {}
        self.miscodings = {}
        self.statistics = {}
        self.testcounter = 0

        try:
            layerindex = self.inputLayer.currentIndex()
            layerId = self.inputLayer.itemData(layerindex)
            self.inputlayer = QgsProject.instance().mapLayer(layerId)
            if self.inputlayer is None:
                self.showError(self.tr('No input layer defined'))
                return
            refindex = self.referenceLayer.currentIndex()
            reflayerId = self.referenceLayer.itemData(refindex)
            self.reflayer = QgsProject.instance().mapLayer(reflayerId)
            if layerId == reflayerId:
                self.showInfo('The reference layer must be different'
                              ' from the input layer!')
                return
            if self.reflayer is None:
                self.showError(self.tr('No reference layer defined'))
                return
            if self.inputlayer.sourceCrs().authid() != self.reflayer.sourceCrs(
            ).authid():
                self.showWarning('Layers must have the same CRS - Input: ' +
                                 str(self.inputlayer.sourceCrs().authid()) +
                                 ' Reference: ' +
                                 str(self.reflayer.sourceCrs().authid()))
                return
            if self.reflayer.sourceCrs().isGeographic():
                self.showWarning('Geographic CRS used -' +
                                 ' computations will be in decimal degrees!')
            # Algorithms
            self.bufferalg = QgsApplication.processingRegistry().algorithmById(
                'native:buffer')
            #self.bufferalg=QgsApplication.processingRegistry().algorithmById('qgis:buffer')
            self.unionalg = QgsApplication.processingRegistry().algorithmById(
                'qgis:union')
            self.intersectionalg = QgsApplication.processingRegistry(
            ).algorithmById('qgis:intersection')
            self.differencealg = QgsApplication.processingRegistry(
            ).algorithmById('qgis:difference')
            self.multitosinglealg = QgsApplication.processingRegistry(
            ).algorithmById('qgis:multiparttosingleparts')
            self.statalg = QgsApplication.processingRegistry().algorithmById(
                'qgis:statisticsbycategories')

            # Calculate the total length of lines in the layers
            self.inpgeomlength = 0
            for f in self.inputlayer.getFeatures():
                self.inpgeomlength = self.inpgeomlength + f.geometry().length()
            self.refgeomlength = 0
            for f in self.reflayer.getFeatures():
                self.refgeomlength = self.refgeomlength + f.geometry().length()

            # Number of steps and radii
            steps = self.stepsSB.value()
            startradius = self.startRadiusSB.value()
            endradius = self.endRadiusSB.value()
            delta = (endradius - startradius) / (steps - 1)
            self.radiuses = []
            for step in range(steps):
                self.radiuses.append(startradius + step * delta)
            #self.radiuses = [10,20,50]
            #self.showInfo(str(self.radiuses))
            feedback = QgsProcessingFeedback()
            selectedinputonly = self.selectedFeaturesCheckBox.isChecked()
            selectedrefonly = self.selectedRefFeaturesCheckBox.isChecked()
            #plugincontext = dataobjects.createContext(feedback)
            #self.showInfo('Plugin context: ' + str(plugincontext))
            #self.showInfo('GUI thread: ' + str(QThread.currentThread()) + ' ID: ' + str(QThread.currentThreadId()))

            ###### Testing QgsTask!!!
            # I følge oppskrifta på opengis.ch
            context = QgsProcessingContext()
            #context = plugincontext
            #self.showInfo('Normal context: ' + str(context))
            #context.setProject(QgsProject.instance())
            for radius in self.radiuses:
                # Buffer input  # Works!
                inlayercopy = QgsVectorLayer(self.inputlayer.source(),
                                             'in' + str(radius),
                                             self.inputlayer.providerType())
                ##inlayercopy = self.copylayer(self.inputlayer, 'in' + str(radius))
                params = {
                    'INPUT': inlayercopy,
                    #'INPUT': self.inputlayer,
                    'DISTANCE': radius,
                    #'OUTPUT':'/home/havatv/test.shp'
                    'OUTPUT': 'memory:InputBuffer'
                }
                task = QgsProcessingAlgRunnerTask(self.bufferalg, params,
                                                  context)
                ##task = QgsProcessingAlgRunnerTask(self.bufferalg,params,context,feedback)
                # Add a few extra parameters (context, radius and "input") using "partial"
                task.executed.connect(
                    partial(self.buffer_executed, context, radius, self.INPUT))
                QgsApplication.taskManager().addTask(task)
                self.showInfo('Start Input buffer: ' + str(radius))
                # Buffer reference  # Works!
                reflayercopy = QgsVectorLayer(self.reflayer.source(),
                                              'ref' + str(radius),
                                              self.reflayer.providerType())
                #reflayercopy = self.copylayer(self.reflayer, 'ref' + str(radius))
                params = {
                    'INPUT': reflayercopy,
                    #'INPUT': self.reflayer,
                    'DISTANCE': radius,
                    #'OUTPUT':'/home/havatv/test.shp'
                    'OUTPUT': 'memory:ReferenceBuffer'
                }
                task = QgsProcessingAlgRunnerTask(self.bufferalg, params,
                                                  context)
                #task = QgsProcessingAlgRunnerTask(self.bufferalg,params,context,feedback)
                # Add a few extra parameters (context, radius and "reference") using "partial"
                task.executed.connect(
                    partial(self.buffer_executed, context, radius, self.REF))
                QgsApplication.taskManager().addTask(task)
                self.showInfo('Start Ref buffer: ' + str(radius))

            ##task.begun.connect(self.task_begun)
            ##task.taskCompleted.connect(self.task_completed)
            ##task.progressChanged.connect(self.task_progress)
            ##task.taskTerminated.connect(self.task_stopped)

            #iteration = 5   # Identifiserer hvilken iterasjon det er snakk om

            ## I følge oppskrifta på opengis.ch (partial legger inn context som første parameter):
            ## context ser ut til å være helt nødvendig!
            #task.executed.connect(partial(self.task_executed, context, iteration))
            #self.button_box.button(QDialogButtonBox.Ok).setEnabled(False)
            #self.button_box.button(QDialogButtonBox.Close).setEnabled(False)
            #self.button_box.button(QDialogButtonBox.Cancel).setEnabled(True)
        except:
            import traceback
            self.showError(traceback.format_exc())
        else:
            pass
Exemple #17
0
    def test_flags(self):
        """
        Test task flags
        """
        thread_safe_alg = QgsApplication.processingRegistry().algorithmById(
            'native:buffer')
        nonthread_safe_alg = QgsApplication.processingRegistry().algorithmById(
            'native:setprojectvariable')
        context = QgsProcessingContext()
        context.setProject(QgsProject.instance())
        feedback = ConsoleFeedBack()

        task = QgsProcessingAlgRunnerTask(thread_safe_alg, {},
                                          context=context,
                                          feedback=feedback)
        self.assertEqual(task.flags(), QgsTask.CanCancel)
        task = QgsProcessingAlgRunnerTask(thread_safe_alg, {},
                                          context=context,
                                          feedback=feedback,
                                          flags=QgsTask.Flags())
        self.assertEqual(task.flags(), QgsTask.Flags())
        task = QgsProcessingAlgRunnerTask(thread_safe_alg, {},
                                          context=context,
                                          feedback=feedback,
                                          flags=QgsTask.CanCancel)
        self.assertEqual(task.flags(), QgsTask.CanCancel)
        task = QgsProcessingAlgRunnerTask(thread_safe_alg, {},
                                          context=context,
                                          feedback=feedback,
                                          flags=QgsTask.CancelWithoutPrompt)
        self.assertEqual(task.flags(), QgsTask.CancelWithoutPrompt)
        task = QgsProcessingAlgRunnerTask(thread_safe_alg, {},
                                          context=context,
                                          feedback=feedback,
                                          flags=QgsTask.CancelWithoutPrompt
                                          | QgsTask.CanCancel)
        self.assertEqual(task.flags(),
                         QgsTask.CancelWithoutPrompt | QgsTask.CanCancel)

        # alg which can't be canceled
        task = QgsProcessingAlgRunnerTask(nonthread_safe_alg, {},
                                          context=context,
                                          feedback=feedback)
        self.assertEqual(task.flags(), QgsTask.Flags())
        # we clear the CanCancel flag automatically, since the algorithm itself cannot be canceled
        task = QgsProcessingAlgRunnerTask(nonthread_safe_alg, {},
                                          context=context,
                                          feedback=feedback,
                                          flags=QgsTask.CanCancel)
        self.assertEqual(task.flags(), QgsTask.Flags())

        # hidden task
        task = QgsProcessingAlgRunnerTask(thread_safe_alg, {},
                                          context=context,
                                          feedback=feedback,
                                          flags=QgsTask.Hidden)
        self.assertEqual(task.flags(), QgsTask.Hidden)
        task = QgsProcessingAlgRunnerTask(thread_safe_alg, {},
                                          context=context,
                                          feedback=feedback,
                                          flags=QgsTask.Hidden
                                          | QgsTask.CanCancel)
        self.assertEqual(task.flags(), QgsTask.Hidden | QgsTask.CanCancel)
        task = QgsProcessingAlgRunnerTask(thread_safe_alg, {},
                                          context=context,
                                          feedback=feedback,
                                          flags=QgsTask.Hidden
                                          | QgsTask.CanCancel
                                          | QgsTask.CancelWithoutPrompt)
        self.assertEqual(
            task.flags(),
            QgsTask.Hidden | QgsTask.CanCancel | QgsTask.CancelWithoutPrompt)

        task = QgsProcessingAlgRunnerTask(nonthread_safe_alg, {},
                                          context=context,
                                          feedback=feedback,
                                          flags=QgsTask.Hidden)
        self.assertEqual(task.flags(), QgsTask.Hidden)
        task = QgsProcessingAlgRunnerTask(nonthread_safe_alg, {},
                                          context=context,
                                          feedback=feedback,
                                          flags=QgsTask.Hidden
                                          | QgsTask.CanCancel)
        self.assertEqual(task.flags(), QgsTask.Hidden)
Exemple #18
0
def calculate_zonal_stats(callback,
                          zonal_layer,
                          points_layer,
                          join_fields,
                          output_layer_name,
                          discard_nonmatching=False,
                          predicates=('intersects', ),
                          summaries=('sum', )):
    """
    Leveraging the QGIS processing algorithm 'Join attributes by location
    (summary)', that is described in QGIS as follows:
    This algorithm takes an input vector layer and creates a new vector layer
    that is an extended version of the input one, with additional attributes in
    its attribute table. The additional attributes and their values are taken
    from a second vector layer. A spatial criteria is applied to select the
    values from the second layer that are added to each feature from the first
    layer in the resulting one. The algorithm calculates a statistical summary
    for the values from matching features in the second layer (e.g. maximum
    value, mean value, etc).
    The full description of the algorithm can be obtained as follows:
    processing.algorithmHelp('qgis:joinbylocationsummary') and it includes
    the lists of predicates and summaries.
    The code of the algorithm is here:
    https://github.com/qgis/QGIS/blob
    /483b4ff977e3d36b166fac792254c31e89e3aeae/python/plugins/processing/algs
    /qgis/SpatialJoinSummary.py  # NOQA

    :param callback: function to be called once the aggregation is complete,
        passing the output zonal layer as a parameter
    :param zonal_layer: vector layer containing polygons (or its path)
    :param points_layer: vector layer containing points (or its path)
    :param join_fields: fields for which we want to calculate statistics
        (e.g. structural)
    :param output_layer_name: a memory layer will be produced, named
        'memory:output_layer_name'
    :param discard_nonmatching: discard records which could not be joined
        (in our case, purge zones that contain no loss/damage points)
    :param predicates: geometric predicates (default: 'intersects')
    :param summaries: statistics to be calculated for each join field
        (default: 'sum')

    :returns: it waits until the task is complete or terminated, then it
        calls the callback function, passing the output QgsVectorLayer as
        parameter, or None in case of failure
    """

    processing.Processing.initialize()
    alg = QgsApplication.processingRegistry().algorithmById(
        'qgis:joinbylocationsummary')
    # make sure to use the actual lists of predicates and summaries as defined
    # in the algorithm when it is instantiated
    predicate_keys = [predicate[0] for predicate in alg.predicates]
    PREDICATES = dict(zip(predicate_keys, range(len(predicate_keys))))
    summary_keys = [statistic[0] for statistic in alg.statistics]
    SUMMARIES = dict(zip(summary_keys, range(len(summary_keys))))

    context = QgsProcessingContext()
    feedback = QgsProcessingFeedback()

    params = {
        'DISCARD_NONMATCHING': discard_nonmatching,
        'INPUT': zonal_layer,
        'JOIN': points_layer,
        'PREDICATE': [PREDICATES[predicate] for predicate in predicates],
        'JOIN_FIELDS': join_fields,
        'SUMMARIES': [SUMMARIES[summary] for summary in summaries],
        'OUTPUT': 'memory:%s' % output_layer_name
    }

    task = QgsProcessingAlgRunnerTask(alg, params, context, feedback)
    task.executed.connect(partial(task_finished, context, callback))
    QgsApplication.taskManager().addTask(task)

    while True:
        # the user can "cancel" the task, interrupting this loop
        QgsApplication.processEvents()
        # status can be queued, onhold, running, complete, terminated
        if task.status() > 2:  # Complete or terminated
            return
        time.sleep(0.1)