예제 #1
0
def execute_in_place(alg, parameters, context=None, feedback=None):
    """Executes an algorithm modifying features in-place, if the INPUT
    parameter is not defined, the current active layer will be used as
    INPUT.

    :param alg: algorithm to run
    :type alg: QgsProcessingAlgorithm
    :param parameters: parameters of the algorithm
    :type parameters: dict
    :param context: context, defaults to None
    :param context: QgsProcessingContext, optional
    :param feedback: feedback, defaults to None
    :param feedback: QgsProcessingFeedback, optional
    :raises QgsProcessingException: raised when the layer is not editable or the layer cannot be found in the current project
    :return: a tuple with true if success and results
    :rtype: tuple
    """

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

    if not 'INPUT' in parameters or not parameters['INPUT']:
        parameters['INPUT'] = iface.activeLayer()
    ok, results = execute_in_place_run(alg, parameters, context=context, feedback=feedback)
    if ok:
        if isinstance(parameters['INPUT'], QgsProcessingFeatureSourceDefinition):
            layer = alg.parameterAsVectorLayer({'INPUT': parameters['INPUT'].source}, 'INPUT', context)
        elif isinstance(parameters['INPUT'], QgsVectorLayer):
            layer = parameters['INPUT']
        if layer:
            layer.triggerRepaint()
    return ok, results
예제 #2
0
    def getParamValues(self):
        if self.mUpdateExistingGroupBox.isChecked():
            fieldName = self.mExistingFieldComboBox.currentText()
        else:
            fieldName = self.mOutputFieldNameLineEdit.text()

        layer = self.cmbInputLayer.currentLayer()

        context = dataobjects.createContext()

        parameters = {}
        parameters['INPUT'] = layer
        parameters['FIELD_NAME'] = fieldName
        parameters['FIELD_TYPE'] = self.mOutputFieldTypeComboBox.currentIndex()
        parameters['FIELD_LENGTH'] = self.mOutputFieldWidthSpinBox.value()
        parameters['FIELD_PRECISION'] = self.mOutputFieldPrecisionSpinBox.value()
        parameters['NEW_FIELD'] = self.mNewFieldGroupBox.isChecked()
        parameters['FORMULA'] = self.builder.expressionText()
        output = QgsProcessingOutputLayerDefinition()
        if self.leOutputFile.text().strip():
            output.sink = QgsProperty.fromValue(self.leOutputFile.text().strip())
        else:
            output.sink = QgsProperty.fromValue('memory:')
        output.destinationProject = context.project()
        parameters['OUTPUT'] = output

        ok, msg = self.alg.checkParameterValues(parameters, context)
        if not ok:
            QMessageBox.warning(
                self, self.tr('Unable to execute algorithm'), msg)
            return {}
        return parameters
예제 #3
0
파일: menus.py 프로젝트: ndavid/QGIS
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()
예제 #4
0
파일: parameters.py 프로젝트: ndavid/QGIS
    def getSafeExportedLayer(self):
        """Returns not the value entered by the user, but a string with
        a filename which contains the data of this layer, but saved in
        a standard format (currently always a shapefile) so that it can
        be opened by most external applications.

        If there is a selection and QGIS is configured to use just the
        selection, if exports the layer even if it is already in a
        suitable format.

        Works only if the layer represented by the parameter value is
        currently loaded in QGIS. Otherwise, it will not perform any
        export and return the current value string.

        If the current value represents a layer in a suitable format,
        it does not export at all and returns that value.

        The layer is exported just the first time the method is called.
        The method can be called several times and it will always
        return the same file, performing the export only the first
        time.
        """
        context = dataobjects.createContext()

        if self.exported:
            return self.exported
        layer = QgsProcessingUtils.mapLayerFromString(self.value, context, False)
        if layer:
            self.exported = dataobjects.exportVectorLayer(layer)
        else:
            self.exported = self.value
        return self.exported
예제 #5
0
    def checkExtentCRS(self):
        unmatchingCRS = False
        hasExtent = False
        context = dataobjects.createContext()
        projectCRS = iface.mapCanvas().mapSettings().destinationCrs()
        layers = QgsProcessingUtils.compatibleLayers(QgsProject.instance())
        for param in self.algorithm().parameterDefinitions():
            if isinstance(param, (ParameterRaster, ParameterVector, ParameterMultipleInput)):
                if param.value:
                    if isinstance(param, ParameterMultipleInput):
                        inputlayers = param.value.split(';')
                    else:
                        inputlayers = [param.value]
                    for inputlayer in inputlayers:
                        for layer in layers:
                            if layer.source() == inputlayer:
                                if layer.crs() != projectCRS:
                                    unmatchingCRS = True

                        p = QgsProcessingUtils.mapLayerFromString(inputlayer, context)
                        if p is not None:
                            if p.crs() != projectCRS:
                                unmatchingCRS = True
            if isinstance(param, ParameterExtent):
                if param.skip_crs_check:
                    continue

                value = self.mainWidget().wrappers[param.name()].widget.leText.text().strip()
                if value:
                    hasExtent = True

        return hasExtent and unmatchingCRS
예제 #6
0
파일: parameters.py 프로젝트: ndavid/QGIS
    def __init__(self, name='', description='', options=[], default=None, isSource=False,
                 multiple=False, optional=False):
        Parameter.__init__(self, name, description, default, optional)
        self.multiple = multiple
        isSource = parseBool(isSource)
        self.options = options
        if isSource:
            self.options = []
            layer = QgsVectorLayer(options[0], "layer", "ogr")
            if layer.isValid():
                try:
                    index = resolveFieldIndex(layer, options[1])
                    feats = QgsProcessingUtils.getFeatures(layer, dataobjects.createContext())
                    for feature in feats:
                        self.options.append(str(feature.attributes()[index]))
                except ValueError:
                    pass
        elif isinstance(self.options, str):
            self.options = self.options.split(";")

        # compute options as (value, text)
        options = []
        for i, option in enumerate(self.options):
            if option is None or isinstance(option, basestring):
                options.append((i, option))
            else:
                options.append((option[0], option[1]))
        self.options = options
        self.values = [option[0] for option in options]

        self.value = None
예제 #7
0
파일: parameters.py 프로젝트: ndavid/QGIS
    def getSafeExportedTable(self):
        """Returns not the value entered by the user, but a string with
        a filename which contains the data of this table, but saved in
        a standard format (currently always a DBF file) so that it can
        be opened by most external applications.

        Works only if the table represented by the parameter value is
        currently loaded in QGIS. Otherwise, it will not perform any
        export and return the current value string.

        If the current value represents a table in a suitable format,
        it does not export at all and returns that value.

        The table is exported just the first time the method is called.
        The method can be called several times and it will always
        return the same file, performing the export only the first
        time.
        """
        context = dataobjects.createContext()
        if self.exported:
            return self.exported
        table = QgsProcessingUtils.mapLayerFromString(self.value, context, False)
        if table:
            self.exported = dataobjects.exportTable(table)
        else:
            self.exported = self.value
        return self.exported
예제 #8
0
    def __init__(self, alg, model, algName=None, configuration=None):
        QDialog.__init__(self)
        self.setModal(True)

        self._alg = alg # The algorithm to define in this dialog. It is an instance of QgsProcessingAlgorithm
        self.model = model # The model this algorithm is going to be added to. It is an instance of QgsProcessingModelAlgorithm
        self.childId = algName # The name of the algorithm in the model, in case we are editing it and not defining it for the first time
        self.configuration = configuration
        self.context = createContext()

        self.widget_labels = {}

        class ContextGenerator(QgsProcessingContextGenerator):

            def __init__(self, context):
                super().__init__()
                self.processing_context = context

            def processingContext(self):
                return self.processing_context

        self.context_generator = ContextGenerator(self.context)

        self.setupUi()
        self.params = None

        settings = QgsSettings()
        self.restoreGeometry(settings.value("/Processing/modelParametersDialogGeometry", QByteArray()))
예제 #9
0
    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()
예제 #10
0
 def setOutputCRS(self):
     context = dataobjects.createContext()
     layers = QgsProcessingUtils.compatibleLayers(QgsProject.instance())
     for param in self.parameterDefinitions():
         if isinstance(param, (ParameterRaster, ParameterVector, ParameterMultipleInput)):
             if param.value:
                 if isinstance(param, ParameterMultipleInput):
                     inputlayers = param.value.split(';')
                 else:
                     inputlayers = [param.value]
                 for inputlayer in inputlayers:
                     for layer in layers:
                         if layer.source() == inputlayer:
                             self.crs = layer.crs()
                             return
                     p = QgsProcessingUtils.mapLayerFromString(inputlayer, context)
                     if p is not None:
                         self.crs = p.crs()
                         p = None
                         return
     try:
         from qgis.utils import iface
         if iface is not None:
             self.crs = iface.mapCanvas().mapSettings().destinationCrs()
     except:
         pass
예제 #11
0
 def getLayerFromValue(self, value):
     context = createContext()
     if isinstance(value, QgsProcessingFeatureSourceDefinition):
         value, ok = value.source.valueAsString(context.expressionContext())
     if isinstance(value, str):
         value = QgsProcessingUtils.mapLayerFromString(value, context)
     return value
예제 #12
0
    def __init__(self, dialog, param):
        super(ExtentSelectionPanel, self).__init__(None)
        self.setupUi(self)

        self.dialog = dialog
        self.param = param
        if self.param.flags() & QgsProcessingParameterDefinition.FlagOptional:
            if hasattr(self.leText, 'setPlaceholderText'):
                self.leText.setPlaceholderText(
                    self.tr('[Leave blank to use min covering extent]'))

        self.btnSelect.clicked.connect(self.selectExtent)

        canvas = iface.mapCanvas()
        self.prevMapTool = canvas.mapTool()
        self.tool = RectangleMapTool(canvas)
        self.tool.rectangleCreated.connect(self.updateExtent)

        if param.defaultValue() is not None:
            context = createContext()
            rect = QgsProcessingParameters.parameterAsExtent(param, {param.name(): param.defaultValue()}, context)
            if not rect.isNull():
                try:
                    s = '{},{},{},{}'.format(
                        rect.xMinimum(), rect.xMaximum(), rect.yMinimum(), rect.yMaximum())
                    self.leText.setText(s)
                except:
                    pass
예제 #13
0
    def __init__(self, parent, alg):
        super(ParametersPanel, self).__init__(None)
        self.setupUi(self)

        self.grpAdvanced.hide()

        self.scrollAreaWidgetContents.setContentsMargins(4, 4, 4, 4)
        self.layoutMain = self.scrollAreaWidgetContents.layout()
        self.layoutAdvanced = self.grpAdvanced.layout()

        self.parent = parent
        self.alg = alg
        self.wrappers = {}
        self.outputWidgets = {}
        self.checkBoxes = {}
        self.dependentItems = {}
        self.iterateButtons = {}

        self.processing_context = createContext()

        class ContextGenerator(QgsProcessingContextGenerator):

            def __init__(self, context):
                super().__init__()
                self.processing_context = context

            def processingContext(self):
                return self.processing_context

        self.context_generator = ContextGenerator(self.processing_context)

        self.initWidgets()

        QgsProject.instance().layerWasAdded.connect(self.layerRegistryChanged)
        QgsProject.instance().layersWillBeRemoved.connect(self.layerRegistryChanged)
예제 #14
0
def executeAlgorithm(alg, parameters, context=None, feedback=None, model=None):
    """The method to use to call a processing algorithm.

    Although the body of the algorithm is in processAlgorithm(),
    it should be called using this method, since it performs
    some additional operations.

    Raises a QgsProcessingException in case anything goes
    wrong.
    :param parameters:
    """

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

    #self.model = model

    #self.setOutputCRS()
    #self.resolveOutputs()
    #self.evaluateParameterValues()
    #self.runPreExecutionScript(feedback)
    result, ok = alg.run(parameters, context, feedback)
    #self.processAlgorithm(parameters, context, feedback)
    feedback.setProgress(100)
    return result, ok
예제 #15
0
    def exportVectorLayer(self, orgFilename):
        context = dataobjects.createContext()

        # TODO: improve this. We are now exporting if it is not a shapefile,
        # but the functionality of v.in.ogr could be used for this.
        # We also export if there is a selection
        if not os.path.exists(orgFilename) or not orgFilename.endswith('shp'):
            layer = QgsProcessingUtils.mapLayerFromString(orgFilename, context, False)
            if layer:
                filename = dataobjects.exportVectorLayer(layer)
        else:
            layer = QgsProcessingUtils.mapLayerFromString(orgFilename, context, False)
            if layer:
                #TODO
                #useSelection = \
                #    ProcessingConfig.getSetting(ProcessingConfig.USE_SELECTED)
                if useSelection and layer.selectedFeatureCount() != 0:
                    filename = dataobjects.exportVectorLayer(layer)
                else:
                    filename = orgFilename
            else:
                filename = orgFilename
        destFilename = 'a' + os.path.basename(self.getTempFilename())
        self.exportedLayers[orgFilename] = destFilename
        command = 'v.in.ogr'
        min_area = self.getParameterValue(self.GRASS_MIN_AREA_PARAMETER)
        command += ' min_area=' + str(min_area)
        snap = self.getParameterValue(self.GRASS_SNAP_TOLERANCE_PARAMETER)
        command += ' snap=' + str(snap)
        command += ' input="' + os.path.dirname(filename) + '"'
        command += ' layer=' + os.path.basename(filename)[:-4]
        command += ' output=' + destFilename
        command += ' --overwrite -o'
        return command
예제 #16
0
 def showExpressionsBuilder(self):
     context = self.alg.createExpressionContext({}, createContext())
     dlg = QgsExpressionBuilderDialog(None, self.leText.text(), self, 'generic',
                                      context)
     dlg.setWindowTitle(self.tr('Expression based output'))
     if dlg.exec_() == QDialog.Accepted:
         expression = QgsExpression(dlg.expressionText())
         self.leText.setText(expression.evaluate(context))
예제 #17
0
파일: ClipByMask.py 프로젝트: rskelly/QGIS
    def getConsoleCommands(self, parameters):
        out = self.getOutputValue(self.OUTPUT)
        mask = self.getParameterValue(self.MASK)
        context = dataobjects.createContext()
        maskLayer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.MASK), context)
        ogrMask = ogrConnectionString(mask)[1:-1]
        noData = self.getParameterValue(self.NO_DATA)
        opts = self.getParameterValue(self.OPTIONS)

        if noData is not None:
            noData = str(noData)

        addAlphaBand = self.getParameterValue(self.ALPHA_BAND)
        cropToCutline = self.getParameterValue(self.CROP_TO_CUTLINE)
        keepResolution = self.getParameterValue(self.KEEP_RESOLUTION)

        arguments = []
        arguments.append('-ot')
        arguments.append(self.TYPE[self.getParameterValue(self.RTYPE)])
        arguments.append('-q')
        arguments.append('-of')
        arguments.append(GdalUtils.getFormatShortNameFromFilename(out))
        if noData and len(noData) > 0:
            arguments.append('-dstnodata')
            arguments.append(noData)

        if keepResolution:
            r = gdal.Open(self.getParameterValue(self.INPUT))
            geoTransform = r.GetGeoTransform()
            r = None
            arguments.append('-tr')
            arguments.append(str(geoTransform[1]))
            arguments.append(str(geoTransform[5]))
            arguments.append('-tap')

        arguments.append('-cutline')
        arguments.append(ogrMask)
        if maskLayer and maskLayer.subsetString() != '':
            arguments.append('-cwhere')
            arguments.append(maskLayer.subsetString())

        if cropToCutline:
            arguments.append('-crop_to_cutline')

        if addAlphaBand:
            arguments.append('-dstalpha')

        if opts:
            arguments.append('-co')
            arguments.append(opts)

        if GdalUtils.version() in [2010000, 2010100]:
            arguments.append("--config GDALWARP_IGNORE_BAD_CUTLINE YES")

        arguments.append(self.getParameterValue(self.INPUT))
        arguments.append(out)

        return ['gdalwarp', GdalUtils.escapeAndJoin(arguments)]
예제 #18
0
파일: BatchPanel.py 프로젝트: qgis/QGIS
    def populateByExpression(self, adding=False):
        """
        Populates the panel using an expression
        """
        context = dataobjects.createContext()
        expression_context = context.expressionContext()

        # use the first row parameter values as a preview during expression creation
        params = self.panel.parametersForRow(0, warnOnInvalid=False)
        alg_scope = QgsExpressionContextUtils.processingAlgorithmScope(self.panel.alg, params, context)

        # create explicit variables corresponding to every parameter
        for k, v in params.items():
            alg_scope.setVariable(k, v, True)

        expression_context.appendScope(alg_scope)

        # mark the parameter variables as highlighted for discoverability
        highlighted_vars = expression_context.highlightedVariables()
        highlighted_vars.extend(list(params.keys()))
        expression_context.setHighlightedVariables(highlighted_vars)

        dlg = QgsExpressionBuilderDialog(layer=None, context=context.expressionContext())
        if adding:
            dlg.setExpectedOutputFormat(self.tr('An array of values corresponding to each new row to add'))

        if not dlg.exec_():
            return

        if adding:
            exp = QgsExpression(dlg.expressionText())
            res = exp.evaluate(expression_context)

            if type(res) is not list:
                res = [res]

            first_row = self.panel.batchRowCount() if self.panel.batchRowCount() > 1 else 0
            for row, value in enumerate(res):
                self.setRowValue(row + first_row, value, context)
        else:
            for row in range(self.panel.batchRowCount()):
                params = self.panel.parametersForRow(row, warnOnInvalid=False)

                # remove previous algorithm scope -- we need to rebuild this completely, using the
                # other parameter values from the current row
                expression_context.popScope()
                alg_scope = QgsExpressionContextUtils.processingAlgorithmScope(self.panel.alg, params, context)

                for k, v in params.items():
                    alg_scope.setVariable(k, v, True)

                expression_context.appendScope(alg_scope)

                # rebuild a new expression every time -- we don't want the expression compiler to replace
                # variables with precompiled values
                exp = QgsExpression(dlg.expressionText())
                value = exp.evaluate(expression_context)
                self.setRowValue(row, value, context)
예제 #19
0
    def testProcessingException(self):
        """
        Test that Python exception is caught when running an alg
        """

        alg = TestAlg()
        context = createContext()
        feedback = QgsProcessingFeedback()
        results, ok = alg.run({}, context, feedback)
        self.assertFalse(ok)
예제 #20
0
파일: BatchPanel.py 프로젝트: uclaros/QGIS
    def fillParameterValues(self, column):
        context = dataobjects.createContext()

        wrapper = self.wrappers[0][column]
        if wrapper is None:
            # e.g. double clicking on a destination header
            return

        for row in range(1, self.tblParameters.rowCount()):
            self.wrappers[row][column].setParameterValue(wrapper.parameterValue(), context)
예제 #21
0
 def setDynamicLayer(self, layer):
     context = createContext()
     try:
         if isinstance(layer, QgsProcessingFeatureSourceDefinition):
             layer, ok = layer.source.valueAsString(context.expressionContext())
         if isinstance(layer, str):
             layer = QgsProcessingUtils.mapLayerFromString(layer, context)
         self.btnDataDefined.setVectorLayer(layer)
     except:
         pass
예제 #22
0
    def _test_difference_on_invalid_geometries(self, geom_option):
        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())
        self.assertTrue(polygon_layer.addFeatures([f]))
        polygon_layer.commitChanges()
        polygon_layer.rollBack()
        self.assertEqual(polygon_layer.featureCount(), 1)

        overlay_layer = self._make_layer('Polygon')
        self.assertTrue(overlay_layer.startEditing())
        f = QgsFeature(overlay_layer.fields())
        f.setAttributes([1])
        f.setGeometry(QgsGeometry.fromWkt('Polygon ((0 0, 2 0, 2 2, 0 2, 0 0))'))
        self.assertTrue(f.isValid())
        self.assertTrue(overlay_layer.addFeatures([f]))
        overlay_layer.commitChanges()
        overlay_layer.rollBack()
        self.assertEqual(overlay_layer.featureCount(), 1)

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

        old_features = [f for f in polygon_layer.getFeatures()]

        # 'Ignore features with invalid geometries' = 1
        ProcessingConfig.setSettingValue(ProcessingConfig.FILTER_INVALID_GEOMETRIES, geom_option)

        feedback = ConsoleFeedBack()
        context = dataobjects.createContext(feedback)
        context.setProject(QgsProject.instance())

        alg = self.registry.createAlgorithmById('native:difference')
        self.assertIsNotNone(alg)

        parameters = {
            'OVERLAY': overlay_layer,
            'INPUT': polygon_layer,
            'OUTPUT': ':memory',
        }

        old_features = [f for f in polygon_layer.getFeatures()]

        self.assertTrue(polygon_layer.startEditing())
        polygon_layer.selectAll()
        ok, _ = execute_in_place_run(
            alg, parameters, context=context, feedback=feedback, raise_exceptions=True)

        new_features = [f for f in polygon_layer.getFeatures()]

        return old_features, new_features
예제 #23
0
 def setSessionProjectionFromLayer(self, layer, commands):
     context = dataobjects.createContext()
     if not Grass7Utils.projectionSet:
         qGisLayer = QgsProcessingUtils.mapLayerFromString(layer, context)
         if qGisLayer:
             proj4 = str(qGisLayer.crs().toProj4())
             command = 'g.proj'
             command += ' -c'
             command += ' proj4="' + proj4 + '"'
             self.commands.append(command)
             Grass7Utils.projectionSet = True
예제 #24
0
 def setLayer(self, layer):
     context = dataobjects.createContext()
     if layer == self._layer:
         return
     if isinstance(layer, QgsProcessingFeatureSourceDefinition):
         layer, ok = layer.source.valueAsString(context.expressionContext())
     if isinstance(layer, str):
         layer = QgsProcessingUtils.mapLayerFromString(layer, context)
     if not isinstance(layer, QgsVectorLayer):
         layer = None
     self._layer = layer
     self.panel.setLayer(self._layer)
예제 #25
0
파일: BatchPanel.py 프로젝트: qgis/QGIS
    def addFilesByPattern(self):
        """
        Populates the dialog using a file pattern match
        """
        dlg = QgsFindFilesByPatternDialog()
        dlg.setWindowTitle(self.tr("Add Files by Pattern"))
        if dlg.exec_():
            files = dlg.files()
            context = dataobjects.createContext()

            first_row = self.panel.batchRowCount() if self.panel.batchRowCount() > 1 else 0
            for row, file in enumerate(files):
                self.setRowValue(first_row + row, file, context)
예제 #26
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()
예제 #27
0
파일: parameters.py 프로젝트: ndavid/QGIS
    def getSafeExportedLayers(self):
        """
        Returns not the value entered by the user, but a string with
        semicolon-separated filenames which contains the data of the
        selected layers, but saved in a standard format (currently
        shapefiles for vector layers and GeoTiff for raster) so that
        they can be opened by most external applications.

        If there is a selection and QGIS is configured to use just the
        selection, it exports the layer even if it is already in a
        suitable format.

        Works only if the layer represented by the parameter value is
        currently loaded in QGIS. Otherwise, it will not perform any
        export and return the current value string.

        If the current value represents a layer in a suitable format,
        it does no export at all and returns that value.

        Currently, it works just for vector layer. In the case of
        raster layers, it returns the parameter value.

        The layers are exported just the first time the method is
        called. The method can be called several times and it will
        always return the same string, performing the export only the
        first time.
        """
        context = dataobjects.createContext()
        if self.exported:
            return self.exported
        self.exported = self.value
        layers = self.value.split(';')
        if layers is None or len(layers) == 0:
            return self.value
        if self.datatype == dataobjects.TYPE_RASTER:
            for layerfile in layers:
                layer = QgsProcessingUtils.mapLayerFromString(layerfile, context, False)
                if layer:
                    filename = dataobjects.exportRasterLayer(layer)
                    self.exported = self.exported.replace(layerfile, filename)
            return self.exported
        elif self.datatype == dataobjects.TYPE_FILE:
            return self.value
        else:
            for layerfile in layers:
                layer = QgsProcessingUtils.mapLayerFromString(layerfile, context, False)
                if layer:
                    filename = dataobjects.exportVectorLayer(layer)
                    self.exported = self.exported.replace(layerfile, filename)
            return self.exported
예제 #28
0
    def getLayerFromValue(self, value):
        context = createContext()
        if isinstance(value, QgsProcessingFeatureSourceDefinition):
            value, ok = value.source.valueAsString(context.expressionContext())
        if isinstance(value, str):
            value = QgsProcessingUtils.mapLayerFromString(value, context)
        if value is None or not isinstance(value, QgsMapLayer):
            return None

        # need to return layer with ownership - otherwise layer may be deleted when context
        # goes out of scope
        new_layer = context.takeResultLayer(value.id())
        # if we got ownership, return that - otherwise just return the layer (which may be owned by the project)
        return new_layer if new_layer is not None else value
예제 #29
0
    def save(self):
        toSave = []
        context = dataobjects.createContext()
        for row in range(self.tblParameters.rowCount()):
            algParams = {}
            algOutputs = {}
            col = 0
            alg = self.alg
            for param in alg.parameterDefinitions():
                if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
                    continue
                if param.isDestination():
                    continue
                wrapper = self.wrappers[row][col]
                if not param.checkValueIsAcceptable(wrapper.value(), context):
                    self.parent.messageBar().pushMessage("", self.tr('Wrong or missing parameter value: {0} (row {1})').format(
                        param.description(), row + 1),
                        level=Qgis.Warning, duration=5)
                    return
                algParams[param.name()] = param.valueAsPythonString(wrapper.value(), context)
                col += 1
            for out in alg.destinationParameterDefinitions():
                if out.flags() & QgsProcessingParameterDefinition.FlagHidden:
                    continue
                widget = self.tblParameters.cellWidget(row, col)
                text = widget.getValue()
                if text.strip() != '':
                    algOutputs[out.name()] = text.strip()
                    col += 1
                else:
                    self.parent.messageBar().pushMessage("", self.tr('Wrong or missing output value: {0} (row {1})').format(
                        out.description(), row + 1),
                        level=Qgis.Warning, duration=5)
                    return
            toSave.append({self.PARAMETERS: algParams, self.OUTPUTS: algOutputs})

        settings = QgsSettings()
        last_path = settings.value("/Processing/LastBatchPath", QDir.homePath())
        filename, __ = QFileDialog.getSaveFileName(self,
                                                   self.tr('Save Batch'),
                                                   last_path,
                                                   self.tr('JSON files (*.json)'))
        if filename:
            if not filename.endswith('.json'):
                filename += '.json'
            last_path = QFileInfo(filename).path()
            settings.setValue('/Processing/LastBatchPath', last_path)
            with open(filename, 'w') as f:
                json.dump(toSave, f)
예제 #30
0
def executeAlgorithm(alg, parameters, context=None, feedback=None, model=None):
    """The method to use to call a processing algorithm.

    Although the body of the algorithm is in processAlgorithm(),
    it should be called using this method, since it performs
    some additional operations.

    Raises a GeoAlgorithmExecutionException in case anything goes
    wrong.
    :param parameters:
    """

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

    #self.model = model
    try:
        #self.setOutputCRS()
        #self.resolveOutputs()
        #self.evaluateParameterValues()
        #self.runPreExecutionScript(feedback)
        result = alg.run(parameters, context, feedback)
        #self.processAlgorithm(parameters, context, feedback)
        feedback.setProgress(100)
        return result
        #self.convertUnsupportedFormats(context, feedback)
        #self.runPostExecutionScript(feedback)
    except GeoAlgorithmExecutionException as gaee:
        lines = [self.tr('Error while executing algorithm')]
        lines = []
        lines.append(traceback.format_exc())
        feedback.reportError(gaee.msg)
        QgsMessageLog.logMessage(gaee.msg, self.tr('Processing'), QgsMessageLog.CRITICAL)
        raise GeoAlgorithmExecutionException(gaee.msg, lines, gaee)
    #except Exception as e:
        # If something goes wrong and is not caught in the
        # algorithm, we catch it here and wrap it
        #lines = [self.tr('Uncaught error while executing algorithm')]
     #   lines = []
      #  lines.append(traceback.format_exc())
        #QgsMessageLog.logMessage('\n'.join(lines), self.tr('Processing'), QgsMessageLog.CRITICAL)
        #raise GeoAlgorithmExecutionException(str(e) + self.tr('\nSee log for more details'), lines, e)

    def helpUrl(self):
        return QgsHelp.helpUrl("processing_algs/{}/{}".format(
            self.provider().id(), self.id())).toString()
예제 #31
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)
예제 #32
0
    def paintModel(self, model, controls=True):
        self.model = model
        context = createContext()
        # Inputs
        for inp in list(model.parameterComponents().values()):
            item = ModelerGraphicItem(inp, model, controls, scene=self)
            item.setFlag(QGraphicsItem.ItemIsMovable, True)
            item.setFlag(QGraphicsItem.ItemIsSelectable, True)
            self.addItem(item)
            item.setPos(inp.position().x(), inp.position().y())
            self.paramItems[inp.parameterName()] = item

        # Input dependency arrows
        for input_name in list(model.parameterComponents().keys()):
            idx = 0
            parameter_def = model.parameterDefinition(input_name)
            if hasattr(parameter_def, 'parentLayerParameterName'
                       ) and parameter_def.parentLayerParameterName():
                parent_name = parameter_def.parentLayerParameterName()
                if input_name in self.paramItems and parent_name in self.paramItems:
                    input_item = self.paramItems[input_name]
                    parent_item = self.paramItems[parent_name]
                    arrow = ModelerArrowItem(parent_item, -1, input_item, -1)
                    input_item.addArrow(arrow)
                    parent_item.addArrow(arrow)
                    arrow.setPenStyle(Qt.DotLine)
                    arrow.updatePath()
                    self.addItem(arrow)

        # We add the algs
        for alg in list(model.childAlgorithms().values()):
            item = ModelerGraphicItem(alg, model, controls, scene=self)
            item.setFlag(QGraphicsItem.ItemIsMovable, True)
            item.setFlag(QGraphicsItem.ItemIsSelectable, True)
            self.addItem(item)
            item.setPos(alg.position().x(), alg.position().y())
            self.algItems[alg.childId()] = item

        # And then the arrows

        for alg in list(model.childAlgorithms().values()):
            idx = 0
            for parameter in alg.algorithm().parameterDefinitions():
                if not parameter.isDestination() and not parameter.flags(
                ) & QgsProcessingParameterDefinition.FlagHidden:
                    if parameter.name() in alg.parameterSources():
                        sources = alg.parameterSources()[parameter.name()]
                    else:
                        sources = []
                    for source in sources:
                        sourceItems = self.getItemsFromParamValue(
                            source, alg.childId(), context)
                        for sourceItem, sourceIdx in sourceItems:
                            arrow = ModelerArrowItem(
                                sourceItem, sourceIdx,
                                self.algItems[alg.childId()], idx)
                            sourceItem.addArrow(arrow)
                            self.algItems[alg.childId()].addArrow(arrow)
                            arrow.updatePath()
                            self.addItem(arrow)
                        idx += 1
            for depend in alg.dependencies():
                arrow = ModelerArrowItem(self.algItems[depend], -1,
                                         self.algItems[alg.childId()], -1)
                self.algItems[depend].addArrow(arrow)
                self.algItems[alg.childId()].addArrow(arrow)
                arrow.updatePath()
                self.addItem(arrow)

        # And finally the outputs
        for alg in list(model.childAlgorithms().values()):
            outputs = alg.modelOutputs()
            outputItems = {}
            idx = 0
            for key, out in outputs.items():
                if out is not None:
                    item = ModelerGraphicItem(out, model, controls, scene=self)
                    item.setFlag(QGraphicsItem.ItemIsMovable, True)
                    item.setFlag(QGraphicsItem.ItemIsSelectable, True)
                    self.addItem(item)
                    pos = out.position()
                    if pos is None:
                        pos = (alg.position() +
                               QPointF(ModelerGraphicItem.BOX_WIDTH, 0) +
                               self.algItems[
                                   alg.childId()].getLinkPointForOutput(idx))
                    item.setPos(pos)
                    outputItems[key] = item
                    arrow = ModelerArrowItem(self.algItems[alg.childId()], idx,
                                             item, -1)
                    self.algItems[alg.childId()].addArrow(arrow)
                    item.addArrow(arrow)
                    arrow.updatePath()
                    self.addItem(arrow)
                    idx += 1
                else:
                    outputItems[key] = None
            self.outputItems[alg.childId()] = outputItems
예제 #33
0
def ogrConnectionString(uri):
    """Generates OGR connection sting from layer source
    """
    ogrstr = None

    context = dataobjects.createContext()
    layer = QgsProcessingUtils.mapLayerFromString(uri, context, False)
    if layer is None:
        return '"' + uri + '"'
    provider = layer.dataProvider().name()
    if provider == 'spatialite':
        # dbname='/geodata/osm_ch.sqlite' table="places" (Geometry) sql=
        regex = re.compile("dbname='(.+)'")
        r = regex.search(str(layer.source()))
        ogrstr = r.groups()[0]
    elif provider == 'postgres':
        # dbname='ktryjh_iuuqef' host=spacialdb.com port=9999
        # user='******' password='******' sslmode=disable
        # key='gid' estimatedmetadata=true srid=4326 type=MULTIPOLYGON
        # table="t4" (geom) sql=
        dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri())
        conninfo = dsUri.connectionInfo()
        conn = None
        ok = False
        while not conn:
            try:
                conn = psycopg2.connect(dsUri.connectionInfo())
            except psycopg2.OperationalError:
                (ok, user, passwd) = QgsCredentials.instance().get(conninfo, dsUri.username(), dsUri.password())
                if not ok:
                    break

                dsUri.setUsername(user)
                dsUri.setPassword(passwd)

        if not conn:
            raise RuntimeError('Could not connect to PostgreSQL database - check connection info')

        if ok:
            QgsCredentials.instance().put(conninfo, user, passwd)

        ogrstr = "PG:%s" % dsUri.connectionInfo()
    elif provider == "oracle":
        # OCI:user/password@host:port/service:table
        dsUri = QgsDataSourceUri(layer.dataProvider().dataSourceUri())
        ogrstr = "OCI:"
        if dsUri.username() != "":
            ogrstr += dsUri.username()
            if dsUri.password() != "":
                ogrstr += "/" + dsUri.password()
            delim = "@"

        if dsUri.host() != "":
            ogrstr += delim + dsUri.host()
            delim = ""
            if dsUri.port() != "" and dsUri.port() != '1521':
                ogrstr += ":" + dsUri.port()
            ogrstr += "/"
            if dsUri.database() != "":
                ogrstr += dsUri.database()
        elif dsUri.database() != "":
            ogrstr += delim + dsUri.database()

        if ogrstr == "OCI:":
            raise RuntimeError('Invalid oracle data source - check connection info')

        ogrstr += ":"
        if dsUri.schema() != "":
            ogrstr += dsUri.schema() + "."

        ogrstr += dsUri.table()
    else:
        ogrstr = str(layer.source()).split("|")[0]

    return '"' + ogrstr + '"'
예제 #34
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
예제 #35
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 = BatchFeedback(len(alg_parameters), feedback)
        feedback.progressChanged.connect(task.setProgress)

        algorithm_results = []
        errors = []

        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 Exception:  # FIXME which one?
                pass

            start_time = time.time()

            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()
                multi_feedback.errors = []
                results, ok = self.algorithm().run(parameters, context, multi_feedback)
                if ok:
                    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({'parameters': parameters, 'results': results})

                    handleAlgorithmResults(self.algorithm(), context, multi_feedback, False, parameters)
                else:
                    err = [e for e in multi_feedback.errors]
                    self.setInfo(
                        QCoreApplication.translate('BatchAlgorithmDialog', 'Algorithm {0} failed…').format(
                            self.algorithm().displayName()), escapeHtml=False)
                    feedback.reportError(
                        self.tr('Execution failed after {0:0.2f} seconds'.format(time.time() - alg_start_time)),
                        fatalError=False)
                    errors.append({'parameters': parameters, 'errors': err})

        feedback.pushInfo(self.tr('Batch execution completed in {0:0.2f} seconds'.format(time.time() - start_time)))
        if errors:
            feedback.reportError(self.tr('{} executions failed. See log for further details.').format(len(errors)), fatalError=True)
        task = None

        self.finish(algorithm_results, errors)
        self.cancelButton().setEnabled(False)
예제 #36
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)

                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)
예제 #37
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
예제 #38
0
파일: BatchPanel.py 프로젝트: pgab/QGIS
    def save(self):
        toSave = []
        context = dataobjects.createContext()
        for row in range(self.batchRowCount()):
            algParams = {}
            algOutputs = {}
            col = 0
            alg = self.alg
            for param in alg.parameterDefinitions():
                if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
                    continue
                if param.isDestination():
                    continue
                wrapper = self.wrappers[row][col]

                # For compatibility with 3.x API, we need to check whether the wrapper is
                # the deprecated WidgetWrapper class. If not, it's the newer
                # QgsAbstractProcessingParameterWidgetWrapper class
                # TODO QGIS 4.0 - remove
                if issubclass(wrapper.__class__, WidgetWrapper):
                    widget = wrapper.widget
                else:
                    widget = wrapper.wrappedWidget()

                value = wrapper.parameterValue()

                if not param.checkValueIsAcceptable(value, context):
                    self.parent.messageBar().pushMessage("", self.tr(
                        'Wrong or missing parameter value: {0} (row {1})').format(
                        param.description(), row + 1),
                        level=Qgis.Warning, duration=5)
                    return
                algParams[param.name()] = param.valueAsPythonString(value, context)
                col += 1
            for out in alg.destinationParameterDefinitions():
                if out.flags() & QgsProcessingParameterDefinition.FlagHidden:
                    continue
                widget = self.tblParameters.cellWidget(row + 1, col)
                text = widget.getValue()
                if text.strip() != '':
                    algOutputs[out.name()] = text.strip()
                    col += 1
                else:
                    self.parent.messageBar().pushMessage("",
                                                         self.tr('Wrong or missing output value: {0} (row {1})').format(
                                                             out.description(), row + 1),
                                                         level=Qgis.Warning, duration=5)
                    return
            toSave.append({self.PARAMETERS: algParams, self.OUTPUTS: algOutputs})

        settings = QgsSettings()
        last_path = settings.value("/Processing/LastBatchPath", QDir.homePath())
        filename, __ = QFileDialog.getSaveFileName(self,
                                                   self.tr('Save Batch'),
                                                   last_path,
                                                   self.tr('JSON files (*.json)'))
        if filename:
            if not filename.endswith('.json'):
                filename += '.json'
            last_path = QFileInfo(filename).path()
            settings.setValue('/Processing/LastBatchPath', last_path)
            with open(filename, 'w') as f:
                json.dump(toSave, f)
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.context = dataobjects.createContext()
예제 #40
0
def execute_in_place_run(alg,
                         parameters,
                         context=None,
                         feedback=None,
                         raise_exceptions=False):
    """Executes an algorithm modifying features in-place in the input layer.

    :param alg: algorithm to run
    :type alg: QgsProcessingAlgorithm
    :param parameters: parameters of the algorithm
    :type parameters: dict
    :param context: context, defaults to None
    :type context: QgsProcessingContext, optional
    :param feedback: feedback, defaults to None
    :type feedback: QgsProcessingFeedback, optional
    :param raise_exceptions: useful for testing, if True exceptions are raised, normally exceptions will be forwarded to the feedback
    :type raise_exceptions: boo, default to False
    :raises QgsProcessingException: raised when there is no active layer, or it cannot be made editable
    :return: a tuple with true if success and results
    :rtype: tuple
    """

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

    active_layer = parameters['INPUT']

    # Run some checks and prepare the layer for in-place execution by:
    # - getting the active layer and checking that it is a vector
    # - making the layer editable if it was not already
    # - selecting all features if none was selected
    # - checking in-place support for the active layer/alg/parameters
    # If one of the check fails and raise_exceptions is True an exception
    # is raised, else the execution is aborted and the error reported in
    # the feedback
    try:
        if active_layer is None:
            raise QgsProcessingException(tr("There is not active layer."))

        if not isinstance(active_layer, QgsVectorLayer):
            raise QgsProcessingException(
                tr("Active layer is not a vector layer."))

        if not active_layer.isEditable():
            if not active_layer.startEditing():
                raise QgsProcessingException(
                    tr("Active layer is not editable (and editing could not be turned on)."
                       ))

        if not alg.supportInPlaceEdit(active_layer):
            raise QgsProcessingException(
                tr("Selected algorithm and parameter configuration are not compatible with in-place modifications."
                   ))
    except QgsProcessingException as e:
        if raise_exceptions:
            raise e
        QgsMessageLog.logMessage(str(sys.exc_info()[0]), 'Processing',
                                 Qgis.Critical)
        if feedback is not None:
            feedback.reportError(getattr(e, 'msg', str(e)), fatalError=True)
        return False, {}

    if not active_layer.selectedFeatureIds():
        active_layer.selectAll()

    parameters['OUTPUT'] = 'memory:'

    # Start the execution
    # If anything goes wrong and raise_exceptions is True an exception
    # is raised, else the execution is aborted and the error reported in
    # the feedback
    try:
        new_feature_ids = []

        active_layer.beginEditCommand(alg.displayName())

        req = QgsFeatureRequest(QgsExpression(r"$id < 0"))
        req.setFlags(QgsFeatureRequest.NoGeometry)
        req.setSubsetOfAttributes([])

        # Checks whether the algorithm has a processFeature method
        if hasattr(alg, 'processFeature'):  # in-place feature editing
            # Make a clone or it will crash the second time the dialog
            # is opened and run
            alg = alg.create()
            if not alg.prepare(parameters, context, feedback):
                raise QgsProcessingException(
                    tr("Could not prepare selected algorithm."))
            # Check again for compatibility after prepare
            if not alg.supportInPlaceEdit(active_layer):
                raise QgsProcessingException(
                    tr("Selected algorithm and parameter configuration are not compatible with in-place modifications."
                       ))
            field_idxs = range(len(active_layer.fields()))
            feature_iterator = active_layer.getFeatures(
                QgsFeatureRequest(active_layer.selectedFeatureIds()))
            step = 100 / len(active_layer.selectedFeatureIds()
                             ) if active_layer.selectedFeatureIds() else 1
            for current, f in enumerate(feature_iterator):
                feedback.setProgress(current * step)
                if feedback.isCanceled():
                    break

                # need a deep copy, because python processFeature implementations may return
                # a shallow copy from processFeature
                input_feature = QgsFeature(f)
                new_features = alg.processFeature(input_feature, context,
                                                  feedback)
                new_features = QgsVectorLayerUtils.makeFeaturesCompatible(
                    new_features, active_layer)
                if len(new_features) == 0:
                    active_layer.deleteFeature(f.id())
                elif len(new_features) == 1:
                    new_f = new_features[0]
                    if not f.geometry().equals(new_f.geometry()):
                        active_layer.changeGeometry(f.id(), new_f.geometry())
                    if f.attributes() != new_f.attributes():
                        active_layer.changeAttributeValues(
                            f.id(), dict(zip(field_idxs, new_f.attributes())),
                            dict(zip(field_idxs, f.attributes())))
                    new_feature_ids.append(f.id())
                else:
                    active_layer.deleteFeature(f.id())
                    # Get the new ids
                    old_ids = set(
                        [f.id() for f in active_layer.getFeatures(req)])
                    if not active_layer.addFeatures(new_features):
                        raise QgsProcessingException(
                            tr("Error adding processed features back into the layer."
                               ))
                    new_ids = set(
                        [f.id() for f in active_layer.getFeatures(req)])
                    new_feature_ids += list(new_ids - old_ids)

            results, ok = {}, True

        else:  # Traditional 'run' with delete and add features cycle
            results, ok = alg.run(parameters, context, feedback)

            if ok:
                result_layer = QgsProcessingUtils.mapLayerFromString(
                    results['OUTPUT'], context)
                # TODO: check if features have changed before delete/add cycle
                active_layer.deleteFeatures(active_layer.selectedFeatureIds())
                new_features = []
                for f in result_layer.getFeatures():
                    new_features.extend(
                        QgsVectorLayerUtils.makeFeaturesCompatible(
                            [f], active_layer))

                # Get the new ids
                old_ids = set([f.id() for f in active_layer.getFeatures(req)])
                if not active_layer.addFeatures(new_features):
                    raise QgsProcessingException(
                        tr("Error adding processed features back into the layer."
                           ))
                new_ids = set([f.id() for f in active_layer.getFeatures(req)])
                new_feature_ids += list(new_ids - old_ids)

        active_layer.endEditCommand()

        if ok and new_feature_ids:
            active_layer.selectByIds(new_feature_ids)
        elif not ok:
            active_layer.rollBack()

        return ok, results

    except QgsProcessingException as e:
        active_layer.endEditCommand()
        active_layer.rollBack()
        if raise_exceptions:
            raise e
        QgsMessageLog.logMessage(str(sys.exc_info()[0]), 'Processing',
                                 Qgis.Critical)
        if feedback is not None:
            feedback.reportError(getattr(e, 'msg', str(e)), fatalError=True)

    return False, {}
예제 #41
0
    def accept(self):
        super(AlgorithmDialog, self)._saveGeometry()

        context = dataobjects.createContext()

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

            QgsMessageLog.logMessage(str(parameters), 'Processing',
                                     QgsMessageLog.CRITICAL)

            # TODO
            if False and 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)
            #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

            QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

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

            if self.iterateParam:
                if executeIterating(self.alg, parameters, self.iterateParam,
                                    context, self.feedback):
                    self.finish(parameters, context)
                else:
                    QApplication.restoreOverrideCursor()
                    self.resetGUI()
            else:
                # TODO
                #command = self.alg.getAsCommand()
                #if command:
                #    ProcessingLog.addToLog(command)
                self.buttonCancel.setEnabled(
                    self.alg.flags() & QgsProcessingAlgorithm.FlagCanCancel)
                result = executeAlgorithm(self.alg, parameters, context,
                                          self.feedback)
                self.buttonCancel.setEnabled(False)
                self.finish(result, context)
                #TODO
                #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)
예제 #42
0
def execute_in_place_run(alg, parameters, context=None, feedback=None, raise_exceptions=False):
    """Executes an algorithm modifying features in-place in the input layer.

    :param alg: algorithm to run
    :type alg: QgsProcessingAlgorithm
    :param parameters: parameters of the algorithm
    :type parameters: dict
    :param context: context, defaults to None
    :type context: QgsProcessingContext, optional
    :param feedback: feedback, defaults to None
    :type feedback: QgsProcessingFeedback, optional
    :param raise_exceptions: useful for testing, if True exceptions are raised, normally exceptions will be forwarded to the feedback
    :type raise_exceptions: boo, default to False
    :raises QgsProcessingException: raised when there is no active layer, or it cannot be made editable
    :return: a tuple with true if success and results
    :rtype: tuple
    """

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

    # Only feature based algs have sourceFlags
    try:
        if alg.sourceFlags() & QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks:
            context.setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck)
    except AttributeError:
        pass

    in_place_input_parameter_name = 'INPUT'
    if hasattr(alg, 'inputParameterName'):
        in_place_input_parameter_name = alg.inputParameterName()

    active_layer = parameters[in_place_input_parameter_name]

    # prepare expression context for feature iteration
    alg_context = context.expressionContext()
    alg_context.appendScope(active_layer.createExpressionContextScope())
    context.setExpressionContext(alg_context)

    # Run some checks and prepare the layer for in-place execution by:
    # - getting the active layer and checking that it is a vector
    # - making the layer editable if it was not already
    # - selecting all features if none was selected
    # - checking in-place support for the active layer/alg/parameters
    # If one of the check fails and raise_exceptions is True an exception
    # is raised, else the execution is aborted and the error reported in
    # the feedback
    try:
        if active_layer is None:
            raise QgsProcessingException(tr("There is no active layer."))

        if not isinstance(active_layer, QgsVectorLayer):
            raise QgsProcessingException(tr("Active layer is not a vector layer."))

        if not active_layer.isEditable():
            if not active_layer.startEditing():
                raise QgsProcessingException(tr("Active layer is not editable (and editing could not be turned on)."))

        if not alg.supportInPlaceEdit(active_layer):
            raise QgsProcessingException(tr("Selected algorithm and parameter configuration are not compatible with in-place modifications."))
    except QgsProcessingException as e:
        if raise_exceptions:
            raise e
        QgsMessageLog.logMessage(str(sys.exc_info()[0]), 'Processing', Qgis.Critical)
        if feedback is not None:
            feedback.reportError(getattr(e, 'msg', str(e)), fatalError=True)
        return False, {}

    if not active_layer.selectedFeatureIds():
        active_layer.selectAll()

    # Make sure we are working on selected features only
    parameters[in_place_input_parameter_name] = QgsProcessingFeatureSourceDefinition(active_layer.id(), True)
    parameters['OUTPUT'] = 'memory:'

    req = QgsFeatureRequest(QgsExpression(r"$id < 0"))
    req.setFlags(QgsFeatureRequest.NoGeometry)
    req.setSubsetOfAttributes([])

    # Start the execution
    # If anything goes wrong and raise_exceptions is True an exception
    # is raised, else the execution is aborted and the error reported in
    # the feedback
    try:
        new_feature_ids = []

        active_layer.beginEditCommand(alg.displayName())

        # Checks whether the algorithm has a processFeature method
        if hasattr(alg, 'processFeature'):  # in-place feature editing
            # Make a clone or it will crash the second time the dialog
            # is opened and run
            alg = alg.create({'IN_PLACE': True})
            if not alg.prepare(parameters, context, feedback):
                raise QgsProcessingException(tr("Could not prepare selected algorithm."))
            # Check again for compatibility after prepare
            if not alg.supportInPlaceEdit(active_layer):
                raise QgsProcessingException(tr("Selected algorithm and parameter configuration are not compatible with in-place modifications."))

            # some algorithms have logic in outputFields/outputCrs/outputWkbType which they require to execute before
            # they can start processing features
            _ = alg.outputFields(active_layer.fields())
            _ = alg.outputWkbType(active_layer.wkbType())
            _ = alg.outputCrs(active_layer.crs())

            field_idxs = range(len(active_layer.fields()))
            iterator_req = QgsFeatureRequest(active_layer.selectedFeatureIds())
            iterator_req.setInvalidGeometryCheck(context.invalidGeometryCheck())
            feature_iterator = active_layer.getFeatures(iterator_req)
            step = 100 / len(active_layer.selectedFeatureIds()) if active_layer.selectedFeatureIds() else 1
            current = 0
            for current, f in enumerate(feature_iterator):
                if feedback.isCanceled():
                    break

                # need a deep copy, because python processFeature implementations may return
                # a shallow copy from processFeature
                input_feature = QgsFeature(f)

                context.expressionContext().setFeature(input_feature)

                new_features = alg.processFeature(input_feature, context, feedback)
                new_features = QgsVectorLayerUtils.makeFeaturesCompatible(new_features, active_layer)

                if len(new_features) == 0:
                    active_layer.deleteFeature(f.id())
                elif len(new_features) == 1:
                    new_f = new_features[0]
                    if not f.geometry().equals(new_f.geometry()):
                        active_layer.changeGeometry(f.id(), new_f.geometry())
                    if f.attributes() != new_f.attributes():
                        active_layer.changeAttributeValues(f.id(), dict(zip(field_idxs, new_f.attributes())), dict(zip(field_idxs, f.attributes())))
                    new_feature_ids.append(f.id())
                else:
                    active_layer.deleteFeature(f.id())
                    # Get the new ids
                    old_ids = set([f.id() for f in active_layer.getFeatures(req)])
                    # If multiple new features were created, we need to pass
                    # them to createFeatures to manage constraints correctly
                    features_data = []
                    for f in new_features:
                        features_data.append(QgsVectorLayerUtils.QgsFeatureData(f.geometry(), dict(enumerate(f.attributes()))))
                    new_features = QgsVectorLayerUtils.createFeatures(active_layer, features_data, context.expressionContext())
                    if not active_layer.addFeatures(new_features):
                        raise QgsProcessingException(tr("Error adding processed features back into the layer."))
                    new_ids = set([f.id() for f in active_layer.getFeatures(req)])
                    new_feature_ids += list(new_ids - old_ids)

                feedback.setProgress(int((current + 1) * step))

            results, ok = {'__count': current + 1}, True

        else:  # Traditional 'run' with delete and add features cycle

            # There is no way to know if some features have been skipped
            # due to invalid geometries
            if context.invalidGeometryCheck() == QgsFeatureRequest.GeometrySkipInvalid:
                selected_ids = active_layer.selectedFeatureIds()
            else:
                selected_ids = []

            results, ok = alg.run(parameters, context, feedback, configuration={'IN_PLACE': True})

            if ok:
                result_layer = QgsProcessingUtils.mapLayerFromString(results['OUTPUT'], context)
                # TODO: check if features have changed before delete/add cycle

                new_features = []

                # Check if there are any skipped features
                if context.invalidGeometryCheck() == QgsFeatureRequest.GeometrySkipInvalid:
                    missing_ids = list(set(selected_ids) - set(result_layer.allFeatureIds()))
                    if missing_ids:
                        for f in active_layer.getFeatures(QgsFeatureRequest(missing_ids)):
                            if not f.geometry().isGeosValid():
                                new_features.append(f)

                active_layer.deleteFeatures(active_layer.selectedFeatureIds())

                regenerate_primary_key = result_layer.customProperty('OnConvertFormatRegeneratePrimaryKey', False)
                sink_flags = QgsFeatureSink.SinkFlags(QgsFeatureSink.RegeneratePrimaryKey) if regenerate_primary_key \
                    else QgsFeatureSink.SinkFlags()

                for f in result_layer.getFeatures():
                    new_features.extend(QgsVectorLayerUtils.
                                        makeFeaturesCompatible([f], active_layer, sink_flags))

                # Get the new ids
                old_ids = set([f.id() for f in active_layer.getFeatures(req)])
                if not active_layer.addFeatures(new_features):
                    raise QgsProcessingException(tr("Error adding processed features back into the layer."))
                new_ids = set([f.id() for f in active_layer.getFeatures(req)])
                new_feature_ids += list(new_ids - old_ids)
                results['__count'] = len(new_feature_ids)

        active_layer.endEditCommand()

        if ok and new_feature_ids:
            active_layer.selectByIds(new_feature_ids)
        elif not ok:
            active_layer.rollBack()

        return ok, results

    except QgsProcessingException as e:
        active_layer.endEditCommand()
        active_layer.rollBack()
        if raise_exceptions:
            raise e
        QgsMessageLog.logMessage(str(sys.exc_info()[0]), 'Processing', Qgis.Critical)
        if feedback is not None:
            feedback.reportError(getattr(e, 'msg', str(e)), fatalError=True)

    return False, {}
예제 #43
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:'))
            display_params = []
            for k, v in parameters.items():
                display_params.append("'" + k + "' : " +
                                      self.alg.parameterDefinition(
                                          k).valueAsPythonString(v, context))
            feedback.pushCommandInfo('{ ' + ', '.join(display_params) + ' }')
            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)
예제 #44
0
    def getParameterValues(self):
        parameters = {}

        if self.mainWidget() is None:
            return parameters

        for param in self.algorithm().parameterDefinitions():
            if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
                continue
            if not param.isDestination():

                if self.in_place and param.name() == 'INPUT':
                    parameters[param.name()] = self.active_layer
                    continue

                try:
                    wrapper = self.mainWidget().wrappers[param.name()]
                except KeyError:
                    continue

                # For compatibility with 3.x API, we need to check whether the wrapper is
                # the deprecated WidgetWrapper class. If not, it's the newer
                # QgsAbstractProcessingParameterWidgetWrapper class
                # TODO QGIS 4.0 - remove
                if issubclass(wrapper.__class__, WidgetWrapper):
                    widget = wrapper.widget
                else:
                    widget = wrapper.wrappedWidget()

                if widget is None:
                    continue

                value = wrapper.parameterValue()
                parameters[param.name()] = value

                if not param.checkValueIsAcceptable(value):
                    raise AlgorithmDialogBase.InvalidParameterValue(
                        param, widget)
            else:
                if self.in_place and param.name() == 'OUTPUT':
                    parameters[param.name()] = 'memory:'
                    continue

                dest_project = None
                if not param.flags() & QgsProcessingParameterDefinition.FlagHidden and \
                        isinstance(param, (QgsProcessingParameterRasterDestination,
                                           QgsProcessingParameterFeatureSink,
                                           QgsProcessingParameterVectorDestination)):
                    if self.mainWidget().checkBoxes[param.name()].isChecked():
                        dest_project = QgsProject.instance()

                widget = self.mainWidget().outputWidgets[param.name()]
                value = widget.getValue()

                if value and isinstance(value,
                                        QgsProcessingOutputLayerDefinition):
                    value.destinationProject = dest_project
                if value:
                    parameters[param.name()] = value
                    if param.isDestination():
                        context = dataobjects.createContext()
                        ok, error = self.algorithm().provider(
                        ).isSupportedOutputValue(value, param, context)
                        if not ok:
                            raise AlgorithmDialogBase.InvalidOutputExtension(
                                widget, error)

        return self.algorithm().preprocessParameters(parameters)
예제 #45
0
def rasterize_vectors_and_load_to_db(
    grassdb,
    grass_location,
    qgis_prefix_path,
    mask,
    vector_path,
    attribue_name,
    raster_name,
):

    QgsApplication.setPrefixPath(qgis_prefix_path, True)
    Qgs = QgsApplication([], False)
    Qgs.initQgis()
    from processing.core.Processing import Processing
    from processing.tools import dataobjects
    from qgis import processing

    feedback = QgsProcessingFeedback()
    Processing.initialize()
    QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
    context = dataobjects.createContext()
    context.setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck)

    mask_layer = qgis_raster_read_raster(
        processing, os.path.join(grassdb, mask + ".tif")
    )  ### load DEM raster as a  QGIS raster object to obtain attribute
    cellSize, SpRef_in = qgis_raster_return_raster_properties(
        processing, mask_layer)  ### Get Raster cell size

    # load grass working location
    import grass.script as grass
    import grass.script.setup as gsetup
    from grass.pygrass.modules import Module
    from grass.pygrass.modules.shortcuts import general as g
    from grass.pygrass.modules.shortcuts import raster as r
    from grass.script import array as garray
    from grass.script import core as gcore
    from grass_session import Session

    os.environ.update(
        dict(GRASS_COMPRESS_NULLS="1",
             GRASS_COMPRESSOR="ZSTD",
             GRASS_VERBOSE="1"))
    PERMANENT = Session()
    PERMANENT.open(gisdb=grassdb, location=grass_location, create_opts="")

    # get dem array and get nrows and ncols of the domain
    strtemp_array = Return_Raster_As_Array_With_garray(garray, mask)
    ncols = int(strtemp_array.shape[1])
    nrows = int(strtemp_array.shape[0])
    grsregion = gcore.region()

    qgis_raster_gdal_rasterize(
        processing,
        context,
        INPUT=vector_path,
        Column_nm=attribue_name,
        cellsize=cellSize,
        w=grsregion["w"],
        s=grsregion["s"],
        e=grsregion["e"],
        n=grsregion["n"],
        OUTPUT=os.path.join(grassdb, raster_name + ".tif"),
    )

    grass_raster_r_in_gdal(
        grass,
        raster_path=os.path.join(grassdb, raster_name + ".tif"),
        output_nm=raster_name,
    )

    grass_raster_setnull(grass,
                         raster_nm=raster_name,
                         null_values=[-9999],
                         create_new_raster=False)

    grass_raster_v_import(grass,
                          input_path=vector_path,
                          output_vector_nm=raster_name)
    Qgs.exit()
    PERMANENT.close()
예제 #46
0
 def __init__(self, param, dialog, row=0, col=0, **kwargs):
     super().__init__(param, dialog, row, col, **kwargs)
     self.context = dataobjects.createContext()
예제 #47
0
    def runAlgorithm(self):
        self.feedback = self.createFeedback()
        self.context = dataobjects.createContext(self.feedback)

        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()

            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:'))
                        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('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)

                    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)
예제 #48
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
예제 #49
0
    def processAlgorithm(self, parameters, context, feedback):
        """
        Here is where the processing itself takes place.
        """

        feedback.pushInfo("\nDébut du processus\n")

        # unité de sondage
        path_us = self.parameterAsVectorLayer(parameters, self.UniteSondage,
                                              context)

        # numéro de l'unité de sondage
        us = self.parameterAsString(parameters, self.uniteSondage, context)

        # Parametres Dossier Intrants
        wd_intrants = self.parameterAsString(parameters, self.DossierIntrants,
                                             context)

        feedback.pushInfo(
            "\nVous traité l'unité de sondage : {0}\n".format(us))

        # Permet d'ignorer les erreurs de geometries
        noCheckGeom = dataobjects.createContext()
        noCheckGeom.setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck)

        # Construction de l'environnement d'exécution d'ArcGIS
        # Nécessaire car l'environnement de QGIS engendre des conflits
        arcgis_env = {}
        arcgis_env['SYSTEMROOT'] = os.environ['SYSTEMROOT']
        arcgis_env['AGSDESKTOPJAVA'] = os.path.join(
            os.environ['AGSDESKTOPJAVA'], 'bin')
        arcgis_env['USERPROFILE'] = os.environ['USERPROFILE']

        # Liste des intrants sur le réseau (DDE et autres)

        # path_PeupForestiers_reseau =

        path_PentesNum_reseau = r"\\vulcain\raigeop\Depot_Dde\Catalogue_du_systeme_DDE\Couches_de_donnees\
                                Classe_de_pente_numerique\CLASSES_DE_PENTE_NUMERIQUE_S\FGDB_GEO\CPN_PROV\CPN_PROV.gdb|layername=CPN_PROV"

        path_HydroLin_reseau = r"\\vulcain\raigeop\Depot_Dde\Catalogue_du_systeme_DDE\Couches_de_donnees\Reference_geographique_Quebec\
                                BDTQ_20K_a_jour\HYDROGRAPHIE_LINEAIRE_BDTQ_20K_L\FGDB_GEO\HL20_PROV\HL20_PROV.gdb|layername=BDTQ_20K_HYDRO_LO"

        path_VoieFerree_reseau = r"\\vulcain\raigeop\Depot_Dde\Catalogue_du_systeme_DDE\Couches_de_donnees\Reference_geographique_Quebec\
                                BDTQ_20K_a_jour\VOIE_COMM_LINEAIRE_BDTQ_20K_L\FGDB_GEO\VCL_BDTQ_20K\VCL_BDTQ_20K.gdb|layername=BDTQ_20K_VOIE_COMMU_LO"

        path_PEP_reseau = r"\\vulcain\raigeop\Depot_Dde\Produits_IEQM\Placettes_echantillons\PEP.gpkg|layername=df_placettes_metadata_PeupForestiers_US"

        path_ponc_reseau = r"\\vulcain\raigeop\Depot_Dde\Catalogue_du_systeme_DDE\Couches_de_donnees\Reference_geographique_Quebec\
                                BDTQ_20K_a_jour\BATIMENT_PONCTUEL_BDTQ_20K_P\FGDB_GEO\BATP_PROV\BATP_PROV.gdb|layername=BDTQ_20K_BATIM_PO"

        path_BatiLin_reseau = r"\\vulcain\raigeop\Depot_Dde\Catalogue_du_systeme_DDE\Couches_de_donnees\Reference_geographique_Quebec\
                                BDTQ_20K_a_jour\BATIMENT_LINEAIRE_BDTQ_20K_L\FGDB_GEO\BATL_PROV\BATL_PROV.gdb|layername=BDTQ_20K_BATIM_LO"

        path_BatiSur_reseau = r"\\vulcain\raigeop\Depot_Dde\Catalogue_du_systeme_DDE\Couches_de_donnees\Reference_geographique_Quebec\
                                BDTQ_20K_a_jour\BATIMENT_SURFACIQUE_BDTQ_20K_S\FGDB_GEO\BATS_PROV\BATS_PROV.gdb|layername=BDTQ_20K_BATIM_SO"

        path_EquipPonc_reseau = r"\\vulcain\raigeop\Depot_Dde\Catalogue_du_systeme_DDE\Couches_de_donnees\Reference_geographique_Quebec\
                                BDTQ_20K_a_jour\EQUIPEMENT_PONCTUEL_BDTQ_20K_P\FGDB_GEO\EQP_PROV\EQP_PROV.gdb|layername=BDTQ_20K_EQUIP_PO"

        path_EquipLin_reseau = r"\\vulcain\raigeop\Depot_Dde\Catalogue_du_systeme_DDE\Couches_de_donnees\Reference_geographique_Quebec\
                                BDTQ_20K_a_jour\EQUIPEMENT_LINEAIRE_BDTQ_20K_L\FGDB_GEO\EQL_PROV\EQL_PROV.gdb|layername=BDTQ_20K_EQUIP_LO"

        path_EquipSur_reseau = r"\\vulcain\raigeop\Depot_Dde\Catalogue_du_systeme_DDE\Couches_de_donnees\Reference_geographique_Quebec\
                                BDTQ_20K_a_jour\EQUIPEMENT_SURFACIQUE_BDTQ_20K_S\FGDB_GEO\EQS_PROV\EQS_PROV.gdb|layername=BDTQ_20K_EQUIP_SO"

        path_AffecPonc_reseau = r"\\vulcain\raigeop\Depot_Dde\Catalogue_du_systeme_DDE\Couches_de_donnees\Utilisation_du_territoire\
                                Usage_forestier\USAGE_FORESTIER_PONCTUEL_P\FGDB_CCL\UFP_PROV\UFP_PROV.gdb|layername=DDE_UFZ_USAGE_FORES_VUE_P"

        path_AffecLin_reseau = r"\\vulcain\raigeop\Depot_Dde\Catalogue_du_systeme_DDE\Couches_de_donnees\Utilisation_du_territoire\
                                Usage_forestier\USAGE_FORESTIER_LINEAIRE_L\FGDB_CCL\UFL_PROV\UFL_PROV.gdb|layername=DDE_UFZ_USAGE_FORES_VUE_L"

        # path_Feux_reseau=
        # path_PertMaj_reseau=

        # path_Interv_reseau=
        # path_Planif_reseau=

        # #Ce sont des intrants préparés hors de l'outil
        # path_us             = os.path.join(wd_intrants, "US_{0}.shp".format(us))  #Robin
        # path_ParamBuffers   = os.path.join(wd_intrants,  "Parametres", "BUFFER_template.csv")# SONDAGE
        # path_chemins        = os.path.join(wd_intrants, "CHEMIN_SONAR_{0}.shp".format(us)) # SONDAGE
        # path_geocodes       = os.path.join(wd_intrants, "LIST_GEOC_{0}.shp".format(us)) # PHILIPPE MORIN
        # path_masque         = os.path.join(wd_intrants, "MASQUE_{0}.shp".format(us))# SONDAGE
        # path_SIP            = os.path.join(wd_intrants, "CFETBFEC_08664_SIP.shp")# Pour l'intant on laisse desactivé

        # Liste des intrant local (gpkg)
        # gpkg des intrants
        gpkg = os.path.join(wd_intrants, "SONAR2_Intrants.gpkg")

        path_PeupForestiers = 'ogr:dbname=\'{0}\' table=\"DDE_20K_PEU_FOR_ORI_TRV_VUE_SE_{1}\" (geom) sql='.format(
            gpkg, us)  #OUTIL
        path_PentesNum = 'ogr:dbname=\'{0}\' table=\"DDE_20K_CLA_PEN_VUE_SE_{1}\" (geom) sql='.format(
            gpkg, us)  #OUTIL
        path_HydroLin = 'ogr:dbname=\'{0}\' table=\"BDTQ_20K_HYDRO_LO_{1}\" (geom) sql='.format(
            gpkg, us)  #OUTIL
        path_VoieFerree = 'ogr:dbname=\'{0}\' table=\"BDTQ_20K_VOIE_COMMU_LO_{1}\" (geom) sql='.format(
            gpkg, us)  #OUTIL
        path_PEP = 'ogr:dbname=\'{0}\' table=\"DDE_20K_PEP_VUE_PE_{1}\" (geom) sql='.format(
            gpkg, us)  #OUTIL
        path_ponc = 'ogr:dbname=\'{0}\' table=\"BDTQ_20K_BATIM_PO_{1}\" (geom) sql='.format(
            gpkg, us)  #OUTIL
        path_BatiLin = 'ogr:dbname=\'{0}\' table=\"BDTQ_20K_BATIM_LO_{1}\" (geom) sql='.format(
            gpkg, us)  #OUTIL
        path_BatiSur = 'ogr:dbname=\'{0}\' table=\"BDTQ_20K_BATIM_SO_{1}\" (geom) sql='.format(
            gpkg, us)  #OUTIL
        path_EquipPonc = 'ogr:dbname=\'{0}\' table=\"BDTQ_20K_EQUIP_PO_{1}\" (geom) sql='.format(
            gpkg, us)  #OUTIL
        path_EquipLin = 'ogr:dbname=\'{0}\' table=\"BDTQ_20K_EQUIP_LO_{1}\" (geom) sql='.format(
            gpkg, us)  #OUTIL
        path_EquipSur = 'ogr:dbname=\'{0}\' table=\"BDTQ_20K_EQUIP_SO_{1}\" (geom) sql='.format(
            gpkg, us)  #OUTIL
        path_AffecPonc = 'ogr:dbname=\'{0}\' table=\"DDE_UFZ_20K_USAGE_FOR_VUE_PE_{1}\" (geom) sql='.format(
            gpkg, us)  #OUTIL
        path_AffecLin = 'ogr:dbname=\'{0}\' table=\"DDE_UFZ_20K_USAGE_FOR_VUE_LE_{1}\" (geom) sql='.format(
            gpkg, us)  #OUTIL
        path_Feux = 'ogr:dbname=\'{0}\' table=\"DDE_20K_FEUX_MAJ_TRV_{1}\" (geom) sql='.format(
            gpkg, us)  #OUTIL
        path_PertMaj = 'ogr:dbname=\'{0}\' table=\"DDE_20K_AUTRE_PERTU_MAJ_TRV_{1}\" (geom) sql='.format(
            gpkg, us)  #OUTIL
        path_Interv = 'ogr:dbname=\'{0}\' table=\"INTERVENTION_{1}\" (geom) sql='.format(
            gpkg, us)  #YVAN
        path_Planif = 'ogr:dbname=\'{0}\' table=\"PLAN_{1}\" (geom) sql='.format(
            gpkg, us)  #YVAN
        path_BufferIn = 'ogr:dbname=\'{0}\' table=\"us_bufin_{1}_2025m\" (geom) sql='.format(
            gpkg, us)  #OUTIL

        # couches intermediaires
        path_us_dissolve = '{0}|layername=us_dissolve'.format(gpkg)
        path_us_buf_2km = 'ogr:dbname=\'{0}\' table=\"us_buf_2km_{1}\" (geom) sql='.format(
            gpkg, us)

        # copie l'us dans le geopackage
        # Copie des peuplement dans le GPKG
        us_gpkg = 'us'
        copyCeToGpkg(path_us, gpkg, us_gpkg)

        # faire un dissolve de l'US
        dissolvedGeopandasGPKG(gpkg, us_gpkg, 'us_dissolve', fields=None)

        # faire un dissolve arcpy
        # si je fais le dissolve avec arpy path_us ser le suivant:
        # path_us = '{0}'.format(gpkg)+"/"+'us'
        # path_us = r"E:\ADG\SONAR\1415CE\Intrants\US_1415CE.shp"

        # basepath = os.path.dirname(os.path.realpath(__file__))
        # path_arpyPy = os.path.join(basepath, 'Arcpy_Dissolve_SONAR2.py {}'.format(path_us))
        #
        #
        # # Paramètres pour éviter que les appels subprocess.run()
        # # n'ouvrent une fenêtre dérangeant l'utilisateur
        # startupinfo = subprocess.STARTUPINFO()
        # startupinfo.dwFlags = subprocess.STARTF_USESHOWWINDOW
        # startupinfo.wShowWindow = 7
        #
        # subprocess.run(r"C:\Mrnmicro\Applic\python27\ArcGIS10.3\python.exe"+" "+ path_arpyPy, env=arcgis_env, startupinfo=startupinfo)
        #
        # dissolve_us = r"C:\MrnMicro\temp\dissolve.shp"

        # supprimer les trous
        # je fais cette étape si je fais le dissolve avec GEOPANDAS
        # clean_us = processing.run("native:deleteholes", {'INPUT':path_us_dissolve,'MIN_AREA':0,
        #                                                  'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT})["OUTPUT"]

        # faire la couche path_BufferIn
        buff_25 = processing.run(
            "native:buffer", {
                'INPUT': dissolve_us,
                'DISTANCE': -25,
                'SEGMENTS': 5,
                'END_CAP_STYLE': 0,
                'JOIN_STYLE': 0,
                'MITER_LIMIT': 2,
                'DISSOLVE': False,
                'OUTPUT': QgsProcessing.TEMPORARY_OUTPUT
            })["OUTPUT"]

        # faire la différence avec l'us et lbuffer interne de 25 m
        processing.run("native:difference", {
            'INPUT': dissolve_us,
            'OVERLAY': buff_25,
            'OUTPUT': path_BufferIn
        })

        # faire un buffer de 2000m de l'US
        # Si GEOPANADS
        # processing.run("native:buffer", {'INPUT':clean_us,'DISTANCE':2000,'SEGMENTS':5,'END_CAP_STYLE':0,'JOIN_STYLE':0,'MITER_LIMIT':2,
        #                                  'DISSOLVE':False,'OUTPUT':path_us_buf_2km})

        processing.run(
            "native:buffer", {
                'INPUT': dissolve_us,
                'DISTANCE': 2000,
                'SEGMENTS': 5,
                'END_CAP_STYLE': 0,
                'JOIN_STYLE': 0,
                'MITER_LIMIT': 2,
                'DISSOLVE': False,
                'OUTPUT': path_us_buf_2km
            })

        # Faire les différents clip

        return {self.uniteSondage: us}
예제 #50
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)):
                        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
예제 #51
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()
예제 #52
0
    def createProcessingParameters(self, flags=QgsProcessingParametersGenerator.Flags()):
        include_default = not (flags & QgsProcessingParametersGenerator.Flag.SkipDefaultValueParameters)
        parameters = {}
        for p, v in self.extra_parameters.items():
            parameters[p] = v

        for param in self.algorithm().parameterDefinitions():
            if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
                continue
            if not param.isDestination():
                try:
                    wrapper = self.wrappers[param.name()]
                except KeyError:
                    continue

                # For compatibility with 3.x API, we need to check whether the wrapper is
                # the deprecated WidgetWrapper class. If not, it's the newer
                # QgsAbstractProcessingParameterWidgetWrapper class
                # TODO QGIS 4.0 - remove
                if issubclass(wrapper.__class__, WidgetWrapper):
                    widget = wrapper.widget
                else:
                    widget = wrapper.wrappedWidget()

                if not isinstance(wrapper, QgsProcessingHiddenWidgetWrapper) and widget is None:
                    continue

                value = wrapper.parameterValue()
                if param.defaultValue() != value or include_default:
                    parameters[param.name()] = value

                if not param.checkValueIsAcceptable(value):
                    raise AlgorithmDialogBase.InvalidParameterValue(param, widget)
            else:
                if self.in_place and param.name() == 'OUTPUT':
                    parameters[param.name()] = 'memory:'
                    continue

                try:
                    wrapper = self.wrappers[param.name()]
                except KeyError:
                    continue

                widget = wrapper.wrappedWidget()
                value = wrapper.parameterValue()

                dest_project = None
                if wrapper.customProperties().get('OPEN_AFTER_RUNNING'):
                    dest_project = QgsProject.instance()

                if value and isinstance(value, QgsProcessingOutputLayerDefinition):
                    value.destinationProject = dest_project
                if value and (param.defaultValue() != value or include_default):
                    parameters[param.name()] = value

                    context = createContext()
                    ok, error = param.isSupportedOutputValue(value, context)
                    if not ok:
                        raise AlgorithmDialogBase.InvalidOutputExtension(widget, error)

        return self.algorithm().preprocessParameters(parameters)
예제 #53
0
 def setLayer(self, layer):
     context = dataobjects.createContext()
     if isinstance(layer, str):
         layer = QgsProcessingUtils.mapLayerFromString(_resolveLayers(layer), context)
     self.widget.setLayer(layer)
예제 #54
0
if args.value5 and args.value5.startswith("["):
    args.value5 = args.value5[1:-1].split(',')
if args.value6 and args.value6.startswith("["):
    args.value6 = args.value6[1:-1].split(',')
if args.value7 and args.value7.startswith("["):
    args.value7 = args.value7[1:-1].split(',')
if args.value8 and args.value8.startswith("["):
    args.value8 = args.value8[1:-1].split(',')
if args.value9 and args.value9.startswith("["):
    args.value9 = args.value9[1:-1].split(',')
if args.value10 and args.value10.startswith("["):
    args.value10 = args.value10[1:-1].split(',')

params = {
    args.param1: args.value1,
    args.param2: args.value2,
    args.param3: args.value3,
    args.param4: args.value4,
    args.param5: args.value5,
    args.param6: args.value6,
    args.param7: args.value7,
    args.param8: args.value8,
    args.param9: args.value9,
    args.param10: args.value10
}
# print(args.value1)
# print(params)
context = dataobjects.createContext()
context.setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck)
res = processing.run(args.alg, params, context=context)
예제 #55
0
def Locate_subid_needsbyuser_qgis(Path_Points="#",
                                  Gauge_NMS="#",
                                  Path_products="#",
                                  qgis_prefix_path="#"):
    """Get Subbasin Ids

    Function that used to obtain subbasin ID of certain gauge.
    or subbasin ID of the polygon that includes the given point
    shapefile.

    Parameters
    ----------
    Path_Points      : string (Optional)
        It is the path of the point shapefile. If the point shapefile is
        provided. The function will return subids of those catchment
        polygons that includes these point in the point shapefile

    Gauge_NMS        : list
        Name of the streamflow gauges, such as ['09PC019'], if the gauge
        name is provided, the subbasin ID that contain this gauge will be
        returned
    Path_products    : string
        The path of the subbasin polygon shapefile.
        The shapefile should at least contains following columns
        ##############Subbasin related attributes###########################
        SubID           - integer, The subbasin Id
        DowSubId        - integer, The downstream subbasin ID of this
                                   subbasin
        Obs_NM          - The streamflow obervation gauge name.

    Notes
    -------
    Path_Points or Gauge_NMS should only provide one each time
    to use this function

    Returns:
    -------
    SubId_Selected  : list
        It is a list contains the selected subid based on provided
        streamflow gauge name or provided point shapefile

    Examples
    -------

    """

    tempfolder = os.path.join(
        tempfile.gettempdir(),
        "basinmaker_locsubid" + str(np.random.randint(1, 10000 + 1)),
    )
    if not os.path.exists(tempfolder):
        os.makedirs(tempfolder)

    # obtain subbasin ID based on either points or guage names
    QgsApplication.setPrefixPath(qgis_prefix_path, True)
    Qgs = QgsApplication([], False)
    Qgs.initQgis()
    from processing.core.Processing import Processing
    from processing.tools import dataobjects
    from qgis import processing

    feedback = QgsProcessingFeedback()
    Processing.initialize()
    QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
    context = dataobjects.createContext()
    context.setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck)

    SubId_Selected = -1
    if Gauge_NMS[0] != "#":
        hyinfocsv = Path_products[:-3] + "dbf"
        tempinfo = Dbf5(hyinfocsv)
        hyshdinfo2 = tempinfo.to_dataframe().drop_duplicates("SubId",
                                                             keep="first")
        hyshdinfo2 = hyshdinfo2.loc[hyshdinfo2["Obs_NM"] != "-9999.0"]
        hyshdinfo2 = hyshdinfo2.loc[hyshdinfo2["Obs_NM"].isin(Gauge_NMS)]
        hyshdinfo2 = hyshdinfo2[["Obs_NM", "SubId"]]
        #            hyshdinfo2.to_csv(os.path.join(self.OutputFolder,'SubIds_Selected.csv'),sep=',', index = None)
        SubId_Selected = hyshdinfo2["SubId"].values

    if Path_Points != "#":
        vector_layer = qgis_vector_read_vector(processing, context,
                                               Path_products)
        SpRef_in = qgis_vector_return_crs_id(processing, context, vector_layer)

        qgis_vector_reproject_layers(
            processing,
            context,
            INPUT=Path_Points,
            TARGET_CRS=SpRef_in,
            OUTPUT=os.path.join(tempfolder, "Obspoint_project2.shp"),
        )

        qgis_vector_add_polygon_attribute_to_points(
            processing,
            context,
            INPUT_Layer=os.path.join(tempfolder, "Obspoint_project2.shp"),
            POLYGONS=Path_products,
            FIELDS="SubId",
            OUTPUT=os.path.join(tempfolder, "Sub_Selected_by_Points.shp"),
        )

        hyshdinfo2 = Dbf_To_Dataframe(
            os.path.join(tempfolder, "Sub_Selected_by_Points.shp"))
        SubId_Selected = hyshdinfo2["SubId"].values
        SubId_Selected = SubId_Selected[SubId_Selected > 0]

    Qgs.exit()

    return SubId_Selected
예제 #56
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()
예제 #57
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('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, 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)

            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)
                QgsGui.instance().processingRecentAlgorithmLog().push(
                    self.algorithm().id())
                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)
def calculate_basic_attributes(
    grassdb,
    grass_location,
    qgis_prefix_path,
    input_geo_names,
    projection,
    catinfo,
    cat_ply_info,
    cat_riv_info,
    outlet_pt_info,
):

    catchments = input_geo_names["catchment_without_merging_lakes"]
    river_r = input_geo_names["river_without_merging_lakes"]
    river_v = input_geo_names["str_v"]
    dem = input_geo_names["dem"]
    fdr = input_geo_names["nfdr_grass"]
    acc = input_geo_names["acc"]
    cat_use_default_acc = input_geo_names["cat_use_default_acc"]
    problem_seg = input_geo_names["problem_seg"]
    nfdr_arcgis = input_geo_names["nfdr_arcgis"]

    import grass.script as grass
    import grass.script.setup as gsetup
    from grass.pygrass.modules import Module
    from grass.pygrass.modules.shortcuts import general as g
    from grass.pygrass.modules.shortcuts import raster as r
    from grass.script import array as garray
    from grass.script import core as gcore
    from grass_session import Session

    QgsApplication.setPrefixPath(qgis_prefix_path, True)
    Qgs = QgsApplication([], False)
    Qgs.initQgis()
    from processing.core.Processing import Processing
    from processing.tools import dataobjects
    from qgis import processing

    feedback = QgsProcessingFeedback()
    Processing.initialize()
    QgsApplication.processingRegistry().addProvider(QgsNativeAlgorithms())
    context = dataobjects.createContext()
    context.setInvalidGeometryCheck(QgsFeatureRequest.GeometryNoCheck)

    os.environ.update(
        dict(GRASS_COMPRESS_NULLS="1",
             GRASS_COMPRESSOR="ZSTD",
             GRASS_VERBOSE="1"))
    PERMANENT = Session()
    PERMANENT.open(gisdb=grassdb, location=grass_location, create_opts="")

    con = sqlite3.connect(
        os.path.join(grassdb, grass_location, "PERMANENT", "sqlite",
                     "sqlite.db"))

    # create a catchment vector and overlay with str v
    exp = "%s = int(%s)" % (catchments, catchments)
    grass.run_command("r.mapcalc", expression=exp, overwrite=True)

    grass.run_command(
        "r.to.vect",
        input=catchments,
        output=cat_ply_info + "t1",
        type="area",
        overwrite=True,
    )
    grass.run_command("v.db.addcolumn",
                      map=cat_ply_info + "t1",
                      columns="GC_str VARCHAR(40)")
    grass.run_command("v.db.addcolumn",
                      map=cat_ply_info + "t1",
                      columns="Area_m double")
    grass.run_command("v.db.update",
                      map=cat_ply_info + "t1",
                      column="GC_str",
                      qcol="value")
    # dissolve based on gridcode
    grass.run_command(
        "v.dissolve",
        input=cat_ply_info + "t1",
        column="GC_str",
        output=cat_ply_info,
        overwrite=True,
    )

    grass.run_command("v.db.addcolumn",
                      map=cat_ply_info,
                      columns="Gridcode INT")
    grass.run_command("v.db.update",
                      map=cat_ply_info,
                      column="Gridcode",
                      qcol="GC_str")

    ## obtain a stream vector, segmentation based on new catchment polygon
    grass.run_command(
        "v.overlay",
        ainput=river_v,
        alayer=2,
        atype="line",
        binput=cat_ply_info,
        operator="and",
        output=cat_riv_info + "t1",
        overwrite=True,
    )
    grass.run_command(
        "v.out.ogr",
        input=cat_riv_info + "t1",
        output=os.path.join(grassdb, cat_riv_info + "t1" + ".shp"),
        format="ESRI_Shapefile",
        overwrite=True,
    )
    processing.run(
        "gdal:dissolve",
        {
            "INPUT": os.path.join(grassdb, cat_riv_info + "t1" + ".shp"),
            "FIELD": "b_GC_str",
            "OUTPUT": os.path.join(grassdb, cat_riv_info + ".shp"),
        },
    )
    grass.run_command(
        "v.import",
        input=os.path.join(grassdb, cat_riv_info + ".shp"),
        output=cat_riv_info,
        overwrite=True,
    )

    grass.run_command("v.db.addcolumn",
                      map=cat_riv_info,
                      columns="Gridcode INT")
    grass.run_command("v.db.addcolumn",
                      map=cat_riv_info,
                      columns="Length_m double")
    grass.run_command("v.db.update",
                      map=cat_riv_info,
                      column="Gridcode",
                      qcol="b_GC_str")
    grass.run_command("v.db.dropcolumn",
                      map=cat_riv_info,
                      columns=["b_GC_str"])

    grass.run_command(
        "r.out.gdal",
        input=dem,
        output=os.path.join(grassdb, "dem_par.tif"),
        format="GTiff",
        overwrite=True,
    )

    PERMANENT.close()

    os.system("gdalwarp " + '"' + os.path.join(grassdb, "dem_par.tif") + '"' +
              "    " + '"' + os.path.join(grassdb, "dem_proj.tif") + '"' +
              " -t_srs  " + '"' + projection + '"')

    project = Session()
    project.open(gisdb=grassdb,
                 location=grass_location + "_proj",
                 create_opts=projection)

    grass.run_command(
        "r.import",
        input=os.path.join(grassdb, "dem_proj.tif"),
        output="dem_proj",
        overwrite=True,
    )
    grass.run_command("g.region", raster="dem_proj")
    grass.run_command(
        "v.proj",
        location=grass_location,
        mapset="PERMANENT",
        input=cat_riv_info,
        overwrite=True,
    )
    grass.run_command(
        "v.proj",
        location=grass_location,
        mapset="PERMANENT",
        input=cat_ply_info,
        overwrite=True,
    )

    grass.run_command(
        "v.to.db",
        map=cat_ply_info,
        option="area",
        columns="Area_m",
        units="meters",
        overwrite=True,
    )
    grass.run_command(
        "v.to.db",
        map=cat_riv_info,
        option="length",
        columns="Length_m",
        units="meters",
        overwrite=True,
    )

    grass.run_command(
        "r.slope.aspect",
        elevation="dem_proj",
        slope="slope",
        aspect="aspect",
        precision="DCELL",
        overwrite=True,
    )

    ### calcuate averaged slope and aspect of each subbasin
    grass.run_command(
        "v.rast.stats",
        map=cat_ply_info,
        raster="slope",
        column_prefix="s",
        method="average",
    )
    grass.run_command(
        "v.rast.stats",
        map=cat_ply_info,
        raster="aspect",
        column_prefix="a",
        method="average",
    )

    grass.run_command(
        "v.rast.stats",
        map=cat_ply_info,
        raster="dem_proj",
        column_prefix="d",
        method="average",
    )

    ### calcuate minimum and maximum dem along the channel
    grass.run_command(
        "v.rast.stats",
        map=cat_riv_info,
        raster="dem_proj",
        column_prefix="d",
        method=["minimum", "maximum"],
    )

    project.close()

    PERMANENT = Session()
    PERMANENT.open(gisdb=grassdb, location=grass_location, create_opts="")
    grass.run_command("g.region", raster="dem")
    grass.run_command(
        "v.proj",
        location=grass_location + "_proj",
        mapset="PERMANENT",
        input=cat_riv_info,
        overwrite=True,
    )
    grass.run_command(
        "v.proj",
        location=grass_location + "_proj",
        mapset="PERMANENT",
        input=cat_ply_info,
        overwrite=True,
    )

    ### calcuate averaged DEM in each subbasin
    # grass.run_command(
    #     "v.rast.stats",
    #     map=cat_ply_info,
    #     raster="dem",
    #     column_prefix="d",
    #     method="average",
    # )
    #
    # ### calcuate minimum and maximum dem along the channel
    # grass.run_command(
    #     "v.rast.stats",
    #     map=cat_riv_info,
    #     raster="dem",
    #     column_prefix="d",
    #     method=["minimum", "maximum"],
    # )

    ## get routing structure

    exp = "%s = int(%s)" % (fdr, fdr)
    grass.run_command(
        "r.mapcalc",
        expression=exp,
        overwrite=True,
    )

    grass.run_command(
        "r.accumulate",
        direction=fdr,
        accumulation="acc_grass_CatOL",
        overwrite=True,
    )

    ##### obtain catment id overlaied with problem seg
    prom_seg_id, cat_pro_id = generate_stats_list_from_grass_raster(
        grass, mode=2, input_a=problem_seg, input_b=catchments)
    cat_pro_id = np.unique(cat_pro_id)
    grass.run_command("g.copy",
                      rast=(catchments, cat_use_default_acc),
                      overwrite=True)
    if len(cat_pro_id) > 0:
        grass.run_command("r.null",
                          map=cat_use_default_acc,
                          setnull=cat_pro_id,
                          overwrite=True)
    else:
        cat_pro_id = []

    exp = "acc_grass_CatOL2 = if(isnull(%s),%s,%s)" % (
        cat_use_default_acc,
        "acc_grass_CatOL",
        acc,
    )
    grass.run_command(
        "r.mapcalc",
        expression=exp,
        overwrite=True,
    )

    routing_temp = generate_routing_info_of_catchments(
        grass,
        con,
        cat=catchments,
        acc="acc_grass_CatOL2",
        Name="Final",
        str=river_r,
        garray=garray,
    )

    routing_temp = generate_routing_info_of_catchments(
        grass,
        con,
        cat=river_r,
        acc="acc_grass_CatOL2",
        Name="Friv",
        str=river_r,
        garray=garray,
    )

    cat_array = garray.array(mapname=catchments)
    nfdr_arcgis_array = garray.array(mapname=nfdr_arcgis)
    cat_outlet_array = garray.array(mapname="Final_OL")
    ncols = int(cat_array.shape[1])
    nrows = int(cat_array.shape[0])

    grass.run_command("g.copy",
                      vector=("Final_OL_v", outlet_pt_info),
                      overwrite=True)
    PERMANENT.close()

    ## add coordinates to outlet point in wgs84 system
    project_wgs84 = Session()
    project_wgs84.open(gisdb=grassdb,
                       location=grass_location + "_wgs84",
                       create_opts='EPSG:4326')
    grass.run_command(
        "v.proj",
        location=grass_location,
        mapset="PERMANENT",
        input=outlet_pt_info,
        overwrite=True,
    )
    grass.run_command(
        "v.to.db",
        map=outlet_pt_info,
        type='point',
        option='coor',
        columns=['outletLng', 'outletLat'],
        overwrite=True,
    )
    project_wgs84.close()

    ## import updated outlet points after add coordinates in wgs84 system
    PERMANENT = Session()
    PERMANENT.open(gisdb=grassdb, location=grass_location, create_opts="")
    grass.run_command("g.region", raster="dem")
    grass.run_command(
        "v.proj",
        location=grass_location + "_wgs84",
        mapset="PERMANENT",
        input=outlet_pt_info,
        overwrite=True,
    )

    ### update dataframe
    ###
    sqlstat = "SELECT Gridcode, Length_m, d_minimum, d_maximum FROM %s" % (
        cat_riv_info)
    leninfo = pd.read_sql_query(sqlstat, con)
    ### read catchment
    sqlstat = "SELECT Gridcode, Area_m,d_average,s_average,a_average FROM %s" % (
        cat_ply_info)
    areainfo = pd.read_sql_query(sqlstat, con)

    ### read catchment
    sqlstat = "SELECT SubId, DowSubId,ILSubIdmax,ILSubIdmin,outletLat, outletLng FROM %s" % (
        outlet_pt_info)
    outletinfo = pd.read_sql_query(sqlstat, con)
    outletinfo = outletinfo.fillna(-9999)
    outletinfo = outletinfo.loc[outletinfo['SubId'] >= 0]
    ### read catchment
    sqlstat = "SELECT SubId, DSubId_str FROM %s" % ('Friv_OL_v')
    outlet_riv_info = pd.read_sql_query(sqlstat, con)
    outlet_riv_info = outlet_riv_info.fillna(-9999)

    leninfo = leninfo.astype(float).fillna(-9999)
    areainfo = areainfo.astype(float).fillna(-9999)

    for i in range(0, len(outletinfo)):
        catid = outletinfo["SubId"].values[i]
        DownSubID_cat = outletinfo["DowSubId"].values[i]
        outlet_lat = outletinfo["outletLat"].values[i]
        outlet_lon = outletinfo["outletLng"].values[i]

        catinfo.loc[i, "SubId"] = catid
        catinfo.loc[i, "outletLat"] = outlet_lat
        catinfo.loc[i, "outletLng"] = outlet_lon

        # load routing info based on str
        outlet_riv_info_i = outlet_riv_info.loc[outlet_riv_info['SubId'] ==
                                                catid]

        # check if riv outlet exist
        if len(outlet_riv_info_i) < 1:
            DownSubID = DownSubID_cat
            DownSubID_riv = -9999
        else:
            # get down sub id based in river network
            DownSubID_riv = outlet_riv_info_i['DSubId_str'].values[0]

            # may need to modify if downsub id from river != down subid from cat
            if DownSubID_riv != DownSubID_cat:

                # check if DownSubID_cat drainage to DSubId_str
                Down_id_of_downriv_info = outletinfo.loc[outletinfo['SubId'] ==
                                                         DownSubID_riv]
                if len(Down_id_of_downriv_info) > 0:
                    # get down subid of down subid of river
                    DSubId_DSubId_str = Down_id_of_downriv_info[
                        'DowSubId'].values[0]
                    # if down subid of down sub id of river  = down sub id from cat
                    if catid == 10762:
                        print(DSubId_DSubId_str, DownSubID_cat)

                    if DSubId_DSubId_str == DownSubID_cat:
                        DownSubID = DownSubID_riv
                    else:
                        DownSubID = DownSubID_cat
                else:
                    DownSubID = DownSubID_cat
            else:
                DownSubID = DownSubID_cat

        if catid in cat_pro_id or DownSubID == catid or DownSubID == -9999:
            downsubid_array = return_subid_of_next_down_stream_grids(
                cat_array, catid, nfdr_arcgis_array, cat_outlet_array, ncols,
                nrows)
            #            print(catid,DownSubID,downsubid_array)
            if downsubid_array > 0:
                DownSubID = downsubid_array

        ### change the downsub id to -1 for watershed outlet
        if len(outletinfo.loc[outletinfo["SubId"] == DownSubID]) < 1:
            catinfo.loc[i, "DowSubId"] = -1
        elif catid == DownSubID:
            catinfo.loc[i, "DowSubId"] = -1
        else:
            catinfo.loc[i, "DowSubId"] = DownSubID

        catarea = np.unique(areainfo.loc[areainfo["Gridcode"] == catid]
                            ["Area_m"].values)  #'Area_m'
        catslope = np.unique(
            areainfo.loc[areainfo["Gridcode"] == catid]["s_average"].values)
        catelev = np.unique(
            areainfo.loc[areainfo["Gridcode"] == catid]["d_average"].values)
        cataspect = np.unique(
            areainfo.loc[areainfo["Gridcode"] == catid]["a_average"].values)
        if len(catarea) == 1:
            catinfo.loc[i, "BasArea"] = catarea
            catinfo.loc[i, "BasSlope"] = catslope
            catinfo.loc[i, "BasAspect"] = cataspect
            catinfo.loc[i, "MeanElev"] = catelev
        else:
            print(
                "Warning  basin area of stream  ",
                catid,
                "   need check   ",
                len(catarea),
            )
            catinfo.loc[i, "BasArea"] = -9999
            catinfo.loc[i, "BasSlope"] = -9999
            catinfo.loc[i, "BasAspect"] = -9999
            catinfo.loc[i, "MeanElev"] = -9999

        ### add river parameters
        rivlen = np.unique(leninfo.loc[leninfo["Gridcode"] == catid]
                           ["Length_m"].values)  #'Area_m'
        dmaxelev = np.unique(
            leninfo.loc[leninfo["Gridcode"] == catid]["d_maximum"].values)
        dminelev = np.unique(
            leninfo.loc[leninfo["Gridcode"] == catid]["d_minimum"].values)
        if len(rivlen) > 0:
            catinfo.loc[i, "RivLength"] = rivlen[0]
            maxdem = dmaxelev[0]
            mindem = dminelev[0]
            catinfo.loc[i, "Min_DEM"] = mindem
            catinfo.loc[i, "Max_DEM"] = maxdem
            if rivlen[0] >= 0:
                if max(0, float((maxdem - mindem)) / float(rivlen[0])) == 0:
                    slope_rch = -9999
                else:
                    slope_rch = max(
                        0,
                        float((maxdem - mindem)) / float(rivlen[0]))

                slope_rch = max(slope_rch, min_riv_slope)
                slope_rch = min(slope_rch, max_riv_slope)

                catinfo.loc[i, "RivSlope"] = slope_rch

            else:
                catinfo.loc[i, "RivSlope"] = -9999
        else:
            catinfo.loc[i, "RivLength"] = -9999
            catinfo.loc[i, "RivSlope"] = -9999
            catinfo.loc[i, "FloodP_n"] = -9999
            catinfo.loc[i, "Min_DEM"] = -9999
            catinfo.loc[i, "Max_DEM"] = -9999

    PERMANENT.close()
    return catinfo
예제 #59
0
파일: BatchPanel.py 프로젝트: pgab/QGIS
    def populateByExpression(self, adding=False):
        """
        Populates the panel using an expression
        """
        context = dataobjects.createContext()
        expression_context = context.expressionContext()

        # use the first row parameter values as a preview during expression creation
        params, ok = self.panel.parametersForRow(0, warnOnInvalid=False)
        alg_scope = QgsExpressionContextUtils.processingAlgorithmScope(self.panel.alg, params, context)

        # create explicit variables corresponding to every parameter
        for k, v in params.items():
            alg_scope.setVariable(k, v, True)

        # add batchCount in the alg scope to be used in the expressions. 0 is only an example value
        alg_scope.setVariable('row_number', 0, False)

        expression_context.appendScope(alg_scope)

        # mark the parameter variables as highlighted for discoverability
        highlighted_vars = expression_context.highlightedVariables()
        highlighted_vars.extend(list(params.keys()))
        highlighted_vars.append('row_number')
        expression_context.setHighlightedVariables(highlighted_vars)

        dlg = QgsExpressionBuilderDialog(layer=None, context=context.expressionContext())
        if adding:
            dlg.setExpectedOutputFormat(self.tr('An array of values corresponding to each new row to add'))

        if not dlg.exec_():
            return

        if adding:
            exp = QgsExpression(dlg.expressionText())
            res = exp.evaluate(expression_context)

            if type(res) is not list:
                res = [res]

            first_row = self.panel.batchRowCount() if self.panel.batchRowCount() > 1 else 0
            for row, value in enumerate(res):
                self.setRowValue(row + first_row, value, context)
        else:
            for row in range(self.panel.batchRowCount()):
                params, ok = self.panel.parametersForRow(row, warnOnInvalid=False)

                # remove previous algorithm scope -- we need to rebuild this completely, using the
                # other parameter values from the current row
                expression_context.popScope()
                alg_scope = QgsExpressionContextUtils.processingAlgorithmScope(self.panel.alg, params, context)

                for k, v in params.items():
                    alg_scope.setVariable(k, v, True)

                # add batch row number as evaluable variable in algorithm scope
                alg_scope.setVariable('row_number', row, False)

                expression_context.appendScope(alg_scope)

                # rebuild a new expression every time -- we don't want the expression compiler to replace
                # variables with precompiled values
                exp = QgsExpression(dlg.expressionText())
                value = exp.evaluate(expression_context)
                self.setRowValue(row, value, context)
예제 #60
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)