mirror of
https://github.com/qgis/QGIS.git
synced 2025-02-27 00:33:48 -05:00
Merge pull request #4783 from nyalldawson/script
processing: restore script algorithm provider and tests
This commit is contained in:
commit
7f7842a11d
@ -63,6 +63,9 @@ from .PostGISExecuteSQL import PostGISExecuteSQL
|
||||
from .RandomExtract import RandomExtract
|
||||
from .RandomExtractWithinSubsets import RandomExtractWithinSubsets
|
||||
from .RegularPoints import RegularPoints
|
||||
from .SaveSelectedFeatures import SaveSelectedFeatures
|
||||
from .SelectByAttribute import SelectByAttribute
|
||||
from .SelectByExpression import SelectByExpression
|
||||
from .SimplifyGeometries import SimplifyGeometries
|
||||
from .Smooth import Smooth
|
||||
from .SpatialiteExecuteSQL import SpatialiteExecuteSQL
|
||||
@ -98,7 +101,6 @@ from .VectorSplit import VectorSplit
|
||||
# from .SpatialJoin import SpatialJoin
|
||||
# from .DeleteDuplicateGeometries import DeleteDuplicateGeometries
|
||||
# from .TextToFloat import TextToFloat
|
||||
# from .SelectByAttribute import SelectByAttribute
|
||||
# from .GridLine import GridLine
|
||||
# from .Gridify import Gridify
|
||||
# from .HubDistancePoints import HubDistancePoints
|
||||
@ -110,7 +112,6 @@ from .VectorSplit import VectorSplit
|
||||
# from .StatisticsByCategories import StatisticsByCategories
|
||||
# from .EquivalentNumField import EquivalentNumField
|
||||
# from .FieldsCalculator import FieldsCalculator
|
||||
# from .SaveSelectedFeatures import SaveSelectedFeatures
|
||||
# from .Explode import Explode
|
||||
# from .FieldPyculator import FieldsPyculator
|
||||
# from .JoinAttributes import JoinAttributes
|
||||
@ -128,7 +129,6 @@ from .VectorSplit import VectorSplit
|
||||
# from .PointsToPaths import PointsToPaths
|
||||
# from .SetVectorStyle import SetVectorStyle
|
||||
# from .SetRasterStyle import SetRasterStyle
|
||||
# from .SelectByExpression import SelectByExpression
|
||||
# from .SelectByAttributeSum import SelectByAttributeSum
|
||||
# from .HypsometricCurves import HypsometricCurves
|
||||
# from .SplitWithLines import SplitWithLines
|
||||
@ -202,11 +202,10 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
|
||||
# ExtractByLocation(),
|
||||
# SpatialJoin(),
|
||||
# DeleteDuplicateGeometries(), TextToFloat(),
|
||||
# SelectByAttribute(),
|
||||
# GridLine(), Gridify(), HubDistancePoints(),
|
||||
# HubDistanceLines(), HubLines(),
|
||||
# GeometryConvert(), FieldsCalculator(),
|
||||
# SaveSelectedFeatures(), JoinAttributes(),
|
||||
# JoinAttributes(),
|
||||
# Explode(), FieldsPyculator(),
|
||||
# EquivalentNumField(), PointsLayerFromTable(),
|
||||
# StatisticsByCategories(), ConcaveHull(),
|
||||
@ -217,7 +216,7 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
|
||||
# RandomPointsPolygonsVariable(),
|
||||
# RandomPointsAlongLines(), PointsToPaths(),
|
||||
# SetVectorStyle(), SetRasterStyle(),
|
||||
# SelectByExpression(), HypsometricCurves(),
|
||||
# HypsometricCurves(),
|
||||
# SplitWithLines(), CreateConstantRaster(),
|
||||
# FieldsMapper(), SelectByAttributeSum(), Datasources2Vrt(),
|
||||
# OrientedMinimumBoundingBox(),
|
||||
@ -265,6 +264,9 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
|
||||
RandomExtract(),
|
||||
RandomExtractWithinSubsets(),
|
||||
RegularPoints(),
|
||||
SaveSelectedFeatures(),
|
||||
SelectByAttribute(),
|
||||
SelectByExpression(),
|
||||
SimplifyGeometries(),
|
||||
Smooth(),
|
||||
SpatialiteExecuteSQL(),
|
||||
|
@ -25,30 +25,29 @@ __copyright__ = '(C) 2012, Victor Olaya'
|
||||
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
from qgis.core import (QgsApplication,
|
||||
QgsFeatureSink,
|
||||
QgsProcessingUtils)
|
||||
from qgis.core import (QgsFeatureSink,
|
||||
QgsProcessingUtils,
|
||||
QgsProcessingParameterVectorLayer,
|
||||
QgsProcessingParameterFeatureSink,
|
||||
QgsProcessingOutputVectorLayer)
|
||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
||||
from processing.core.parameters import ParameterVector
|
||||
from processing.core.outputs import OutputVector
|
||||
|
||||
|
||||
class SaveSelectedFeatures(QgisAlgorithm):
|
||||
|
||||
OUTPUT_LAYER = 'OUTPUT_LAYER'
|
||||
INPUT_LAYER = 'INPUT_LAYER'
|
||||
OUTPUT = 'OUTPUT'
|
||||
INPUT = 'INPUT'
|
||||
|
||||
def group(self):
|
||||
return self.tr('Vector general tools')
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.addParameter(ParameterVector(self.INPUT_LAYER,
|
||||
self.tr('Input layer')))
|
||||
|
||||
self.addOutput(OutputVector(self.OUTPUT_LAYER,
|
||||
self.tr('Selection')))
|
||||
self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT, self.tr('Input layer')))
|
||||
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Selection')))
|
||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Selection")))
|
||||
|
||||
def name(self):
|
||||
return 'saveselectedfeatures'
|
||||
@ -57,20 +56,20 @@ class SaveSelectedFeatures(QgisAlgorithm):
|
||||
return self.tr('Save selected features')
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
inputFilename = self.getParameterValue(self.INPUT_LAYER)
|
||||
output = self.getOutputFromName(self.OUTPUT_LAYER)
|
||||
vectorLayer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
|
||||
|
||||
vectorLayer = QgsProcessingUtils.mapLayerFromString(inputFilename, context)
|
||||
|
||||
writer = output.getVectorWriter(vectorLayer.fields(), vectorLayer.wkbType(), vectorLayer.crs(), context)
|
||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||
vectorLayer.fields(), vectorLayer.wkbType(), vectorLayer.sourceCrs())
|
||||
|
||||
features = vectorLayer.getSelectedFeatures()
|
||||
count = int(vectorLayer.selectedFeatureCount())
|
||||
if count == 0:
|
||||
raise GeoAlgorithmExecutionException(self.tr('There are no selected features in the input layer.'))
|
||||
|
||||
total = 100.0 / count if count else 1
|
||||
for current, feat in enumerate(features):
|
||||
writer.addFeature(feat, QgsFeatureSink.FastInsert)
|
||||
if feedback.isCanceled():
|
||||
break
|
||||
|
||||
sink.addFeature(feat, QgsFeatureSink.FastInsert)
|
||||
feedback.setProgress(int(current * total))
|
||||
del writer
|
||||
|
||||
return {self.OUTPUT: dest_id}
|
||||
|
@ -28,14 +28,14 @@ __revision__ = '$Format:%H$'
|
||||
from qgis.core import (QgsApplication)
|
||||
from qgis.PyQt.QtCore import QVariant
|
||||
from qgis.core import (QgsExpression,
|
||||
QgsProcessingUtils)
|
||||
QgsProcessingUtils,
|
||||
QgsProcessingParameterVectorLayer,
|
||||
QgsProcessingParameterField,
|
||||
QgsProcessingParameterEnum,
|
||||
QgsProcessingParameterString,
|
||||
QgsProcessingOutputVectorLayer)
|
||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
||||
from processing.core.parameters import ParameterVector
|
||||
from processing.core.parameters import ParameterTableField
|
||||
from processing.core.parameters import ParameterSelection
|
||||
from processing.core.parameters import ParameterString
|
||||
from processing.core.outputs import OutputVector
|
||||
|
||||
|
||||
class SelectByAttribute(QgisAlgorithm):
|
||||
@ -82,15 +82,15 @@ class SelectByAttribute(QgisAlgorithm):
|
||||
self.tr('does not contain')
|
||||
]
|
||||
|
||||
self.addParameter(ParameterVector(self.INPUT,
|
||||
self.tr('Input Layer')))
|
||||
self.addParameter(ParameterTableField(self.FIELD,
|
||||
self.tr('Selection attribute'), self.INPUT))
|
||||
self.addParameter(ParameterSelection(self.OPERATOR,
|
||||
self.tr('Operator'), self.i18n_operators))
|
||||
self.addParameter(ParameterString(self.VALUE, self.tr('Value')))
|
||||
self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT, self.tr('Input layer')))
|
||||
|
||||
self.addOutput(OutputVector(self.OUTPUT, self.tr('Selected (attribute)'), True))
|
||||
self.addParameter(QgsProcessingParameterField(self.FIELD,
|
||||
self.tr('Selection attribute'), parentLayerParameterName=self.INPUT))
|
||||
self.addParameter(QgsProcessingParameterEnum(self.OPERATOR,
|
||||
self.tr('Operator'), self.i18n_operators))
|
||||
self.addParameter(QgsProcessingParameterString(self.VALUE, self.tr('Value')))
|
||||
|
||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Selected (attribute)')))
|
||||
|
||||
def name(self):
|
||||
return 'selectbyattribute'
|
||||
@ -99,11 +99,11 @@ class SelectByAttribute(QgisAlgorithm):
|
||||
return self.tr('Select by attribute')
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
fileName = self.getParameterValue(self.INPUT)
|
||||
layer = QgsProcessingUtils.mapLayerFromString(fileName, context)
|
||||
fieldName = self.getParameterValue(self.FIELD)
|
||||
operator = self.OPERATORS[self.getParameterValue(self.OPERATOR)]
|
||||
value = self.getParameterValue(self.VALUE)
|
||||
layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
|
||||
|
||||
fieldName = self.parameterAsString(parameters, self.FIELD, context)
|
||||
operator = self.OPERATORS[self.parameterAsEnum(parameters, self.OPERATOR, context)]
|
||||
value = self.parameterAsString(parameters, self.VALUE, context)
|
||||
|
||||
fields = layer.fields()
|
||||
|
||||
@ -135,4 +135,4 @@ class SelectByAttribute(QgisAlgorithm):
|
||||
raise GeoAlgorithmExecutionException(expression.parserErrorString())
|
||||
|
||||
layer.selectByExpression(expression_string)
|
||||
self.setOutputValue(self.OUTPUT, fileName)
|
||||
return {self.OUTPUT: parameters[self.INPUT]}
|
||||
|
@ -24,23 +24,21 @@ __copyright__ = '(C) 2014, Michael Douchin'
|
||||
|
||||
__revision__ = '$Format:%H$'
|
||||
|
||||
from qgis.core import (QgsApplication,
|
||||
QgsExpression,
|
||||
from qgis.core import (QgsExpression,
|
||||
QgsVectorLayer,
|
||||
QgsProcessingUtils)
|
||||
QgsProcessingParameterVectorLayer,
|
||||
QgsProcessingParameterExpression,
|
||||
QgsProcessingParameterEnum,
|
||||
QgsProcessingOutputVectorLayer)
|
||||
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
||||
from processing.core.parameters import ParameterVector
|
||||
from processing.core.parameters import ParameterSelection
|
||||
from processing.core.outputs import OutputVector
|
||||
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
|
||||
from processing.core.parameters import ParameterExpression
|
||||
|
||||
|
||||
class SelectByExpression(QgisAlgorithm):
|
||||
|
||||
LAYERNAME = 'LAYERNAME'
|
||||
INPUT = 'INPUT'
|
||||
EXPRESSION = 'EXPRESSION'
|
||||
RESULT = 'RESULT'
|
||||
OUTPUT = 'OUTPUT'
|
||||
METHOD = 'METHOD'
|
||||
|
||||
def group(self):
|
||||
@ -53,13 +51,14 @@ class SelectByExpression(QgisAlgorithm):
|
||||
self.tr('removing from current selection'),
|
||||
self.tr('selecting within current selection')]
|
||||
|
||||
self.addParameter(ParameterVector(self.LAYERNAME,
|
||||
self.tr('Input Layer')))
|
||||
self.addParameter(ParameterExpression(self.EXPRESSION,
|
||||
self.tr("Expression"), parent_layer=self.LAYERNAME))
|
||||
self.addParameter(ParameterSelection(self.METHOD,
|
||||
self.tr('Modify current selection by'), self.methods, 0))
|
||||
self.addOutput(OutputVector(self.RESULT, self.tr('Selected (expression)'), True))
|
||||
self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT, self.tr('Input layer')))
|
||||
|
||||
self.addParameter(QgsProcessingParameterExpression(self.EXPRESSION,
|
||||
self.tr('Expression'), parentLayerParameterName=self.INPUT))
|
||||
self.addParameter(QgsProcessingParameterEnum(self.METHOD,
|
||||
self.tr('Modify current selection by'), self.methods, 0))
|
||||
|
||||
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Selected (attribute)')))
|
||||
|
||||
def name(self):
|
||||
return 'selectbyexpression'
|
||||
@ -68,9 +67,9 @@ class SelectByExpression(QgisAlgorithm):
|
||||
return self.tr('Select by expression')
|
||||
|
||||
def processAlgorithm(self, parameters, context, feedback):
|
||||
filename = self.getParameterValue(self.LAYERNAME)
|
||||
layer = QgsProcessingUtils.mapLayerFromString(filename, context)
|
||||
method = self.getParameterValue(self.METHOD)
|
||||
layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
|
||||
|
||||
method = self.parameterAsEnum(parameters, self.METHOD, context)
|
||||
|
||||
if method == 0:
|
||||
behavior = QgsVectorLayer.SetSelection
|
||||
@ -81,10 +80,10 @@ class SelectByExpression(QgisAlgorithm):
|
||||
elif method == 3:
|
||||
behavior = QgsVectorLayer.IntersectSelection
|
||||
|
||||
expression = self.getParameterValue(self.EXPRESSION)
|
||||
expression = self.parameterAsString(parameters, self.EXPRESSION, context)
|
||||
qExp = QgsExpression(expression)
|
||||
if qExp.hasParserError():
|
||||
raise GeoAlgorithmExecutionException(qExp.parserErrorString())
|
||||
|
||||
layer.selectByExpression(expression, behavior)
|
||||
self.setOutputValue(self.RESULT, filename)
|
||||
return {self.OUTPUT: parameters[self.INPUT]}
|
||||
|
@ -39,7 +39,7 @@ from qgis.utils import iface
|
||||
from qgis.core import (QgsMessageLog,
|
||||
QgsApplication,
|
||||
QgsProcessingProvider,
|
||||
QgsProcessingUtils,
|
||||
QgsProcessingAlgorithm,
|
||||
QgsProcessingParameterDefinition)
|
||||
|
||||
import processing
|
||||
@ -51,12 +51,13 @@ from processing.gui.RenderingStyles import RenderingStyles
|
||||
from processing.gui.Postprocessing import handleAlgorithmResults
|
||||
from processing.gui.AlgorithmExecutor import execute
|
||||
from processing.tools import dataobjects
|
||||
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
|
||||
|
||||
from processing.algs.qgis.QGISAlgorithmProvider import QGISAlgorithmProvider # NOQA
|
||||
#from processing.algs.grass7.Grass7AlgorithmProvider import Grass7AlgorithmProvider # NOQA
|
||||
#from processing.algs.gdal.GdalAlgorithmProvider import GdalAlgorithmProvider # NOQA
|
||||
#from processing.algs.saga.SagaAlgorithmProvider import SagaAlgorithmProvider # NOQA
|
||||
#from processing.script.ScriptAlgorithmProvider import ScriptAlgorithmProvider # NOQA
|
||||
from processing.script.ScriptAlgorithmProvider import ScriptAlgorithmProvider # NOQA
|
||||
#from processing.preconfigured.PreconfiguredAlgorithmProvider import PreconfiguredAlgorithmProvider # NOQA
|
||||
|
||||
# should be loaded last - ensures that all dependent algorithms are available when loading models
|
||||
@ -122,128 +123,61 @@ class Processing(object):
|
||||
provider.refreshAlgorithms()
|
||||
|
||||
@staticmethod
|
||||
def runAlgorithm(algOrName, onFinish, *args, **kwargs):
|
||||
if isinstance(algOrName, GeoAlgorithm):
|
||||
def runAlgorithm(algOrName, parameters, onFinish=None, feedback=None, context=None):
|
||||
if isinstance(algOrName, QgsProcessingAlgorithm):
|
||||
alg = algOrName
|
||||
else:
|
||||
alg = QgsApplication.processingRegistry().algorithmById(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')
|
||||
QgsMessageLog.logMessage(Processing.tr('Error: Algorithm {0} not found\n').format(algOrName),
|
||||
Processing.tr("Processing"))
|
||||
return
|
||||
msg = Processing.tr('Error: Algorithm {0} not found\n').format(algOrName)
|
||||
feedback.reportError(msg)
|
||||
raise GeoAlgorithmExecutionException(msg)
|
||||
|
||||
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
|
||||
# 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 GeoAlgorithmExecutionException(msg)
|
||||
|
||||
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
|
||||
|
||||
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())
|
||||
|
||||
context = None
|
||||
if kwargs is not None and 'context' in list(kwargs.keys()):
|
||||
context = kwargs["context"]
|
||||
else:
|
||||
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))
|
||||
QgsMessageLog.logMessage(Processing.tr('Unable to execute algorithm\n{0}').format(msg),
|
||||
Processing.tr("Processing"))
|
||||
return
|
||||
msg = Processing.tr('Unable to execute algorithm\n{0}').format(msg)
|
||||
feedback.reportError(msg)
|
||||
raise GeoAlgorithmExecutionException(msg)
|
||||
|
||||
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.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:
|
||||
QgsMessageLog.logMessage(Processing.tr("There were errors executing the algorithm."),
|
||||
Processing.tr("Processing"))
|
||||
msg = Processing.tr("There were errors executing the algorithm.")
|
||||
feedback.reportError(msg)
|
||||
raise GeoAlgorithmExecutionException(msg)
|
||||
|
||||
if overrideCursor:
|
||||
QApplication.restoreOverrideCursor()
|
||||
if isinstance(feedback, MessageBarProgress):
|
||||
feedback.close()
|
||||
return results
|
||||
|
@ -39,6 +39,8 @@ from qgis.core import (QgsProject,
|
||||
QgsProcessingParameterDefinition,
|
||||
QgsProcessingOutputRasterLayer,
|
||||
QgsProcessingOutputVectorLayer,
|
||||
QgsProcessingOutputHtml,
|
||||
QgsProcessingParameterVectorOutput,
|
||||
QgsProcessingOutputLayerDefinition,
|
||||
QgsProcessingParameterFeatureSink,
|
||||
QgsProcessingParameterRasterOutput,
|
||||
@ -48,7 +50,7 @@ from qgis.utils import iface
|
||||
|
||||
from processing.core.ProcessingLog import ProcessingLog
|
||||
from processing.core.ProcessingConfig import ProcessingConfig
|
||||
|
||||
from processing.core.ProcessingResults import resultsList
|
||||
from processing.gui.ParametersPanel import ParametersPanel
|
||||
from processing.gui.BatchAlgorithmDialog import BatchAlgorithmDialog
|
||||
from processing.gui.AlgorithmDialogBase import AlgorithmDialogBase
|
||||
@ -82,7 +84,6 @@ class AlgorithmDialog(AlgorithmDialogBase):
|
||||
self.cornerWidget = QWidget()
|
||||
layout = QVBoxLayout()
|
||||
layout.setContentsMargins(0, 0, 0, 5)
|
||||
self.tabWidget.setStyleSheet("QTabBar::tab { height: 30px; }")
|
||||
self.runAsBatchButton = QPushButton(self.tr("Run as batch process..."))
|
||||
self.runAsBatchButton.clicked.connect(self.runAsBatch)
|
||||
layout.addWidget(self.runAsBatchButton)
|
||||
@ -116,7 +117,7 @@ class AlgorithmDialog(AlgorithmDialogBase):
|
||||
else:
|
||||
dest_project = None
|
||||
if not param.flags() & QgsProcessingParameterDefinition.FlagHidden and \
|
||||
isinstance(param, (QgsProcessingParameterRasterOutput, QgsProcessingParameterFeatureSink, OutputTable)):
|
||||
isinstance(param, (QgsProcessingParameterRasterOutput, QgsProcessingParameterFeatureSink, QgsProcessingParameterVectorOutput)):
|
||||
if self.mainWidget.checkBoxes[param.name()].isChecked():
|
||||
dest_project = QgsProject.instance()
|
||||
|
||||
@ -273,6 +274,12 @@ class AlgorithmDialog(AlgorithmDialogBase):
|
||||
|
||||
if self.iterateParam is None:
|
||||
|
||||
# add html results to results dock
|
||||
for out in self.alg.outputDefinitions():
|
||||
if isinstance(out, QgsProcessingOutputHtml) and out.name() in result and result[out.name()]:
|
||||
resultsList.addResult(icon=self.alg.icon(), name=out.description(),
|
||||
result=result[out.name()])
|
||||
|
||||
if not handleAlgorithmResults(self.alg, context, feedback, not keepOpen):
|
||||
self.resetGUI()
|
||||
return
|
||||
|
@ -267,6 +267,8 @@ class DestinationSelectionPanel(BASE, WIDGET):
|
||||
key = None
|
||||
if self.use_temporary and isinstance(self.parameter, QgsProcessingParameterFeatureSink):
|
||||
key = 'memory:'
|
||||
elif self.use_temporary:
|
||||
key = self.parameter.generateTemporaryDestination()
|
||||
else:
|
||||
key = self.leText.text()
|
||||
|
||||
|
@ -1077,16 +1077,12 @@ class TableWidgetWrapper(WidgetWrapper):
|
||||
return BatchInputSelectionPanel(self.param, self.row, self.col, self.dialog)
|
||||
else:
|
||||
self.combo = QComboBox()
|
||||
layers = self.dialog.getAvailableValuesOfType(QgsProcessingParameterRasterLayer, QgsProcessingOutputRasterLayer)
|
||||
self.combo.setEditable(True)
|
||||
tables = self.dialog.getAvailableValuesOfType(QgsProcessingParameterVectorLayer, OutputTable)
|
||||
layers = self.dialog.getAvailableValuesOfType(QgsProcessingParameterFeatureSource, QgsProcessingOutputVectorLayer)
|
||||
tables = self.dialog.getAvailableValuesOfType(QgsProcessingParameterVectorLayer, QgsProcessingOutputVectorLayer)
|
||||
if self.param.flags() & QgsProcessingParameterDefinition.FlagOptional:
|
||||
self.combo.addItem(self.NOT_SELECTED, None)
|
||||
for table in tables:
|
||||
self.combo.addItem(self.dialog.resolveValueDescription(table), table)
|
||||
for layer in layers:
|
||||
self.combo.addItem(self.dialog.resolveValueDescription(layer), layer)
|
||||
|
||||
widget = QWidget()
|
||||
layout = QHBoxLayout()
|
||||
|
@ -2543,29 +2543,29 @@ tests:
|
||||
# MIN_DISTANCE: 0.0
|
||||
# POINT_NUMBER: 5
|
||||
# results: {}
|
||||
#
|
||||
# - algorithm: script:selectbyattribute
|
||||
# name: Select by attribute
|
||||
# params:
|
||||
# INPUT_LAYER:
|
||||
# name: points.gml
|
||||
# type: vector
|
||||
# results:
|
||||
# OUTPUT_LAYER:
|
||||
# name: expected/selected_points.gml
|
||||
# type: vector
|
||||
#
|
||||
# - algorithm: script:selectbyexpression
|
||||
# name: Select by expression
|
||||
# params:
|
||||
# INPUT_LAYER:
|
||||
# name: points.gml
|
||||
# type: vector
|
||||
# results:
|
||||
# OUTPUT_LAYER:
|
||||
# name: expected/select_by_expression.gml
|
||||
# type: vector
|
||||
#
|
||||
|
||||
- algorithm: script:selectbyattribute
|
||||
name: Select by attribute
|
||||
params:
|
||||
INPUT_LAYER:
|
||||
name: points.gml
|
||||
type: vector
|
||||
results:
|
||||
OUTPUT_LAYER:
|
||||
name: expected/selected_points.gml
|
||||
type: vector
|
||||
|
||||
- algorithm: script:selectbyexpression
|
||||
name: Select by expression
|
||||
params:
|
||||
INPUT_LAYER:
|
||||
name: points.gml
|
||||
type: vector
|
||||
results:
|
||||
OUTPUT_LAYER:
|
||||
name: expected/select_by_expression.gml
|
||||
type: vector
|
||||
|
||||
- algorithm: qgis:randomextract
|
||||
name: Random extract by number
|
||||
params:
|
||||
|
@ -2,16 +2,16 @@
|
||||
|
||||
tests:
|
||||
|
||||
# - algorithm: script:centroids
|
||||
# name: Centroids script test
|
||||
# params:
|
||||
# INPUT_LAYER:
|
||||
# name: polys.gml
|
||||
# type: vector
|
||||
# results:
|
||||
# OUTPUT_LAYER:
|
||||
# name: expected/centroid_polys.gml
|
||||
# type: vector
|
||||
# compare:
|
||||
# geometry:
|
||||
# precision: 7
|
||||
- algorithm: script:centroids
|
||||
name: Centroids script test
|
||||
params:
|
||||
INPUT_LAYER:
|
||||
name: polys.gml
|
||||
type: vector
|
||||
results:
|
||||
OUTPUT_LAYER:
|
||||
name: expected/centroid_polys.gml
|
||||
type: vector
|
||||
compare:
|
||||
geometry:
|
||||
precision: 7
|
||||
|
@ -1,17 +1,24 @@
|
||||
##Centroids=name
|
||||
##Geometry=group
|
||||
##INPUT_LAYER=vector
|
||||
##OUTPUT_LAYER=output vector
|
||||
|
||||
#inputs
|
||||
|
||||
##INPUT_LAYER=source
|
||||
##OUTPUT_LAYER=sink point
|
||||
|
||||
#outputs
|
||||
|
||||
##OUTPUT_LAYER=output outputVector
|
||||
|
||||
from qgis.core import QgsWkbTypes, QgsProcessingUtils
|
||||
|
||||
layer = QgsProcessingUtils.mapLayerFromString(INPUT_LAYER, context)
|
||||
fields = layer.fields()
|
||||
fields = INPUT_LAYER.fields()
|
||||
|
||||
writer, writer_dest = QgsProcessingUtils.createFeatureSink(OUTPUT_LAYER, context, fields, QgsWkbTypes.Point, layer.crs(), {'fileEncoding': 'utf-8'})
|
||||
(sink, OUTPUT_LAYER) = self.parameterAsSink(parameters, 'OUTPUT_LAYER', context,
|
||||
fields, QgsWkbTypes.Point, INPUT_LAYER.sourceCrs())
|
||||
|
||||
features = QgsProcessingUtils.getFeatures(layer, context)
|
||||
count = QgsProcessingUtils.featureCount(layer, context)
|
||||
features = INPUT_LAYER.getFeatures()
|
||||
count = INPUT_LAYER.featureCount()
|
||||
if count == 0:
|
||||
raise GeoAlgorithmExecutionException('Input layer contains no features.')
|
||||
|
||||
@ -23,5 +30,5 @@ for count, f in enumerate(features):
|
||||
outputGeometry = f.geometry().centroid()
|
||||
outputFeature.setGeometry(outputGeometry)
|
||||
|
||||
writer.addFeature(outputFeature)
|
||||
sink.addFeature(outputFeature)
|
||||
feedback.setProgress(int(count * total))
|
||||
|
@ -1,16 +1,23 @@
|
||||
##Select by attribute=name
|
||||
##Tests=group
|
||||
|
||||
#inputs
|
||||
|
||||
##INPUT_LAYER=vector
|
||||
##OUTPUT_LAYER=output vector
|
||||
##OUTPUT_LAYER=vectorOut
|
||||
|
||||
#outputs
|
||||
|
||||
##OUTPUT_LAYER=output outputVector
|
||||
|
||||
import processing
|
||||
|
||||
result = processing.run("qgis:selectbyattribute",
|
||||
INPUT_LAYER,
|
||||
"id2",
|
||||
0,
|
||||
"2")
|
||||
|
||||
processing.run("qgis:saveselectedfeatures",
|
||||
result["OUTPUT"],
|
||||
OUTPUT_LAYER)
|
||||
{'INPUT': INPUT_LAYER,
|
||||
'FIELD': "id2",
|
||||
'OPERATOR': 0,
|
||||
'VALUE': "2"}, context=context, feedback=feedback)
|
||||
result = processing.run("qgis:saveselectedfeatures",
|
||||
{'INPUT': result["OUTPUT"],
|
||||
'OUTPUT': parameters['OUTPUT_LAYER']}, context=context, feedback=feedback)
|
||||
OUTPUT_LAYER = result['OUTPUT']
|
||||
|
@ -1,15 +1,25 @@
|
||||
##Select by expression=name
|
||||
##Tests=group
|
||||
|
||||
#inputs
|
||||
|
||||
##INPUT_LAYER=vector
|
||||
##OUTPUT_LAYER=output vector
|
||||
##OUTPUT_LAYER=vectorOut
|
||||
|
||||
#outputs
|
||||
|
||||
##OUTPUT_LAYER=output outputVector
|
||||
|
||||
|
||||
import processing
|
||||
|
||||
result = processing.run("qgis:selectbyexpression",
|
||||
INPUT_LAYER,
|
||||
'"id2" = 0 and "id" > 7',
|
||||
"1")
|
||||
{'INPUT': INPUT_LAYER,
|
||||
'EXPRESSION': '"id2" = 0 and "id" > 7',
|
||||
'METHOD': 1}, context=context, feedback=feedback)
|
||||
|
||||
processing.run("qgis:saveselectedfeatures",
|
||||
result["RESULT"],
|
||||
OUTPUT_LAYER)
|
||||
result = processing.run("qgis:saveselectedfeatures",
|
||||
{'INPUT': result["OUTPUT"],
|
||||
'OUTPUT': parameters['OUTPUT_LAYER']},
|
||||
context=context, feedback=feedback)
|
||||
OUTPUT_LAYER = result['OUTPUT']
|
||||
|
@ -69,11 +69,11 @@ def algorithmHelp(id):
|
||||
print('Algorithm "{}" not found.'.format(id))
|
||||
|
||||
|
||||
def run(algOrName, *args, **kwargs):
|
||||
def run(algOrName, parameters, onFinish=None, feedback=None, context=None):
|
||||
"""Executes given algorithm and returns its outputs as dictionary
|
||||
object.
|
||||
"""
|
||||
return Processing.runAlgorithm(algOrName, None, *args, **kwargs)
|
||||
return Processing.runAlgorithm(algOrName, parameters, onFinish, feedback, context)
|
||||
|
||||
|
||||
def runAndLoadResults(name, *args, **kwargs):
|
||||
|
@ -408,7 +408,7 @@ QString QgsProcessingUtils::tempFolder()
|
||||
sMutex.lock();
|
||||
if ( sFolder.isEmpty() )
|
||||
{
|
||||
QString subPath = QUuid::createUuid().toString();
|
||||
QString subPath = QUuid::createUuid().toString().remove( '-' ).remove( '{' ).remove( '}' );
|
||||
sFolder = QDir::tempPath() + QStringLiteral( "/processing_" ) + subPath;
|
||||
if ( !QDir( sFolder ).exists() )
|
||||
QDir().mkpath( sFolder );
|
||||
@ -419,12 +419,12 @@ QString QgsProcessingUtils::tempFolder()
|
||||
|
||||
QString QgsProcessingUtils::generateTempFilename( const QString &basename )
|
||||
{
|
||||
QString subPath = QUuid::createUuid().toString();
|
||||
QString subPath = QUuid::createUuid().toString().remove( '-' ).remove( '{' ).remove( '}' );
|
||||
QString path = tempFolder() + '/' + subPath;
|
||||
if ( !QDir( path ).exists() ) //make sure the directory exists - it shouldn't, but lets be safe...
|
||||
{
|
||||
QDir tmpDir( QDir::tempPath() );
|
||||
tmpDir.mkdir( subPath );
|
||||
QDir tmpDir;
|
||||
tmpDir.mkdir( path );
|
||||
}
|
||||
return path + '/' + basename;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user