[processing] More helpful errors when sources cannot be loaded

Include descriptive text with the specified parameter value
in error, and always check that sources were loaded to avoid
raw Python exceptions when they are not
This commit is contained in:
Nyall Dawson 2018-04-27 12:31:56 +10:00
parent 199af26048
commit 5339d62715
95 changed files with 469 additions and 43 deletions

View File

@ -744,6 +744,32 @@ Evaluates the parameter with matching ``name`` to a range of values.
QStringList parameterAsFields( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context ) const;
%Docstring
Evaluates the parameter with matching ``name`` to a list of fields.
%End
static QString invalidSourceError( const QVariantMap &parameters, const QString &name );
%Docstring
Returns a user-friendly string to use as an error when a source parameter could
not be loaded.
The ``parameters`` argument should give the algorithms parameter map, and the ``name``
should correspond to the invalid source parameter name.
.. versionadded:: 3.2
.. seealso:: :py:func:`invalidSinkError`
%End
static QString invalidSinkError( const QVariantMap &parameters, const QString &name );
%Docstring
Returns a user-friendly string to use as an error when a sink parameter could
not be created.
The ``parameters`` argument should give the algorithms parameter map, and the ``name``
should correspond to the invalid source parameter name.
.. versionadded:: 3.2
.. seealso:: :py:func:`invalidSourceError`
%End
private:

View File

@ -32,6 +32,7 @@ from qgis.core import (QgsProcessing,
QgsProcessingParameterField,
QgsProcessingParameterString,
QgsProcessingParameterNumber,
QgsProcessingException,
QgsProcessingParameterBoolean,
QgsProcessingParameterVectorDestination)
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
@ -103,7 +104,10 @@ class Buffer(GdalAlgorithm):
return 'ogr2ogr'
def getConsoleCommands(self, parameters, context, feedback, executing=True):
fields = self.parameterAsSource(parameters, self.INPUT, context).fields()
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
fields = source.fields()
ogrLayer, layerName = self.getOgrCompatibleSource(self.INPUT, parameters, context, feedback, executing)
geometry = self.parameterAsString(parameters, self.GEOMETRY, context)
distance = self.parameterAsDouble(parameters, self.DISTANCE, context)

View File

@ -27,6 +27,7 @@ __revision__ = '$Format:%H$'
from qgis.core import (QgsVectorLayer,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterExtent,
@ -80,6 +81,9 @@ class ClipVectorByExtent(GdalAlgorithm):
def getConsoleCommands(self, parameters, context, feedback, executing=True):
ogrLayer, layerName = self.getOgrCompatibleSource(self.INPUT, parameters, context, feedback, executing)
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
extent = self.parameterAsExtent(parameters, self.EXTENT, context, source.sourceCrs())
options = self.parameterAsString(parameters, self.OPTIONS, context)
outFile = self.parameterAsOutputLayer(parameters, self.OUTPUT, context)

View File

@ -26,6 +26,7 @@ __copyright__ = '(C) 2015, Giovanni Manghi'
__revision__ = '$Format:%H$'
from qgis.core import (QgsProcessing,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterField,
@ -113,7 +114,11 @@ class Dissolve(GdalAlgorithm):
return 'ogr2ogr'
def getConsoleCommands(self, parameters, context, feedback, executing=True):
fields = self.parameterAsSource(parameters, self.INPUT, context).fields()
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
fields = source.fields()
ogrLayer, layerName = self.getOgrCompatibleSource(self.INPUT, parameters, context, feedback, executing)
geometry = self.parameterAsString(parameters, self.GEOMETRY, context)
fieldName = self.parameterAsString(parameters, self.FIELD, context)

View File

@ -30,6 +30,7 @@ from qgis.core import (QgsProcessing,
QgsProcessingParameterDistance,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterString,
QgsProcessingException,
QgsProcessingParameterNumber,
QgsProcessingParameterVectorDestination)
from processing.algs.gdal.GdalAlgorithm import GdalAlgorithm
@ -86,7 +87,11 @@ class OffsetCurve(GdalAlgorithm):
return 'ogr2ogr'
def getConsoleCommands(self, parameters, context, feedback, executing=True):
fields = self.parameterAsSource(parameters, self.INPUT, context).fields()
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
fields = source.fields()
ogrLayer, layerName = self.getOgrCompatibleSource(self.INPUT, parameters, context, feedback, executing)
geometry = self.parameterAsString(parameters, self.GEOMETRY, context)
distance = self.parameterAsDouble(parameters, self.DISTANCE, context)

View File

@ -26,6 +26,7 @@ __copyright__ = '(C) 2015, Giovanni Manghi'
__revision__ = '$Format:%H$'
from qgis.core import (QgsProcessing,
QgsProcessingException,
QgsProcessingParameterDefinition,
QgsProcessingParameterDistance,
QgsProcessingParameterFeatureSource,
@ -112,7 +113,11 @@ class OneSideBuffer(GdalAlgorithm):
return 'ogr2ogr'
def getConsoleCommands(self, parameters, context, feedback, executing=True):
fields = self.parameterAsSource(parameters, self.INPUT, context).fields()
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
fields = source.fields()
ogrLayer, layerName = self.getOgrCompatibleSource(self.INPUT, parameters, context, feedback, executing)
geometry = self.parameterAsString(parameters, self.GEOMETRY, context)
distance = self.parameterAsDouble(parameters, self.DISTANCE, context)

View File

@ -25,7 +25,8 @@ __copyright__ = '(C) 2015, Giovanni Manghi'
__revision__ = '$Format:%H$'
from qgis.core import (QgsProcessingParameterFeatureSource,
from qgis.core import (QgsProcessingException,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterString,
QgsProcessingParameterNumber,
QgsProcessingParameterVectorDestination,
@ -90,7 +91,11 @@ class PointsAlongLines(GdalAlgorithm):
return 'ogr2ogr'
def getConsoleCommands(self, parameters, context, feedback, executing=True):
fields = self.parameterAsSource(parameters, self.INPUT, context).fields()
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
fields = source.fields()
ogrLayer, layerName = self.getOgrCompatibleSource(self.INPUT, parameters, context, feedback, executing)
distance = self.parameterAsDouble(parameters, self.DISTANCE, context)
geometry = self.parameterAsString(parameters, self.GEOMETRY, context)

View File

@ -131,6 +131,9 @@ class Aggregate(QgisAlgorithm):
def prepareAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
group_by = self.parameterAsExpression(parameters, self.GROUP_BY, context)
aggregates = self.parameterAsAggregates(parameters, self.AGGREGATES, context)

View File

@ -31,6 +31,7 @@ import plotly.graph_objs as go
from qgis.core import (QgsProcessingParameterFeatureSource,
QgsProcessingParameterField,
QgsProcessingException,
QgsProcessingParameterFileDestination)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools import vector
@ -72,6 +73,8 @@ class BarPlot(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
namefieldname = self.parameterAsString(parameters, self.NAME_FIELD, context)
valuefieldname = self.parameterAsString(parameters, self.VALUE_FIELD, context)

View File

@ -35,6 +35,7 @@ from qgis.core import (QgsStatisticalSummary,
QgsStringStatisticalSummary,
QgsDateTimeStatisticalSummary,
QgsFeatureRequest,
QgsProcessingException,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterField,
QgsProcessingParameterFileDestination,
@ -128,6 +129,9 @@ class BasicStatisticsForField(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
field_name = self.parameterAsString(parameters, self.FIELD_NAME, context)
field = source.fields().at(source.fields().lookupField(field_name))

View File

@ -28,7 +28,8 @@ __revision__ = '$Format:%H$'
import plotly as plt
import plotly.graph_objs as go
from qgis.core import (QgsProcessingParameterFeatureSource,
from qgis.core import (QgsProcessingException,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterField,
QgsProcessingParameterEnum,
QgsProcessingParameterFileDestination,
@ -84,6 +85,9 @@ class BoxPlot(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
namefieldname = self.parameterAsString(parameters, self.NAME_FIELD, context)
valuefieldname = self.parameterAsString(parameters, self.VALUE_FIELD, context)

View File

@ -39,6 +39,7 @@ from qgis.core import (QgsSettings,
QgsWkbTypes,
QgsFields,
QgsProcessing,
QgsProcessingException,
QgsProcessingFeatureSource,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterEnum,
@ -121,6 +122,8 @@ class CheckValidity(QgisAlgorithm):
def doCheck(self, method, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
(valid_output_sink, valid_output_dest_id) = self.parameterAsSink(parameters, self.VALID_OUTPUT, context,
source.fields(), source.wkbType(), source.sourceCrs())

View File

@ -79,6 +79,9 @@ class ConcaveHull(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
layer = self.parameterAsSource(parameters, ConcaveHull.INPUT, context)
if layer is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
alpha = self.parameterAsDouble(parameters, self.ALPHA, context)
holes = self.parameterAsBool(parameters, self.HOLES, context)
no_multigeom = self.parameterAsBool(parameters, self.NO_MULTIGEOMETRY, context)

View File

@ -79,6 +79,8 @@ class Delaunay(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
fields = QgsFields()
fields.append(QgsField('POINTA', QVariant.Double, '', 24, 15))

View File

@ -26,6 +26,7 @@ __copyright__ = '(C) 2010, Michael Minn'
__revision__ = '$Format:%H$'
from qgis.core import (QgsFeatureRequest,
QgsProcessingException,
QgsFeatureSink,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink)
@ -59,6 +60,9 @@ class DeleteDuplicateGeometries(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
source.fields(), source.wkbType(), source.sourceCrs())

View File

@ -40,6 +40,7 @@ from qgis.core import (NULL,
QgsFeatureSink,
QgsDistanceArea,
QgsProcessingUtils,
QgsProcessingException,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterEnum,
QgsProcessingParameterFeatureSink)
@ -92,6 +93,9 @@ class ExportGeometryInfo(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
method = self.parameterAsEnum(parameters, self.METHOD, context)
wkb_type = source.wkbType()

View File

@ -77,6 +77,9 @@ class ExtractSpecificVertices(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
fields = source.fields()
fields.append(QgsField('vertex_pos', QVariant.Int))
fields.append(QgsField('vertex_index', QVariant.Int))

View File

@ -91,6 +91,9 @@ class FieldsPyculator(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
field_name = self.parameterAsString(parameters, self.FIELD_NAME, context)
field_type = self.TYPES[self.parameterAsEnum(parameters, self.FIELD_TYPE, context)]
width = self.parameterAsInt(parameters, self.FIELD_LENGTH, context)

View File

@ -94,6 +94,9 @@ class FieldsCalculator(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
field_name = self.parameterAsString(parameters, self.FIELD_NAME, context)
field_type = self.TYPES[self.parameterAsEnum(parameters, self.FIELD_TYPE, context)]

View File

@ -81,6 +81,9 @@ class FieldsMapper(QgisFeatureBasedAlgorithm):
def prepareAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, 'INPUT', context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
mapping = self.parameterAsFieldsMapping(parameters, self.FIELDS_MAPPING, context)
self.fields = QgsFields()

View File

@ -36,6 +36,7 @@ from qgis.core import (QgsGeometry,
QgsCoordinateTransform,
QgsCoordinateTransformContext,
QgsWkbTypes,
QgsProcessingException,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterExtent,
QgsProcessingParameterCrs,
@ -86,6 +87,8 @@ class FindProjection(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
extent = self.parameterAsExtent(parameters, self.TARGET_AREA, context)
target_crs = self.parameterAsCrs(parameters, self.TARGET_AREA_CRS, context)

View File

@ -77,6 +77,9 @@ class GeometryConvert(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
index = self.parameterAsEnum(parameters, self.TYPE, context)
if index == 0:

View File

@ -176,6 +176,8 @@ class Heatmap(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
radius = self.parameterAsDouble(parameters, self.RADIUS, context)
kernel_shape = self.parameterAsEnum(parameters, self.KERNEL, context)

View File

@ -102,7 +102,13 @@ class HubDistanceLines(QgisAlgorithm):
self.tr('Same layer given for both hubs and spokes'))
point_source = self.parameterAsSource(parameters, self.INPUT, context)
if point_source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
hub_source = self.parameterAsSource(parameters, self.HUBS, context)
if hub_source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.HUBS))
fieldName = self.parameterAsString(parameters, self.FIELD, context)
units = self.UNITS[self.parameterAsEnum(parameters, self.UNIT, context)]

View File

@ -98,7 +98,13 @@ class HubDistancePoints(QgisAlgorithm):
self.tr('Same layer given for both hubs and spokes'))
point_source = self.parameterAsSource(parameters, self.INPUT, context)
if point_source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
hub_source = self.parameterAsSource(parameters, self.HUBS, context)
if hub_source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.HUBS))
fieldName = self.parameterAsString(parameters, self.FIELD, context)
units = self.UNITS[self.parameterAsEnum(parameters, self.UNIT, context)]

View File

@ -34,6 +34,7 @@ from osgeo import gdal, ogr, osr
from qgis.core import (QgsRectangle,
QgsGeometry,
QgsFeatureRequest,
QgsProcessingException,
QgsProcessing,
QgsProcessingParameterBoolean,
QgsProcessingParameterNumber,
@ -87,6 +88,9 @@ class HypsometricCurves(QgisAlgorithm):
rasterPath = raster_layer.source()
source = self.parameterAsSource(parameters, self.BOUNDARY_LAYER, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.BOUNDARY_LAYER))
step = self.parameterAsDouble(parameters, self.STEP, context)
percentage = self.parameterAsBool(parameters, self.USE_PERCENTAGE, context)

View File

@ -131,6 +131,8 @@ class ImportIntoPostGIS(QgisAlgorithm):
encoding = self.parameterAsString(parameters, self.ENCODING, context)
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
table = self.parameterAsString(parameters, self.TABLENAME, context)
if table:

View File

@ -107,6 +107,8 @@ class ImportIntoSpatialite(QgisAlgorithm):
encoding = self.parameterAsString(parameters, self.ENCODING, context)
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
table = self.parameterAsString(parameters, self.TABLENAME, context)
if table:

View File

@ -31,6 +31,7 @@ from operator import itemgetter
from qgis.core import (QgsGeometry,
QgsFeatureSink,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterFeatureSink,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterNumber,
@ -72,6 +73,9 @@ class KeepNBiggestParts(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.POLYGONS, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.POLYGONS))
parts = self.parameterAsInt(parameters, self.PARTS, context)
fields = source.fields()

View File

@ -31,6 +31,7 @@ import plotly.graph_objs as go
from qgis.core import (QgsProcessingParameterFeatureSource,
QgsProcessingParameterField,
QgsProcessingUtils,
QgsProcessingException,
QgsProcessingParameterFileDestination)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
@ -72,6 +73,9 @@ class MeanAndStdDevPlot(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
namefieldname = self.parameterAsString(parameters, self.NAME_FIELD, context)
valuefieldname = self.parameterAsString(parameters, self.VALUE_FIELD, context)

View File

@ -38,6 +38,7 @@ from qgis.core import (QgsField,
QgsFeatureRequest,
QgsFields,
QgsRectangle,
QgsProcessingException,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterField,
QgsProcessingParameterEnum,
@ -99,6 +100,9 @@ class MinimumBoundingGeometry(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
field_name = self.parameterAsString(parameters, self.FIELD, context)
type = self.parameterAsEnum(parameters, self.TYPE, context)
use_field = bool(field_name)

View File

@ -35,6 +35,7 @@ from qgis.core import (QgsFeatureRequest,
QgsDistanceArea,
QgsProject,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFileDestination,
QgsProcessingOutputNumber,
@ -91,6 +92,9 @@ class NearestNeighbourAnalysis(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
output_file = self.parameterAsFileOutput(parameters, self.OUTPUT_HTML_FILE, context)
spatialIndex = QgsSpatialIndex(source, feedback)

View File

@ -41,6 +41,7 @@ from qgis.core import (QgsFeatureRequest,
QgsFeatureSink,
QgsProcessingParameterFeatureSource,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterEnum,
QgsProcessingParameterField,
QgsProcessingParameterNumber,
@ -108,8 +109,14 @@ class PointDistance(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
source_field = self.parameterAsString(parameters, self.INPUT_FIELD, context)
target_source = self.parameterAsSource(parameters, self.TARGET, context)
if target_source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.TARGET))
target_field = self.parameterAsString(parameters, self.TARGET_FIELD, context)
same_source_and_target = parameters[self.INPUT] == parameters[self.TARGET]
matType = self.parameterAsEnum(parameters, self.MATRIX_TYPE, context)

View File

@ -36,6 +36,7 @@ from qgis.core import (QgsFeature,
QgsWkbTypes,
QgsField,
QgsProcessing,
QgsProcessingException,
QgsProcessingUtils,
QgsProcessingParameterDistance,
QgsProcessingParameterNumber,
@ -90,6 +91,9 @@ class PointsAlongGeometry(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
distance = self.parameterAsDouble(parameters, self.DISTANCE, context)
start_offset = self.parameterAsDouble(parameters, self.START_OFFSET, context)
end_offset = self.parameterAsDouble(parameters, self.END_OFFSET, context)

View File

@ -32,6 +32,7 @@ from qgis.core import (QgsFeatureSink,
QgsSpatialIndex,
QgsRectangle,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterDistance,
QgsProcessingParameterNumber,
@ -78,6 +79,9 @@ class PointsDisplacement(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
proximity = self.parameterAsDouble(parameters, self.PROXIMITY, context)
radius = self.parameterAsDouble(parameters, self.DISTANCE, context)
horizontal = self.parameterAsBool(parameters, self.HORIZONTAL, context)

View File

@ -35,6 +35,7 @@ from qgis.core import (QgsFeature,
QgsPointXY,
QgsWkbTypes,
QgsProcessing,
QgsProcessingException,
QgsFeatureRequest,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterFeatureSource,
@ -74,6 +75,8 @@ class PointsFromLines(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT_VECTOR, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
raster_layer = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER, context)
rasterPath = raster_layer.source()

View File

@ -36,6 +36,7 @@ from qgis.core import (QgsFeatureRequest,
QgsProcessingParameterBand,
QgsPoint,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink)
@ -74,6 +75,8 @@ class PointsFromPolygons(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT_VECTOR, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
raster_layer = self.parameterAsRasterLayer(parameters, self.INPUT_RASTER, context)
rasterPath = raster_layer.source()

View File

@ -36,6 +36,7 @@ from qgis.core import (QgsGeometry,
QgsFeature,
QgsField,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterFeatureSink,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterString,
@ -91,7 +92,12 @@ class PointsInPolygon(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
poly_source = self.parameterAsSource(parameters, self.POLYGONS, context)
if poly_source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.POLYGONS))
point_source = self.parameterAsSource(parameters, self.POINTS, context)
if point_source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.POINTS))
weight_field = self.parameterAsString(parameters, self.WEIGHT, context)
weight_field_index = -1

View File

@ -31,6 +31,7 @@ from qgis.core import (QgsApplication,
QgsFeatureRequest,
QgsGeometry,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterFeatureSink,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterCrs,
@ -86,6 +87,8 @@ class PointsLayerFromTable(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
fields = source.fields()
x_field_index = fields.lookupField(self.parameterAsString(parameters, self.XFIELD, context))

View File

@ -38,6 +38,7 @@ from qgis.core import (QgsFeature,
QgsLineString,
QgsWkbTypes,
QgsFeatureRequest,
QgsProcessingException,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterField,
QgsProcessingParameterString,
@ -93,6 +94,9 @@ class PointsToPaths(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
group_field_name = self.parameterAsString(parameters, self.GROUP_FIELD, context)
order_field_name = self.parameterAsString(parameters, self.ORDER_FIELD, context)
date_format = self.parameterAsString(parameters, self.DATE_FORMAT, context)

View File

@ -29,7 +29,8 @@ import plotly as plt
import plotly.graph_objs as go
import numpy as np
from qgis.core import (QgsProcessingParameterFeatureSource,
from qgis.core import (QgsProcessingException,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterField,
QgsProcessingParameterFileDestination)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
@ -70,6 +71,9 @@ class PolarPlot(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
namefieldname = self.parameterAsString(parameters, self.NAME_FIELD, context) # NOQA FIXME unused?
valuefieldname = self.parameterAsString(parameters, self.VALUE_FIELD, context)

View File

@ -86,6 +86,9 @@ class PoleOfInaccessibility(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context)
fields = source.fields()

View File

@ -33,6 +33,7 @@ from qgis.core import (QgsFields,
QgsWkbTypes,
QgsFeatureRequest,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterBoolean,
QgsProcessingParameterFeatureSink)
@ -72,6 +73,9 @@ class Polygonize(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
if self.parameterAsBool(parameters, self.KEEP_FIELDS, context):
fields = source.fields()
else:

View File

@ -78,6 +78,9 @@ class RandomExtract(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
method = self.parameterAsEnum(parameters, self.METHOD, context)
features = source.getFeatures(QgsFeatureRequest(), QgsProcessingFeatureSource.FlagSkipGeometryValidityChecks)

View File

@ -84,6 +84,9 @@ class RandomExtractWithinSubsets(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
method = self.parameterAsEnum(parameters, self.METHOD, context)
field = self.parameterAsString(parameters, self.FIELD, context)

View File

@ -90,6 +90,9 @@ class RandomPointsAlongLines(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
pointCount = self.parameterAsDouble(parameters, self.POINTS_NUMBER, context)
minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context)

View File

@ -95,6 +95,9 @@ class RandomPointsLayer(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
pointCount = self.parameterAsDouble(parameters, self.POINTS_NUMBER, context)
minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context)

View File

@ -108,6 +108,9 @@ class RandomPointsPolygons(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
strategy = self.parameterAsEnum(parameters, self.STRATEGY, context)
minDistance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context)

View File

@ -32,6 +32,7 @@ from qgis.core import (QgsProcessingParameterFeatureSource,
QgsProcessingParameterNumber,
QgsProcessingParameterFeatureSink,
QgsProcessingParameterDistance,
QgsProcessingException,
QgsFeature,
QgsFeatureSink,
QgsGeometry,
@ -93,6 +94,9 @@ class RectanglesOvalsDiamondsFixed(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
shape = self.parameterAsEnum(parameters, self.SHAPE, context)
width = self.parameterAsDouble(parameters, self.WIDTH, context)
height = self.parameterAsDouble(parameters, self.HEIGHT, context)

View File

@ -33,6 +33,7 @@ from qgis.core import (QgsWkbTypes,
QgsGeometry,
QgsPointXY,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterField,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterEnum,
@ -102,6 +103,9 @@ class RectanglesOvalsDiamondsVariable(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
shape = self.parameterAsEnum(parameters, self.SHAPE, context)
width_field = self.parameterAsString(parameters, self.WIDTH, context)

View File

@ -42,6 +42,7 @@ from qgis.core import (QgsWkbTypes,
QgsPointXY,
QgsField,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterBoolean,
QgsProcessingParameterDistance,
QgsProcessingParameterEnum,
@ -177,7 +178,13 @@ class ServiceAreaFromLayer(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
network = self.parameterAsSource(parameters, self.INPUT, context)
if network is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
startPoints = self.parameterAsSource(parameters, self.START_POINTS, context)
if startPoints is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.START_POINTS))
strategy = self.parameterAsEnum(parameters, self.STRATEGY, context)
travelCost = self.parameterAsDouble(parameters, self.TRAVEL_COST, context)

View File

@ -40,6 +40,7 @@ from qgis.core import (QgsWkbTypes,
QgsFields,
QgsField,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterBoolean,
QgsProcessingParameterDistance,
QgsProcessingParameterEnum,
@ -175,6 +176,9 @@ class ServiceAreaFromPoint(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
network = self.parameterAsSource(parameters, self.INPUT, context)
if network is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
startPoint = self.parameterAsPoint(parameters, self.START_POINT, context, network.sourceCrs())
strategy = self.parameterAsEnum(parameters, self.STRATEGY, context)
travelCost = self.parameterAsDouble(parameters, self.TRAVEL_COST, context)

View File

@ -40,6 +40,7 @@ from qgis.core import (QgsWkbTypes,
QgsField,
QgsPointXY,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterEnum,
QgsProcessingParameterPoint,
QgsProcessingParameterField,
@ -160,7 +161,13 @@ class ShortestPathLayerToPoint(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
network = self.parameterAsSource(parameters, self.INPUT, context)
if network is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
startPoints = self.parameterAsSource(parameters, self.START_POINTS, context)
if startPoints is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.START_POINTS))
endPoint = self.parameterAsPoint(parameters, self.END_POINT, context, network.sourceCrs())
strategy = self.parameterAsEnum(parameters, self.STRATEGY, context)

View File

@ -41,6 +41,7 @@ from qgis.core import (NULL,
QgsField,
QgsPointXY,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterEnum,
QgsProcessingParameterDistance,
QgsProcessingParameterPoint,
@ -161,8 +162,14 @@ class ShortestPathPointToLayer(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
network = self.parameterAsSource(parameters, self.INPUT, context)
if network is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
startPoint = self.parameterAsPoint(parameters, self.START_POINT, context, network.sourceCrs())
endPoints = self.parameterAsSource(parameters, self.END_POINTS, context)
if endPoints is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.END_POINTS))
strategy = self.parameterAsEnum(parameters, self.STRATEGY, context)
directionFieldName = self.parameterAsString(parameters, self.DIRECTION_FIELD, context)

View File

@ -163,6 +163,9 @@ class ShortestPathPointToPoint(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
network = self.parameterAsSource(parameters, self.INPUT, context)
if network is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
startPoint = self.parameterAsPoint(parameters, self.START_POINT, context, network.sourceCrs())
endPoint = self.parameterAsPoint(parameters, self.END_POINT, context, network.sourceCrs())
strategy = self.parameterAsEnum(parameters, self.STRATEGY, context)

View File

@ -29,6 +29,7 @@ from qgis.analysis import (QgsGeometrySnapper,
QgsInternalGeometrySnapper)
from qgis.core import (QgsFeatureSink,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterDistance,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink,
@ -87,8 +88,13 @@ class SnapGeometriesToLayer(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
reference_source = self.parameterAsSource(parameters, self.REFERENCE_LAYER, context)
if reference_source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.REFERENCE_LAYER))
tolerance = self.parameterAsDouble(parameters, self.TOLERANCE, context)
mode = self.parameterAsEnum(parameters, self.BEHAVIOR, context)

View File

@ -35,6 +35,7 @@ from qgis.core import (QgsFields,
QgsGeometry,
QgsProcessing,
QgsProcessingUtils,
QgsProcessingException,
QgsProcessingParameterBoolean,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterEnum,
@ -131,7 +132,13 @@ class SpatialJoin(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
join_source = self.parameterAsSource(parameters, self.JOIN, context)
if join_source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.JOIN))
join_fields = self.parameterAsFields(parameters, self.JOIN_FIELDS, context)
method = self.parameterAsEnum(parameters, self.METHOD, context)
discard_nomatch = self.parameterAsBool(parameters, self.DISCARD_NONMATCHING, context)

View File

@ -43,6 +43,7 @@ from qgis.core import (NULL,
QgsStringStatisticalSummary,
QgsProcessing,
QgsProcessingUtils,
QgsProcessingException,
QgsProcessingParameterBoolean,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterEnum,
@ -151,7 +152,13 @@ class SpatialJoinSummary(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
join_source = self.parameterAsSource(parameters, self.JOIN, context)
if join_source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.JOIN))
join_fields = self.parameterAsFields(parameters, self.JOIN_FIELDS, context)
discard_nomatch = self.parameterAsBool(parameters, self.DISCARD_NONMATCHING, context)
summaries = [self.statistics[i][0] for i in

View File

@ -30,6 +30,7 @@ from qgis.core import (QgsProcessingParameterFeatureSource,
QgsDateTimeStatisticalSummary,
QgsStringStatisticalSummary,
QgsFeatureRequest,
QgsProcessingException,
QgsProcessingParameterField,
QgsProcessingParameterFeatureSink,
QgsFields,
@ -88,6 +89,9 @@ class StatisticsByCategories(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
value_field_name = self.parameterAsString(parameters, self.VALUES_FIELD_NAME, context)
category_field_names = self.parameterAsFields(parameters, self.CATEGORIES_FIELD_NAME, context)

View File

@ -37,6 +37,7 @@ from qgis.core import (QgsFeature,
QgsDistanceArea,
QgsProject,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterString,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink,
@ -87,7 +88,12 @@ class SumLines(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
line_source = self.parameterAsSource(parameters, self.LINES, context)
if line_source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.LINES))
poly_source = self.parameterAsSource(parameters, self.POLYGONS, context)
if poly_source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.POLYGONS))
length_field_name = self.parameterAsString(parameters, self.LEN_FIELD, context)
count_field_name = self.parameterAsString(parameters, self.COUNT_FIELD, context)

View File

@ -38,6 +38,7 @@ from qgis.core import (QgsField,
QgsPointXY,
NULL,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterNumber,
QgsProcessingParameterEnum,
@ -96,6 +97,9 @@ class TopoColor(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
min_colors = self.parameterAsInt(parameters, self.MIN_COLORS, context)
balance_by = self.parameterAsEnum(parameters, self.BALANCE, context)
min_distance = self.parameterAsDouble(parameters, self.MIN_DISTANCE, context)

View File

@ -37,6 +37,7 @@ from qgis.core import (QgsCoordinateReferenceSystem,
QgsFeatureRequest,
QgsFields,
QgsProcessing,
QgsProcessingException,
QgsProcessingParameterField,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink,
@ -92,6 +93,9 @@ class UniqueValues(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
field_names = self.parameterAsFields(parameters, self.FIELDS, context)
fields = QgsFields()

View File

@ -31,6 +31,7 @@ from qgis.PyQt.QtGui import QIcon
from qgis.core import (QgsWkbTypes,
QgsProcessing,
QgsProcessingException,
QgsProcessingAlgorithm,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterField,
@ -111,6 +112,8 @@ class VariableDistanceBuffer(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
dissolve = self.parameterAsBool(parameters, self.DISSOLVE, context)
segments = self.parameterAsInt(parameters, self.SEGMENTS, context)

View File

@ -28,7 +28,8 @@ __revision__ = '$Format:%H$'
import plotly as plt
import plotly.graph_objs as go
from qgis.core import (QgsProcessingParameterFeatureSource,
from qgis.core import (QgsProcessingException,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterField,
QgsProcessingParameterNumber,
QgsProcessingParameterFileDestination)
@ -71,6 +72,9 @@ class VectorLayerHistogram(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
fieldname = self.parameterAsString(parameters, self.FIELD, context)
bins = self.parameterAsInt(parameters, self.BINS, context)

View File

@ -28,7 +28,8 @@ __revision__ = '$Format:%H$'
import plotly as plt
import plotly.graph_objs as go
from qgis.core import (QgsProcessingParameterFeatureSource,
from qgis.core import (QgsProcessingException,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterField,
QgsProcessingUtils,
QgsProcessingParameterFileDestination)
@ -74,6 +75,9 @@ class VectorLayerScatterplot(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
xfieldname = self.parameterAsString(parameters, self.XFIELD, context)
yfieldname = self.parameterAsString(parameters, self.YFIELD, context)

View File

@ -31,7 +31,8 @@ import plotly.graph_objs as go
from qgis.core import (QgsProcessingParameterFeatureSource,
QgsProcessingParameterField,
QgsProcessingParameterFileDestination,
QgsProcessingUtils)
QgsProcessingUtils,
QgsProcessingException)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.tools import vector
@ -80,6 +81,9 @@ class VectorLayerScatterplot3D(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
xfieldname = self.parameterAsString(parameters, self.XFIELD, context)
yfieldname = self.parameterAsString(parameters, self.YFIELD, context)
zfieldname = self.parameterAsString(parameters, self.ZFIELD, context)

View File

@ -33,6 +33,7 @@ from qgis.core import (QgsProcessingUtils,
QgsProcessingParameterField,
QgsProcessingParameterFolderDestination,
QgsProcessingOutputFolder,
QgsProcessingException,
QgsProcessingOutputMultipleLayers,
QgsExpression,
QgsFeatureRequest)
@ -78,6 +79,9 @@ class VectorSplit(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
fieldName = self.parameterAsString(parameters, self.FIELD, context)
directory = self.parameterAsString(parameters, self.OUTPUT, context)

View File

@ -82,6 +82,9 @@ class VoronoiPolygons(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
buf = self.parameterAsDouble(parameters, self.BUFFER, context)
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
source.fields(), QgsWkbTypes.Polygon, source.sourceCrs())

View File

@ -193,6 +193,9 @@ class SagaAlgorithm(SagaAlgorithmBase):
if not crs:
source = self.parameterAsSource(parameters, param.name(), context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, param.name()))
crs = source.sourceCrs()
layer_path = self.parameterAsCompatibleSourceLayerPath(parameters, param.name(), context, ['shp'], 'shp', feedback=feedback)
@ -229,6 +232,9 @@ class SagaAlgorithm(SagaAlgorithmBase):
if not crs:
source = self.parameterAsSource(temp_params, param.name(), context)
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, param.name()))
crs = source.sourceCrs()
layer_path = self.parameterAsCompatibleSourceLayerPath(temp_params, param.name(), context, 'shp',

View File

@ -3,6 +3,7 @@
from PyQt5.QtCore import QCoreApplication
from qgis.core import (QgsProcessing,
QgsFeatureSink,
QgsProcessingException,
QgsProcessingAlgorithm,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink)
@ -120,6 +121,14 @@ class ExampleProcessingAlgorithm(QgsProcessingAlgorithm):
self.INPUT,
context
)
# If source was not found, throw an exception to indicate that the algorithm
# encountered a fatal error. The exception text can be any string, but in this
# case we use the pre-built invalidSourceError method to return a standard
# helper text for when a source cannot be evaluated
if source is None:
raise QgsProcessingException(self.invalidSourceError(parameters, self.INPUT))
(sink, dest_id) = self.parameterAsSink(
parameters,
self.OUTPUT,

View File

@ -81,12 +81,12 @@ QVariantMap QgsBufferAlgorithm::processAlgorithm( const QVariantMap &parameters,
{
std::unique_ptr< QgsFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !source )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
QString dest;
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, source->fields(), QgsWkbTypes::Polygon, source->sourceCrs() ) );
if ( !sink )
throw QgsProcessingException( QObject::tr( "Could not create destination layer for OUTPUT" ) );
throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );
// fixed parameters
bool dissolve = parameterAsBool( parameters, QStringLiteral( "DISSOLVE" ), context );

View File

@ -71,11 +71,11 @@ QVariantMap QgsClipAlgorithm::processAlgorithm( const QVariantMap &parameters, Q
{
std::unique_ptr< QgsFeatureSource > featureSource( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !featureSource )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
std::unique_ptr< QgsFeatureSource > maskSource( parameterAsSource( parameters, QStringLiteral( "OVERLAY" ), context ) );
if ( !maskSource )
throw QgsProcessingException( QObject::tr( "Could not load source layer for OVERLAY" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "OVERLAY" ) ) );
QString dest;
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, featureSource->fields(), QgsWkbTypes::multiType( featureSource->wkbType() ), featureSource->sourceCrs() ) );

View File

@ -64,11 +64,11 @@ QVariantMap QgsDifferenceAlgorithm::processAlgorithm( const QVariantMap &paramet
{
std::unique_ptr< QgsFeatureSource > sourceA( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !sourceA )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
std::unique_ptr< QgsFeatureSource > sourceB( parameterAsSource( parameters, QStringLiteral( "OVERLAY" ), context ) );
if ( !sourceB )
throw QgsProcessingException( QObject::tr( "Could not load source layer for OVERLAY" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "OVERLAY" ) ) );
QgsWkbTypes::Type geomType = QgsWkbTypes::multiType( sourceA->wkbType() );

View File

@ -28,7 +28,7 @@ QVariantMap QgsCollectorAlgorithm::processCollection( const QVariantMap &paramet
{
std::unique_ptr< QgsFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !source )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
QString dest;
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, source->fields(), QgsWkbTypes::multiType( source->wkbType() ), source->sourceCrs() ) );

View File

@ -85,7 +85,7 @@ QVariantMap QgsExtractByAttributeAlgorithm::processAlgorithm( const QVariantMap
{
std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !source )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
QString fieldName = parameterAsString( parameters, QStringLiteral( "FIELD" ), context );
Operation op = static_cast< Operation >( parameterAsEnum( parameters, QStringLiteral( "OPERATOR" ), context ) );

View File

@ -72,7 +72,7 @@ QVariantMap QgsExtractByExpressionAlgorithm::processAlgorithm( const QVariantMap
{
std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !source )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
QString expressionString = parameterAsExpression( parameters, QStringLiteral( "EXPRESSION" ), context );

View File

@ -68,7 +68,7 @@ QVariantMap QgsExtractByExtentAlgorithm::processAlgorithm( const QVariantMap &pa
{
std::unique_ptr< QgsFeatureSource > featureSource( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !featureSource )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
QgsRectangle extent = parameterAsExtent( parameters, QStringLiteral( "EXTENT" ), context, featureSource->sourceCrs() );
bool clip = parameterAsBool( parameters, QStringLiteral( "CLIP" ), context );

View File

@ -269,8 +269,14 @@ QgsSelectByLocationAlgorithm *QgsSelectByLocationAlgorithm::createInstance() con
QVariantMap QgsSelectByLocationAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
{
QgsVectorLayer *selectLayer = parameterAsVectorLayer( parameters, QStringLiteral( "INPUT" ), context );
if ( !selectLayer )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
QgsVectorLayer::SelectBehavior method = static_cast< QgsVectorLayer::SelectBehavior >( parameterAsEnum( parameters, QStringLiteral( "METHOD" ), context ) );
std::unique_ptr< QgsFeatureSource > intersectSource( parameterAsSource( parameters, QStringLiteral( "INTERSECT" ), context ) );
if ( !intersectSource )
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INTERSECT" ) ) );
const QList< int > selectedPredicates = parameterAsEnums( parameters, QStringLiteral( "PREDICATE" ), context );
QgsFeatureIds selectedIds;

View File

@ -70,7 +70,7 @@ QVariantMap QgsExtractVerticesAlgorithm::processAlgorithm( const QVariantMap &pa
{
std::unique_ptr< QgsProcessingFeatureSource > featureSource( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !featureSource )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
QgsWkbTypes::Type outputWkbType = QgsWkbTypes::Point;
if ( QgsWkbTypes::hasM( featureSource->wkbType() ) )

View File

@ -90,7 +90,7 @@ QVariantMap QgsFilterAlgorithm::processAlgorithm( const QVariantMap &parameters,
{
std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !source )
throw QgsProcessingException( QObject::tr( "Could not open input layer or feature source for parameter INPUT." ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
QgsExpressionContext expressionContext = createExpressionContext( parameters, context, source.get() );
for ( Output *output : qgis::as_const( mOutputs ) )

View File

@ -77,11 +77,11 @@ QVariantMap QgsIntersectionAlgorithm::processAlgorithm( const QVariantMap &param
{
std::unique_ptr< QgsFeatureSource > sourceA( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !sourceA )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
std::unique_ptr< QgsFeatureSource > sourceB( parameterAsSource( parameters, QStringLiteral( "OVERLAY" ), context ) );
if ( !sourceB )
throw QgsProcessingException( QObject::tr( "Could not load source layer for OVERLAY" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "OVERLAY" ) ) );
QgsWkbTypes::Type geomType = QgsWkbTypes::multiType( sourceA->wkbType() );

View File

@ -94,9 +94,12 @@ QVariantMap QgsJoinByAttributeAlgorithm::processAlgorithm( const QVariantMap &pa
bool discardNonMatching = parameterAsBool( parameters, QStringLiteral( "DISCARD_NONMATCHING" ), context );
std::unique_ptr< QgsProcessingFeatureSource > input( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !input )
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
std::unique_ptr< QgsProcessingFeatureSource > input2( parameterAsSource( parameters, QStringLiteral( "INPUT_2" ), context ) );
if ( !input || !input2 )
throw QgsProcessingException( QObject::tr( "Could not load source layers" ) );
if ( !input2 )
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT_2" ) ) );
QString field1Name = parameterAsString( parameters, QStringLiteral( "FIELD" ), context );
QString field2Name = parameterAsString( parameters, QStringLiteral( "FIELD_2" ), context );

View File

@ -88,9 +88,12 @@ QVariantMap QgsJoinWithLinesAlgorithm::processAlgorithm( const QVariantMap &para
throw QgsProcessingException( QObject::tr( "Same layer given for both hubs and spokes" ) );
std::unique_ptr< QgsProcessingFeatureSource > hubSource( parameterAsSource( parameters, QStringLiteral( "HUBS" ), context ) );
if ( !hubSource )
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "HUBS" ) ) );
std::unique_ptr< QgsProcessingFeatureSource > spokeSource( parameterAsSource( parameters, QStringLiteral( "SPOKES" ), context ) );
if ( !hubSource || !spokeSource )
throw QgsProcessingException( QObject::tr( "Could not load source layers" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "SPOKES" ) ) );
QString fieldHubName = parameterAsString( parameters, QStringLiteral( "HUB_FIELD" ), context );
int fieldHubIndex = hubSource->fields().lookupField( fieldHubName );

View File

@ -80,11 +80,11 @@ QVariantMap QgsLineIntersectionAlgorithm::processAlgorithm( const QVariantMap &p
{
std::unique_ptr< QgsFeatureSource > sourceA( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !sourceA )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
std::unique_ptr< QgsFeatureSource > sourceB( parameterAsSource( parameters, QStringLiteral( "INTERSECT" ), context ) );
if ( !sourceB )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INTERSECT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INTERSECT" ) ) );
const QStringList fieldsA = parameterAsFields( parameters, QStringLiteral( "INPUT_FIELDS" ), context );
const QStringList fieldsB = parameterAsFields( parameters, QStringLiteral( "INTERSECT_FIELDS" ), context );

View File

@ -75,7 +75,7 @@ QVariantMap QgsMeanCoordinatesAlgorithm::processAlgorithm( const QVariantMap &pa
{
std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !source )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
QString weightFieldName = parameterAsString( parameters, QStringLiteral( "WEIGHT" ), context );
QString uniqueFieldName = parameterAsString( parameters, QStringLiteral( "UID" ), context );

View File

@ -71,7 +71,7 @@ QVariantMap QgsOrderByExpressionAlgorithm::processAlgorithm( const QVariantMap &
{
std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !source )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
QString expressionString = parameterAsExpression( parameters, QStringLiteral( "EXPRESSION" ), context );

View File

@ -72,7 +72,7 @@ QVariantMap QgsRemoveNullGeometryAlgorithm::processAlgorithm( const QVariantMap
{
std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !source )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
QString nonNullSinkId;
std::unique_ptr< QgsFeatureSink > nonNullSink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, nonNullSinkId, source->fields(),

View File

@ -69,11 +69,11 @@ QVariantMap QgsSplitWithLinesAlgorithm::processAlgorithm( const QVariantMap &par
{
std::unique_ptr< QgsFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !source )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
std::unique_ptr< QgsFeatureSource > linesSource( parameterAsSource( parameters, QStringLiteral( "LINES" ), context ) );
if ( !linesSource )
throw QgsProcessingException( QObject::tr( "Could not load source layer for LINES" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "LINES" ) ) );
bool sameLayer = parameters.value( QStringLiteral( "INPUT" ) ) == parameters.value( QStringLiteral( "LINES" ) );

View File

@ -61,11 +61,11 @@ QVariantMap QgsSymmetricalDifferenceAlgorithm::processAlgorithm( const QVariantM
{
std::unique_ptr< QgsFeatureSource > sourceA( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !sourceA )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
std::unique_ptr< QgsFeatureSource > sourceB( parameterAsSource( parameters, QStringLiteral( "OVERLAY" ), context ) );
if ( !sourceB )
throw QgsProcessingException( QObject::tr( "Could not load source layer for OVERLAY" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "OVERLAY" ) ) );
QgsWkbTypes::Type geomType = QgsWkbTypes::multiType( sourceA->wkbType() );

View File

@ -110,7 +110,7 @@ QVariantMap QgsTransectAlgorithm::processAlgorithm( const QVariantMap &parameter
std::unique_ptr< QgsFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !source )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
QgsExpressionContext expressionContext = createExpressionContext( parameters, context, dynamic_cast< QgsProcessingFeatureSource * >( source.get() ) );

View File

@ -63,11 +63,11 @@ QVariantMap QgsUnionAlgorithm::processAlgorithm( const QVariantMap &parameters,
{
std::unique_ptr< QgsFeatureSource > sourceA( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !sourceA )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
std::unique_ptr< QgsFeatureSource > sourceB( parameterAsSource( parameters, QStringLiteral( "OVERLAY" ), context ) );
if ( !sourceB )
throw QgsProcessingException( QObject::tr( "Could not load source layer for OVERLAY" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "OVERLAY" ) ) );
QgsWkbTypes::Type geomType = QgsWkbTypes::multiType( sourceA->wkbType() );

View File

@ -79,7 +79,7 @@ QVariantMap QgsAddUniqueValueIndexAlgorithm::processAlgorithm( const QVariantMap
{
std::unique_ptr< QgsProcessingFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !source )
throw QgsProcessingException( QObject::tr( "Could not load source layer for INPUT" ) );
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
QString newFieldName = parameterAsString( parameters, QStringLiteral( "FIELD_NAME" ), context );
QgsFields fields = source->fields();

View File

@ -91,7 +91,16 @@ bool QgsProcessingAlgorithm::checkParameterValues( const QVariantMap &parameters
if ( !def->checkValueIsAcceptable( parameters.value( def->name() ), &context ) )
{
if ( message )
*message = QObject::tr( "Incorrect parameter value for %1" ).arg( def->name() );
{
// TODO QGIS 4 - move the message handling to the parameter subclasses (but this
// requires a change in signature for the virtual checkValueIsAcceptable method)
if ( def->type() == QgsProcessingParameterFeatureSource::typeName() )
*message = invalidSourceError( parameters, def->name() );
else if ( def->type() == QgsProcessingParameterFeatureSink::typeName() )
*message = invalidSinkError( parameters, def->name() );
else
*message = QObject::tr( "Incorrect parameter value for %1" ).arg( def->name() );
}
return false;
}
}
@ -633,6 +642,60 @@ QStringList QgsProcessingAlgorithm::parameterAsFields( const QVariantMap &parame
return QgsProcessingParameters::parameterAsFields( parameterDefinition( name ), parameters, context );
}
QString QgsProcessingAlgorithm::invalidSourceError( const QVariantMap &parameters, const QString &name )
{
if ( !parameters.contains( name ) )
return QObject::tr( "Could not load source layer for %1: no value specified for parameter" ).arg( name );
else
{
QVariant var = parameters.value( name );
if ( var.canConvert<QgsProcessingFeatureSourceDefinition>() )
{
QgsProcessingFeatureSourceDefinition fromVar = qvariant_cast<QgsProcessingFeatureSourceDefinition>( var );
var = fromVar.source;
}
if ( var.canConvert<QgsProperty>() )
{
QgsProperty p = var.value< QgsProperty >();
if ( p.propertyType() == QgsProperty::StaticProperty )
{
var = p.staticValue();
}
}
if ( !var.toString().isEmpty() )
return QObject::tr( "Could not load source layer for %1: %2 not found" ).arg( name, var.toString() );
else
return QObject::tr( "Could not load source layer for %1: invalid value" ).arg( name );
}
}
QString QgsProcessingAlgorithm::invalidSinkError( const QVariantMap &parameters, const QString &name )
{
if ( !parameters.contains( name ) )
return QObject::tr( "Could not create destination layer for %1: no value specified for parameter" ).arg( name );
else
{
QVariant var = parameters.value( name );
if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
{
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
var = fromVar.sink;
}
if ( var.canConvert<QgsProperty>() )
{
QgsProperty p = var.value< QgsProperty >();
if ( p.propertyType() == QgsProperty::StaticProperty )
{
var = p.staticValue();
}
}
if ( !var.toString().isEmpty() )
return QObject::tr( "Could not create destination layer for %1: %2" ).arg( name, var.toString() );
else
return QObject::tr( "Could not create destination layer for %1: invalid value" ).arg( name );
}
}
bool QgsProcessingAlgorithm::createAutoOutputForParameter( QgsProcessingParameterDefinition *parameter )
{
if ( !parameter->isDestination() )
@ -712,7 +775,7 @@ QVariantMap QgsProcessingFeatureBasedAlgorithm::processAlgorithm( const QVariant
{
mSource.reset( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !mSource )
return QVariantMap();
throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );
QString dest;
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest,
@ -766,3 +829,4 @@ QgsFeatureRequest QgsProcessingFeatureBasedAlgorithm::request() const
{
return QgsFeatureRequest();
}

View File

@ -744,6 +744,32 @@ class CORE_EXPORT QgsProcessingAlgorithm
*/
QStringList parameterAsFields( const QVariantMap &parameters, const QString &name, QgsProcessingContext &context ) const;
/**
* Returns a user-friendly string to use as an error when a source parameter could
* not be loaded.
*
* The \a parameters argument should give the algorithms parameter map, and the \a name
* should correspond to the invalid source parameter name.
*
* \since QGIS 3.2
*
* \see invalidSinkError()
*/
static QString invalidSourceError( const QVariantMap &parameters, const QString &name );
/**
* Returns a user-friendly string to use as an error when a sink parameter could
* not be created.
*
* The \a parameters argument should give the algorithms parameter map, and the \a name
* should correspond to the invalid source parameter name.
*
* \since QGIS 3.2
*
* \see invalidSourceError()
*/
static QString invalidSinkError( const QVariantMap &parameters, const QString &name );
private:
QgsProcessingProvider *mProvider = nullptr;

View File

@ -4220,6 +4220,19 @@ void TestQgsProcessing::parameterFeatureSource()
//optional with direct layer default
def.reset( new QgsProcessingParameterFeatureSource( "optional", QString(), QList< int >() << QgsProcessing::TypeVectorAnyGeometry, QVariant::fromValue( v1 ), true ) );
QCOMPARE( QgsProcessingParameters::parameterAsVectorLayer( def.get(), params, context )->id(), v1->id() );
// invalidSourceError
params.clear();
QCOMPARE( QgsProcessingAlgorithm::invalidSourceError( params, QStringLiteral( "MISSING" ) ), QStringLiteral( "Could not load source layer for MISSING: no value specified for parameter" ) );
params.insert( QStringLiteral( "INPUT" ), QStringLiteral( "my layer" ) );
QCOMPARE( QgsProcessingAlgorithm::invalidSourceError( params, QStringLiteral( "INPUT" ) ), QStringLiteral( "Could not load source layer for INPUT: my layer not found" ) );
params.insert( QStringLiteral( "INPUT" ), QgsProperty::fromValue( "my prop layer" ) );
QCOMPARE( QgsProcessingAlgorithm::invalidSourceError( params, QStringLiteral( "INPUT" ) ), QStringLiteral( "Could not load source layer for INPUT: my prop layer not found" ) );
params.insert( QStringLiteral( "INPUT" ), QgsProcessingFeatureSourceDefinition( QStringLiteral( "my prop layer" ) ) );
QCOMPARE( QgsProcessingAlgorithm::invalidSourceError( params, QStringLiteral( "INPUT" ) ), QStringLiteral( "Could not load source layer for INPUT: my prop layer not found" ) );
params.insert( QStringLiteral( "INPUT" ), QVariant::fromValue( v1 ) );
QCOMPARE( QgsProcessingAlgorithm::invalidSourceError( params, QStringLiteral( "INPUT" ) ), QStringLiteral( "Could not load source layer for INPUT: invalid value" ) );
}
void TestQgsProcessing::parameterFeatureSink()