First working pure c++ algorithms

This commit is contained in:
Nyall Dawson 2017-05-15 19:01:15 +10:00
parent 4cb7d18b1c
commit c1d9d57dd2
19 changed files with 262 additions and 76 deletions

View File

@ -193,17 +193,14 @@ class QgsProcessingAlgorithm
:rtype: QgsProcessingOutputDefinition
%End
virtual QVariantMap run( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const;
QVariantMap run( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const;
%Docstring
Runs the algorithm using the specified ``parameters``. Algorithms should implement
their custom processing logic here.
Executes the algorithm using the specified ``parameters``.
The ``context`` argument specifies the context in which the algorithm is being run.
Algorithm progress should be reported using the supplied ``feedback`` object. Additionally,
well-behaved algorithms should periodically check ``feedback`` to determine whether the
algorithm should be canceled and exited early.
Algorithm progress should be reported using the supplied ``feedback`` object.
:return: A map of algorithm outputs. These may be output layer references, or calculated
values such as statistical calculations.
@ -239,6 +236,23 @@ class QgsProcessingAlgorithm
:rtype: bool
%End
virtual QVariantMap processAlgorithm( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const = 0;
%Docstring
Runs the algorithm using the specified ``parameters``. Algorithms should implement
their custom processing logic here.
The ``context`` argument specifies the context in which the algorithm is being run.
Algorithm progress should be reported using the supplied ``feedback`` object. Additionally,
well-behaved algorithms should periodically check ``feedback`` to determine whether the
algorithm should be canceled and exited early.
:return: A map of algorithm outputs. These may be output layer references, or calculated
values such as statistical calculations.
:rtype: QVariantMap
%End
QString parameterAsString( const QVariantMap &parameters, const QString &name, const QgsProcessingContext &context ) const;
%Docstring
Evaluates the parameter with matching ``name`` to a static string value.

View File

@ -83,6 +83,28 @@ class QgsProcessingContext
:rtype: QgsMapLayerStore
%End
QStringList layersToLoadOnCompletion() const;
%Docstring
Returns a list of layers (by ID or datasource) to load into the canvas upon completion of the algorithm or model.
.. seealso:: setLayersToLoadOnCompletion()
.. seealso:: addLayerToLoadOnCompletion()
:rtype: list of str
%End
void setLayersToLoadOnCompletion( const QStringList &layers );
%Docstring
Sets the list of ``layers`` (by ID or datasource) to load into the canvas upon completion of the algorithm or model.
.. seealso:: addLayerToLoadOnCompletion()
.. seealso:: layersToLoadOnCompletion()
%End
void addLayerToLoadOnCompletion( const QString &layer );
%Docstring
Adds a ``layer`` to load (by ID or datasource) into the canvas upon completion of the algorithm or model.
.. seealso:: setLayersToLoadOnCompletion()
.. seealso:: layersToLoadOnCompletion()
%End
QgsFeatureRequest::InvalidGeometryCheck invalidGeometryCheck() const;
%Docstring
@ -137,6 +159,10 @@ class QgsProcessingContext
QgsProcessingContext( const QgsProcessingContext &other );
};
QFlags<QgsProcessingContext::Flag> operator|(QgsProcessingContext::Flag f1, QFlags<QgsProcessingContext::Flag> f2);

View File

@ -178,9 +178,9 @@ class CheckValidity(QgisAlgorithm):
del invalid_writer
del error_writer
if valid_count == 0:
valid_output.open = False
if invalid_count == 0:
invalid_output.open = False
if error_count == 0:
error_output.open = False
if valid_count != 0:
context.addLayerToLoadOnCompletion(valid_output.value)
if invalid_count != 0:
context.addLayerToLoadOnCompletion(invalid_output.value)
if error_count != 0:
context.addLayerToLoadOnCompletion(error_output.value)

View File

@ -75,7 +75,6 @@ class SetRasterStyle(QgisAlgorithm):
style = self.getParameterValue(self.STYLE)
if layer is None:
dataobjects.load(filename, os.path.basename(filename), style=style)
self.getOutputFromName(self.OUTPUT).open = False
else:
with open(style) as f:
xml = "".join(f.readlines())
@ -83,5 +82,6 @@ class SetRasterStyle(QgisAlgorithm):
d.setContent(xml)
n = d.firstChild()
layer.readSymbology(n, '')
context.addLayerToLoadOnCompletion(self.getOutputFromName(self.OUTPUT).value)
self.setOutputValue(self.OUTPUT, filename)
iface.mapCanvas().refresh()
layer.triggerRepaint()

View File

@ -72,8 +72,7 @@ class SetVectorStyle(QgisAlgorithm):
layer = QgsProcessingUtils.mapLayerFromString(filename, context, False)
if layer is None:
dataobjects.load(filename, os.path.basename(filename), style=style)
self.getOutputFromName(self.OUTPUT).open = False
else:
layer.loadNamedStyle(style)
iface.mapCanvas().refresh()
context.addLayerToLoadOnCompletion(layer.id())
layer.triggerRepaint()

View File

@ -462,9 +462,10 @@ def executeAlgorithm(alg, parameters, context=None, feedback=None, model=None):
#self.resolveOutputs()
#self.evaluateParameterValues()
#self.runPreExecutionScript(feedback)
alg.run(parameters, context, 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:

View File

@ -78,10 +78,6 @@ class Output(object):
# outputs not representing layers or tables should always be hidden.
self.hidden = str(hidden).lower() == str(True).lower()
# This value indicates whether the output has to be opened
# after being produced by the algorithm or not
self.open = True
def __str__(self):
return u'{} <{}>'.format(self.name, self.__class__.__name__)

View File

@ -33,7 +33,9 @@ from qgis.PyQt.QtGui import QCursor, QColor, QPalette
from qgis.core import (QgsProject,
QgsProcessingUtils,
QgsMessageLog,
QgsProcessingParameterDefinition)
QgsProcessingParameterDefinition,
QgsProcessingOutputVectorLayer,
QgsProcessingParameterOutputVectorLayer)
from qgis.gui import QgsMessageBar
from qgis.utils import iface
@ -114,6 +116,17 @@ class AlgorithmDialog(AlgorithmDialogBase):
return parameters
def getLayersToOpen(self):
layer_outputs = []
for param in self.alg.destinationParameterDefinitions():
if param.flags() & QgsProcessingParameterDefinition.FlagHidden:
continue
if isinstance(param, (OutputRaster, QgsProcessingParameterOutputVectorLayer, OutputTable)):
if self.mainWidget.checkBoxes[param.name()].isChecked():
layer_outputs.append(param.name())
return layer_outputs
def setParamValue(self, param, wrapper):
if wrapper.widget:
return param.setValue(wrapper.value())
@ -220,7 +233,7 @@ class AlgorithmDialog(AlgorithmDialogBase):
if self.iterateParam:
if executeIterating(self.alg, parameters, self.iterateParam, context, self.feedback):
self.finish(context)
self.finish(parameters, context)
else:
QApplication.restoreOverrideCursor()
self.resetGUI()
@ -229,11 +242,12 @@ class AlgorithmDialog(AlgorithmDialogBase):
#command = self.alg.getAsCommand()
#if command:
# ProcessingLog.addToLog(command)
if executeAlgorithm(self.alg, parameters, context, self.feedback):
self.finish(context)
else:
QApplication.restoreOverrideCursor()
self.resetGUI()
result = executeAlgorithm(self.alg, parameters, context, self.feedback)
self.finish(result, context)
#TODO
#else:
# QApplication.restoreOverrideCursor()
# self.resetGUI()
except AlgorithmDialogBase.InvalidParameterValue as e:
try:
self.buttonBox.accepted.connect(lambda e=e:
@ -247,10 +261,14 @@ class AlgorithmDialog(AlgorithmDialogBase):
self.bar.pushMessage("", self.tr("Wrong or missing parameter value: {0}").format(e.parameter.description),
level=QgsMessageBar.WARNING, duration=5)
def finish(self, context):
def finish(self, result, context):
keepOpen = ProcessingConfig.getSetting(ProcessingConfig.KEEP_DIALOG_OPEN)
if self.iterateParam is None:
for o in self.getLayersToOpen():
context.addLayerToLoadOnCompletion(result[o])
if not handleAlgorithmResults(self.alg, context, self.feedback, not keepOpen):
self.resetGUI()
return

View File

@ -158,6 +158,9 @@ class ConfigDialog(BASE, WIDGET):
emptyItem.setEditable(False)
rootItem.insertRow(0, [groupItem, emptyItem])
if not group in settings:
continue
# add menu item only if it has any search matches
for setting in settings[group]:
if setting.hidden or setting.name.startswith("MENU_"):

View File

@ -33,7 +33,8 @@ from qgis.PyQt import uic
from qgis.PyQt.QtCore import pyqtSignal
from qgis.PyQt.QtWidgets import QDialog
from qgis.core import QgsExpression
from qgis.core import (QgsExpression,
QgsProcessingParameterNumber)
from qgis.gui import QgsExpressionBuilderDialog
from processing.core.parameters import ParameterNumber, ParameterVector, ParameterRaster
from processing.core.outputs import OutputNumber, OutputVector, OutputRaster
@ -63,8 +64,8 @@ class ModellerNumberInputPanel(BASE, WIDGET):
self.param = param
self.modelParametersDialog = modelParametersDialog
if param.default:
self.setValue(param.default)
if param.defaultValue():
self.setValue(param.defaultValue())
self.btnSelect.clicked.connect(self.showExpressionsBuilder)
self.leText.textChanged.connect(lambda: self.hasChanged.emit())
@ -153,36 +154,36 @@ class NumberInputPanel(NUMBER_BASE, NUMBER_WIDGET):
self.spnValue.setExpressionsEnabled(True)
self.param = param
if self.param.isInteger:
if self.param.dataType() == QgsProcessingParameterNumber.Integer:
self.spnValue.setDecimals(0)
else:
# Guess reasonable step value
if self.param.max is not None and self.param.min is not None:
if self.param.maximum() is not None and self.param.minimum() is not None:
try:
self.spnValue.setSingleStep(self.calculateStep(float(self.param.min), float(self.param.max)))
self.spnValue.setSingleStep(self.calculateStep(float(self.param.minimum()), float(self.param.maximum())))
except:
pass
if self.param.max is not None:
self.spnValue.setMaximum(self.param.max)
if self.param.maximum() is not None:
self.spnValue.setMaximum(self.param.maximum())
else:
self.spnValue.setMaximum(999999999)
if self.param.min is not None:
self.spnValue.setMinimum(self.param.min)
if self.param.minimum() is not None:
self.spnValue.setMinimum(self.param.minimum())
else:
self.spnValue.setMinimum(-999999999)
# set default value
if param.default is not None:
self.setValue(param.default)
if param.defaultValue() is not None:
self.setValue(param.defaultValue())
try:
self.spnValue.setClearValue(float(param.default))
self.spnValue.setClearValue(float(param.defaultValue()))
except:
pass
elif self.param.min is not None:
elif self.param.minimum() is not None:
try:
self.setValue(float(self.param.min))
self.spnValue.setClearValue(float(self.param.min))
self.setValue(float(self.param.minimum()))
self.spnValue.setClearValue(float(self.param.minimum()))
except:
pass
else:

View File

@ -55,6 +55,54 @@ def handleAlgorithmResults(alg, context, feedback=None, showResults=True):
feedback = QgsProcessingFeedback()
feedback.setProgressText(QCoreApplication.translate('Postprocessing', 'Loading resulting layers'))
i = 0
#for out in alg.outputs:
# feedback.setProgress(100 * i / float(len(alg.outputs)))
# if out.hidden or not out.open:
# continue
# if isinstance(out, (OutputRaster, OutputVector, OutputTable)):
# try:
# layer = QgsProcessingUtils.mapLayerFromString(out.value, context)
# if layer:
# layer.setName(out.description)
# QgsProject.instance().addMapLayer(context.temporaryLayerStore().takeMapLayer(layer))
# else:
# if ProcessingConfig.getSetting(
# ProcessingConfig.USE_FILENAME_AS_LAYER_NAME):
# name = os.path.basename(out.value)
# else:
# name = out.description
# dataobjects.load(out.value, name, alg.crs,
# RenderingStyles.getStyle(alg.id(),
# out.name))
# except Exception:
# QgsMessageLog.logMessage("Error loading result layer:\n" + traceback.format_exc(), 'Processing', QgsMessageLog.CRITICAL)
# wrongLayers.append(out.description)
# elif isinstance(out, OutputHTML):
# resultsList.addResult(alg.icon(), out.description, out.value)
# i += 1
i = 0
for l in context.layersToLoadOnCompletion():
feedback.setProgress(100 * i / float(len(context.layersToLoadOnCompletion())))
try:
layer = QgsProcessingUtils.mapLayerFromString(l, context)
if layer:
#TODO
#layer.setName(out.description)
QgsProject.instance().addMapLayer(context.temporaryLayerStore().takeMapLayer(layer))
else:
if ProcessingConfig.getSetting(
ProcessingConfig.USE_FILENAME_AS_LAYER_NAME):
name = os.path.basename(l)
else:
#TODO
name = l # out.description
dataobjects.load(l, name, alg.crs,
RenderingStyles.getStyle(alg.id(), l))
#out.name))
except Exception:
QgsMessageLog.logMessage("Error loading result layer:\n" + traceback.format_exc(), 'Processing', QgsMessageLog.CRITICAL)
#wrongLayers.append(out.description)
wrongLayers.append(l)
for out in alg.outputs:
feedback.setProgress(100 * i / float(len(alg.outputs)))
if out.hidden or not out.open:

View File

@ -723,8 +723,8 @@ class SelectionWidgetWrapper(WidgetWrapper):
return MultipleInputPanel(options=self.param.options())
else:
widget = QComboBox()
for option in self.param.options():
widget.addItem(option[1], option[0])
for i, option in enumerate(self.param.options()):
widget.addItem(option, i)
if self.param.defaultValue():
widget.setCurrentIndex(widget.findData(self.param.defaultValue()))
return widget

View File

@ -1377,11 +1377,16 @@ bool QgsGeos::centroid( QgsPoint &pt, QString *errorMsg ) const
return false;
}
double x, y;
GEOSGeomGetX_r( geosinit.ctxt, geos.get(), &x );
GEOSGeomGetY_r( geosinit.ctxt, geos.get(), &y );
pt.setX( x );
pt.setY( y );
try
{
double x, y;
GEOSGeomGetX_r( geosinit.ctxt, geos.get(), &x );
GEOSGeomGetY_r( geosinit.ctxt, geos.get(), &y );
pt.setX( x );
pt.setY( y );
}
CATCH_GEOS_WITH_ERRMSG( false );
return true;
}

View File

@ -76,7 +76,7 @@ QString QgsCentroidAlgorithm::shortHelpString() const
"The attributes associated to each point in the output layer are the same ones associated to the original features." );
}
QVariantMap QgsCentroidAlgorithm::run( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const
QVariantMap QgsCentroidAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const
{
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( parameterAsLayer( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !layer )
@ -130,6 +130,11 @@ QgsBufferAlgorithm::QgsBufferAlgorithm()
addParameter( new QgsProcessingParameterVectorLayer( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
addParameter( new QgsProcessingParameterNumber( QStringLiteral( "DISTANCE" ), QObject::tr( "Distance" ), QgsProcessingParameterNumber::Double, 10 ) );
addParameter( new QgsProcessingParameterNumber( QStringLiteral( "SEGMENTS" ), QObject::tr( "Segments" ), QgsProcessingParameterNumber::Integer, 5, false, 1 ) );
addParameter( new QgsProcessingParameterEnum( QStringLiteral( "END_CAP_STYLE" ), QObject::tr( "End cap style" ), QStringList() << QObject::tr( "Round" ) << QObject::tr( "Flat" ) << QObject::tr( "Square" ), false ) );
addParameter( new QgsProcessingParameterEnum( QStringLiteral( "JOIN_STYLE" ), QObject::tr( "Join style" ), QStringList() << QObject::tr( "Round" ) << QObject::tr( "Miter" ) << QObject::tr( "Bevel" ), false ) );
addParameter( new QgsProcessingParameterNumber( QStringLiteral( "MITRE_LIMIT" ), QObject::tr( "Miter limit" ), QgsProcessingParameterNumber::Double, 2, false, 1 ) );
addParameter( new QgsProcessingParameterBoolean( QStringLiteral( "DISSOLVE" ), QObject::tr( "Dissolve result" ), false ) );
addParameter( new QgsProcessingParameterOutputVectorLayer( QStringLiteral( "OUTPUT_LAYER" ), QObject::tr( "Buffered" ), QgsProcessingParameterDefinition::TypeVectorPolygon ) );
addOutput( new QgsProcessingOutputVectorLayer( QStringLiteral( "OUTPUT_LAYER" ), QObject::tr( "Buffered" ), QgsProcessingParameterDefinition::TypeVectorPoint ) );
@ -144,20 +149,20 @@ QString QgsBufferAlgorithm::shortHelpString() const
"The mitre limit parameter is only applicable for mitre join styles, and controls the maximum distance from the offset curve to use when creating a mitred join." );
}
QVariantMap QgsBufferAlgorithm::run( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const
QVariantMap QgsBufferAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const
{
QgsVectorLayer *layer = qobject_cast< QgsVectorLayer *>( parameterAsLayer( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !layer )
return QVariantMap();
QString dest = parameterAsString( parameters, QStringLiteral( "OUTPUT_LAYER" ), context );
std::unique_ptr< QgsFeatureSink > writer( QgsProcessingUtils::createFeatureSink( dest, QString(), layer->fields(), QgsWkbTypes::Point, layer->crs(), context ) );
std::unique_ptr< QgsFeatureSink > writer( QgsProcessingUtils::createFeatureSink( dest, QString(), layer->fields(), QgsWkbTypes::Polygon, layer->crs(), context ) );
// fixed parameters
//bool dissolve = QgsProcessingParameters::parameterAsBool( parameters, QStringLiteral( "DISSOLVE" ), context );
int segments = parameterAsInt( parameters, QStringLiteral( "SEGMENTS" ), context );
QgsGeometry::EndCapStyle endCapStyle = static_cast< QgsGeometry::EndCapStyle >( parameterAsInt( parameters, QStringLiteral( "END_CAP_STYLE" ), context ) );
QgsGeometry::JoinStyle joinStyle = static_cast< QgsGeometry::JoinStyle>( parameterAsInt( parameters, QStringLiteral( "JOIN_STYLE" ), context ) );
QgsGeometry::EndCapStyle endCapStyle = static_cast< QgsGeometry::EndCapStyle >( 1 + parameterAsInt( parameters, QStringLiteral( "END_CAP_STYLE" ), context ) );
QgsGeometry::JoinStyle joinStyle = static_cast< QgsGeometry::JoinStyle>( 1 + parameterAsInt( parameters, QStringLiteral( "JOIN_STYLE" ), context ) );
double miterLimit = parameterAsDouble( parameters, QStringLiteral( "MITRE_LIMIT" ), context );
double bufferDistance = parameterAsDouble( parameters, QStringLiteral( "DISTANCE" ), context );
bool dynamicBuffer = QgsProcessingParameters::isDynamic( parameters, QStringLiteral( "DISTANCE" ) );

View File

@ -59,8 +59,10 @@ class QgsCentroidAlgorithm : public QgsProcessingAlgorithm
QString group() const override { return QObject::tr( "Vector geometry tools" ); }
QString shortHelpString() const override;
virtual QVariantMap run( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const override;
protected:
virtual QVariantMap processAlgorithm( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const override;
};
@ -80,8 +82,10 @@ class QgsBufferAlgorithm : public QgsProcessingAlgorithm
QString group() const override { return QObject::tr( "Vector geometry tools" ); }
QString shortHelpString() const override;
virtual QVariantMap run( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const override;
protected:
virtual QVariantMap processAlgorithm( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const override;
};

View File

@ -81,11 +81,6 @@ void QgsProcessingAlgorithm::setProvider( QgsProcessingProvider *provider )
mProvider = provider;
}
QVariantMap QgsProcessingAlgorithm::run( const QVariantMap &, QgsProcessingContext &, QgsProcessingFeedback * ) const
{
return QVariantMap();
}
QWidget *QgsProcessingAlgorithm::createCustomParametersWidget( QWidget * ) const
{
return nullptr;
@ -161,6 +156,11 @@ const QgsProcessingOutputDefinition *QgsProcessingAlgorithm::outputDefinition( c
return nullptr;
}
QVariantMap QgsProcessingAlgorithm::run( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const
{
return processAlgorithm( parameters, context, feedback );
}
QString QgsProcessingAlgorithm::parameterAsString( const QVariantMap &parameters, const QString &name, const QgsProcessingContext &context ) const
{
return QgsProcessingParameters::parameterAsString( parameterDefinition( name ), parameters, name, context );

View File

@ -198,20 +198,17 @@ class CORE_EXPORT QgsProcessingAlgorithm
const QgsProcessingOutputDefinition *outputDefinition( const QString &name ) const;
/**
* Runs the algorithm using the specified \a parameters. Algorithms should implement
* their custom processing logic here.
* Executes the algorithm using the specified \a parameters.
*
* The \a context argument specifies the context in which the algorithm is being run.
*
* Algorithm progress should be reported using the supplied \a feedback object. Additionally,
* well-behaved algorithms should periodically check \a feedback to determine whether the
* algorithm should be canceled and exited early.
* Algorithm progress should be reported using the supplied \a feedback object.
*
* \returns A map of algorithm outputs. These may be output layer references, or calculated
* values such as statistical calculations.
*/
virtual QVariantMap run( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const;
QVariantMap run( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const;
/**
* If an algorithm subclass implements a custom parameters widget, a copy of this widget
@ -239,6 +236,22 @@ class CORE_EXPORT QgsProcessingAlgorithm
*/
bool addOutput( QgsProcessingOutputDefinition *outputDefinition SIP_TRANSFER );
/**
* Runs the algorithm using the specified \a parameters. Algorithms should implement
* their custom processing logic here.
*
* The \a context argument specifies the context in which the algorithm is being run.
*
* Algorithm progress should be reported using the supplied \a feedback object. Additionally,
* well-behaved algorithms should periodically check \a feedback to determine whether the
* algorithm should be canceled and exited early.
*
* \returns A map of algorithm outputs. These may be output layer references, or calculated
* values such as statistical calculations.
*/
virtual QVariantMap processAlgorithm( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const = 0;
/**
* Evaluates the parameter with matching \a name to a static string value.
*/

View File

@ -23,6 +23,7 @@
#include "qgsproject.h"
#include "qgsexpressioncontext.h"
#include "qgsfeaturerequest.h"
#include "qgsmaplayerlistutils.h"
/**
* \class QgsProcessingContext
@ -100,6 +101,36 @@ class CORE_EXPORT QgsProcessingContext
*/
QgsMapLayerStore *temporaryLayerStore() { return &tempLayerStore; }
/**
* Returns a list of layers (by ID or datasource) to load into the canvas upon completion of the algorithm or model.
* \see setLayersToLoadOnCompletion()
* \see addLayerToLoadOnCompletion()
*/
QStringList layersToLoadOnCompletion() const
{
return mLayersToLoadOnCompletion;
}
/**
* Sets the list of \a layers (by ID or datasource) to load into the canvas upon completion of the algorithm or model.
* \see addLayerToLoadOnCompletion()
* \see layersToLoadOnCompletion()
*/
void setLayersToLoadOnCompletion( const QStringList &layers )
{
mLayersToLoadOnCompletion = layers;
}
/**
* Adds a \a layer to load (by ID or datasource) into the canvas upon completion of the algorithm or model.
* \see setLayersToLoadOnCompletion()
* \see layersToLoadOnCompletion()
*/
void addLayerToLoadOnCompletion( const QString &layer )
{
mLayersToLoadOnCompletion << layer;
}
/**
* Returns a map of output values stored in the context. These are grouped with the map keys
* matching the algorithm name for multi-algorithm models.
@ -177,12 +208,17 @@ class CORE_EXPORT QgsProcessingContext
QgsFeatureRequest::InvalidGeometryCheck mInvalidGeometryCheck = QgsFeatureRequest::GeometryNoCheck;
std::function< void( const QgsFeature & ) > mInvalidGeometryCallback;
QString mDefaultEncoding;
QStringList mLayersToLoadOnCompletion;
#ifdef SIP_RUN
QgsProcessingContext( const QgsProcessingContext &other );
#endif
};
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsProcessingContext::Flags )
#endif // QGSPROCESSINGPARAMETERS_H

View File

@ -39,8 +39,8 @@ class DummyAlgorithm : public QgsProcessingAlgorithm
QString name() const override { return mName; }
QString displayName() const override { return mName; }
virtual QVariantMap run( const QVariantMap &,
QgsProcessingContext &, QgsProcessingFeedback * ) const override { return QVariantMap(); }
virtual QVariantMap processAlgorithm( const QVariantMap &,
QgsProcessingContext &, QgsProcessingFeedback * ) const override { return QVariantMap(); }
QString mName;
void runParameterChecks()
@ -443,6 +443,23 @@ void TestQgsProcessing::context()
context.setInvalidGeometryCheck( QgsFeatureRequest::GeometrySkipInvalid );
QCOMPARE( context.invalidGeometryCheck(), QgsFeatureRequest::GeometrySkipInvalid );
// layers to load on completion
QgsVectorLayer *v1 = new QgsVectorLayer( "Polygon", "V1", "memory" );
QgsVectorLayer *v2 = new QgsVectorLayer( "Polygon", "V2", "memory" );
QVERIFY( context.layersToLoadOnCompletion().isEmpty() );
context.setLayersToLoadOnCompletion( QStringList() << v1->id() );
QCOMPARE( context.layersToLoadOnCompletion().count(), 1 );
QCOMPARE( context.layersToLoadOnCompletion().at( 0 ), v1->id() );
context.addLayerToLoadOnCompletion( v2->id() );
QCOMPARE( context.layersToLoadOnCompletion().count(), 2 );
QCOMPARE( context.layersToLoadOnCompletion().at( 0 ), v1->id() );
QCOMPARE( context.layersToLoadOnCompletion().at( 1 ), v2->id() );
context.setLayersToLoadOnCompletion( QStringList() << v2->id() );
QCOMPARE( context.layersToLoadOnCompletion().count(), 1 );
QCOMPARE( context.layersToLoadOnCompletion().at( 0 ), v2->id() );
delete v1;
delete v2;
}
void TestQgsProcessing::mapLayers()