Merge pull request #4783 from nyalldawson/script

processing: restore script algorithm provider and tests
This commit is contained in:
Nyall Dawson 2017-06-27 14:15:36 +10:00 committed by GitHub
commit 7f7842a11d
15 changed files with 203 additions and 240 deletions

View File

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

View File

@ -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}

View File

@ -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]}

View File

@ -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]}

View File

@ -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

View File

@ -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

View File

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

View File

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

View File

@ -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:

View File

@ -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

View File

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

View File

@ -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']

View File

@ -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']

View File

@ -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):

View File

@ -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;
}