Merge pull request #4761 from nyalldawson/algs2

Port more processing algs to new API
This commit is contained in:
Nyall Dawson 2017-06-22 06:40:32 +10:00 committed by GitHub
commit b01cae0740
23 changed files with 1240 additions and 367 deletions

View File

@ -163,14 +163,16 @@ class QgsProcessingParameterDefinition
sipType = sipType_QgsProcessingParameterString;
else if ( sipCpp->type() == "expression" )
sipType = sipType_QgsProcessingParameterExpression;
else if ( sipCpp->type() == "table" )
sipType = sipType_QgsProcessingParameterTable;
else if ( sipCpp->type() == "vector" )
sipType = sipType_QgsProcessingParameterVectorLayer;
else if ( sipCpp->type() == "field" )
sipType = sipType_QgsProcessingParameterTableField;
sipType = sipType_QgsProcessingParameterField;
else if ( sipCpp->type() == "source" )
sipType = sipType_QgsProcessingParameterFeatureSource;
else if ( sipCpp->type() == "sink" )
sipType = sipType_QgsProcessingParameterFeatureSink;
else if ( sipCpp->type() == "vectorOut" )
sipType = sipType_QgsProcessingParameterVectorOutput;
else if ( sipCpp->type() == "rasterOut" )
sipType = sipType_QgsProcessingParameterRasterOutput;
else if ( sipCpp->type() == "fileOut" )
@ -1153,10 +1155,11 @@ class QgsProcessingParameterExpression : QgsProcessingParameterDefinition
};
class QgsProcessingParameterTable : QgsProcessingParameterDefinition
class QgsProcessingParameterVectorLayer : QgsProcessingParameterDefinition
{
%Docstring
A table (i.e. vector layers with or without geometry) parameter for processing algorithms.
A vector layer (with or without geometry) parameter for processing algorithms. Consider using
the more versatile QgsProcessingParameterFeatureSource wherever possible.
.. versionadded:: 3.0
%End
@ -1165,20 +1168,24 @@ class QgsProcessingParameterTable : QgsProcessingParameterDefinition
%End
public:
QgsProcessingParameterTable( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
bool optional = false );
QgsProcessingParameterVectorLayer( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
bool optional = false );
%Docstring
Constructor for QgsProcessingParameterTable.
Constructor for QgsProcessingParameterVectorLayer.
%End
virtual QString type() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
virtual QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const;
};
class QgsProcessingParameterTableField : QgsProcessingParameterDefinition
class QgsProcessingParameterField : QgsProcessingParameterDefinition
{
%Docstring
A table field parameter for processing algorithms.
A vector layer or feature source field parameter for processing algorithms.
.. versionadded:: 3.0
%End
@ -1195,13 +1202,13 @@ class QgsProcessingParameterTableField : QgsProcessingParameterDefinition
DateTime
};
QgsProcessingParameterTableField( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
const QString &parentLayerParameterName = QString(),
DataType type = Any,
bool allowMultiple = false,
bool optional = false );
QgsProcessingParameterField( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
const QString &parentLayerParameterName = QString(),
DataType type = Any,
bool allowMultiple = false,
bool optional = false );
%Docstring
Constructor for QgsProcessingParameterTableField.
Constructor for QgsProcessingParameterField.
%End
virtual QString type() const;
@ -1354,6 +1361,60 @@ class QgsProcessingParameterFeatureSink : QgsProcessingParameterDefinition
virtual bool fromVariantMap( const QVariantMap &map );
};
class QgsProcessingParameterVectorOutput : QgsProcessingParameterDefinition
{
%Docstring
A vector layer output parameter. Consider using the more flexible QgsProcessingParameterFeatureSink wherever
possible.
.. versionadded:: 3.0
%End
%TypeHeaderCode
#include "qgsprocessingparameters.h"
%End
public:
QgsProcessingParameterVectorOutput( const QString &name, const QString &description = QString(), QgsProcessingParameterDefinition::LayerType type = QgsProcessingParameterDefinition::TypeVectorAny, const QVariant &defaultValue = QVariant(),
bool optional = false );
%Docstring
Constructor for QgsProcessingParameterVectorOutput.
%End
virtual QString type() const;
virtual bool isDestination() const;
virtual bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = 0 ) const;
virtual QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const;
QgsProcessingParameterDefinition::LayerType dataType() const;
%Docstring
Returns the layer type for layers associated with the parameter.
.. seealso:: setDataType()
:rtype: QgsProcessingParameterDefinition.LayerType
%End
bool hasGeometry() const;
%Docstring
Returns true if the layer is likely to include geometries. In cases were presence of geometry
cannot be reliably determined in advance, this method will default to returning true.
:rtype: bool
%End
void setDataType( QgsProcessingParameterDefinition::LayerType type );
%Docstring
Sets the layer ``type`` for the layers associated with the parameter.
.. seealso:: dataType()
%End
virtual QVariantMap toVariantMap() const;
virtual bool fromVariantMap( const QVariantMap &map );
};
class QgsProcessingParameterRasterOutput : QgsProcessingParameterDefinition

View File

@ -32,7 +32,7 @@ import plotly.graph_objs as go
from qgis.core import (QgsApplication,
QgsProcessingUtils,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterTableField,
QgsProcessingParameterField,
QgsProcessingParameterFileOutput,
QgsProcessingOutputHtml)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
@ -60,12 +60,12 @@ class BarPlot(QgisAlgorithm):
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
self.tr('Input layer')))
self.addParameter(QgsProcessingParameterTableField(self.NAME_FIELD,
self.tr('Category name field'),
None, self.INPUT, QgsProcessingParameterTableField.Any))
self.addParameter(QgsProcessingParameterTableField(self.VALUE_FIELD,
self.tr('Value field'),
None, self.INPUT, QgsProcessingParameterTableField.Numeric))
self.addParameter(QgsProcessingParameterField(self.NAME_FIELD,
self.tr('Category name field'),
None, self.INPUT, QgsProcessingParameterField.Any))
self.addParameter(QgsProcessingParameterField(self.VALUE_FIELD,
self.tr('Value field'),
None, self.INPUT, QgsProcessingParameterField.Numeric))
self.addParameter(QgsProcessingParameterFileOutput(self.OUTPUT, self.tr('Added'), self.tr('HTML files (*.html)')))

View File

@ -37,7 +37,7 @@ from qgis.core import (QgsStatisticalSummary,
QgsFeatureRequest,
QgsProcessingUtils,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterTableField,
QgsProcessingParameterField,
QgsProcessingParameterFileOutput,
QgsProcessingOutputHtml,
QgsProcessingOutputNumber)
@ -90,9 +90,9 @@ class BasicStatisticsForField(QgisAlgorithm):
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT_LAYER,
self.tr('Input layer')))
self.addParameter(QgsProcessingParameterTableField(self.FIELD_NAME,
self.tr('Field to calculate statistics on'),
None, self.INPUT_LAYER, QgsProcessingParameterTableField.Any))
self.addParameter(QgsProcessingParameterField(self.FIELD_NAME,
self.tr('Field to calculate statistics on'),
None, self.INPUT_LAYER, QgsProcessingParameterField.Any))
self.addParameter(QgsProcessingParameterFileOutput(self.OUTPUT_HTML_FILE, self.tr('Statistics'), self.tr('HTML files (*.html)'), None, True))
self.addOutput(QgsProcessingOutputHtml(self.OUTPUT_HTML_FILE, self.tr('Statistics')))

View File

@ -28,12 +28,12 @@ __revision__ = '$Format:%H$'
from qgis.core import (QgsVectorDataProvider,
QgsFields,
QgsApplication,
QgsProcessingUtils)
QgsProcessingParameterVectorLayer,
QgsProcessingParameterField,
QgsProcessingParameterDefinition,
QgsProcessingOutputVectorLayer)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.parameters import ParameterTable
from processing.core.parameters import ParameterTableField
from processing.core.outputs import OutputVector
class CreateAttributeIndex(QgisAlgorithm):
@ -53,12 +53,11 @@ class CreateAttributeIndex(QgisAlgorithm):
def __init__(self):
super().__init__()
self.addParameter(ParameterTable(self.INPUT,
self.tr('Input Layer')))
self.addParameter(ParameterTableField(self.FIELD,
self.tr('Attribute to index'), self.INPUT))
self.addOutput(OutputVector(self.OUTPUT,
self.tr('Indexed layer'), True))
self.addParameter(QgsProcessingParameterVectorLayer(self.INPUT,
self.tr('Input Layer')))
self.addParameter(QgsProcessingParameterField(self.FIELD,
self.tr('Attribute to index'), None, self.INPUT))
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Indexed layer')))
def name(self):
return 'createattributeindex'
@ -67,9 +66,8 @@ class CreateAttributeIndex(QgisAlgorithm):
return self.tr('Create attribute index')
def processAlgorithm(self, parameters, context, feedback):
file_name = self.getParameterValue(self.INPUT)
layer = QgsProcessingUtils.mapLayerFromString(file_name, context)
field = self.getParameterValue(self.FIELD)
layer = self.parameterAsVectorLayer(parameters, self.INPUT, context)
field = self.parameterAsString(parameters, self.FIELD, context)
provider = layer.dataProvider()
field_index = layer.fields().lookupField(field)
@ -84,4 +82,4 @@ class CreateAttributeIndex(QgisAlgorithm):
feedback.pushInfo(self.tr("Layer's data provider does not support "
"creating attribute indexes"))
self.setOutputValue(self.OUTPUT, file_name)
return {self.OUTPUT: layer.id()}

View File

@ -29,7 +29,7 @@ from qgis.core import (QgsApplication,
QgsProcessingUtils,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink,
QgsProcessingParameterTableField,
QgsProcessingParameterField,
QgsProcessingOutputVectorLayer)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
@ -56,9 +56,9 @@ class DeleteColumn(QgisAlgorithm):
super().__init__()
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT, self.tr('Input layer')))
self.addParameter(QgsProcessingParameterTableField(self.COLUMNS,
self.tr('Fields to delete'),
None, self.INPUT, QgsProcessingParameterTableField.Any, True))
self.addParameter(QgsProcessingParameterField(self.COLUMNS,
self.tr('Fields to delete'),
None, self.INPUT, QgsProcessingParameterField.Any, True))
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Output layer')))
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr("Output layer")))

View File

@ -25,12 +25,13 @@ __copyright__ = '(C) 2015, Etienne Trimaille'
__revision__ = '$Format:%H$'
from qgis.core import (QgsApplication,
QgsProcessingUtils)
QgsProcessingUtils,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterNumber,
QgsProcessingParameterFeatureSink,
QgsProcessingOutputVectorLayer,
QgsProcessingParameterDefinition)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.parameters import (ParameterVector,
ParameterNumber)
from processing.core.outputs import OutputVector
from processing.tools import dataobjects
class DeleteHoles(QgisAlgorithm):
@ -53,12 +54,14 @@ class DeleteHoles(QgisAlgorithm):
def __init__(self):
super().__init__()
self.addParameter(ParameterVector(self.INPUT,
self.tr('Input layer'), [dataobjects.TYPE_VECTOR_POLYGON]))
self.addParameter(ParameterNumber(self.MIN_AREA,
self.tr('Remove holes with area less than'), 0, 10000000.0, default=0.0, optional=True))
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
self.tr('Input layer'), [QgsProcessingParameterDefinition.TypeVectorPolygon]))
self.addParameter(QgsProcessingParameterNumber(self.MIN_AREA,
self.tr('Remove holes with area less than'), QgsProcessingParameterNumber.Double,
0, True, 0.0, 10000000.0))
self.addOutput(OutputVector(self.OUTPUT, self.tr('Cleaned'), datatype=[dataobjects.TYPE_VECTOR_POLYGON]))
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Cleaned'), QgsProcessingParameterDefinition.TypeVectorPolygon))
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Cleaned'), QgsProcessingParameterDefinition.TypeVectorPolygon))
def name(self):
return 'deleteholes'
@ -67,29 +70,24 @@ class DeleteHoles(QgisAlgorithm):
return self.tr('Delete holes')
def processAlgorithm(self, parameters, context, feedback):
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
min_area = self.getParameterValue(self.MIN_AREA)
if min_area is not None:
try:
min_area = float(min_area)
except:
pass
source = self.parameterAsSource(parameters, self.INPUT, context)
min_area = self.parameterAsDouble(parameters, self.MIN_AREA, context)
if min_area == 0.0:
min_area = -1.0
writer = self.getOutputFromName(self.OUTPUT).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(),
context)
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
source.fields(), source.wkbType(), source.sourceCrs())
features = QgsProcessingUtils.getFeatures(layer, context)
total = 100.0 / QgsProcessingUtils.featureCount(layer, context)
features = source.getFeatures()
total = 100.0 / source.featureCount()
for current, f in enumerate(features):
if feedback.isCanceled():
break
if f.hasGeometry():
if min_area is not None:
f.setGeometry(f.geometry().removeInteriorRings(min_area))
else:
f.setGeometry(f.geometry().removeInteriorRings())
writer.addFeature(f)
f.setGeometry(f.geometry().removeInteriorRings(min_area))
sink.addFeature(f)
feedback.setProgress(int(current * total))
del writer
return {self.OUTPUT: dest_id}

View File

@ -30,15 +30,12 @@ import os
from qgis.core import (QgsWkbTypes,
QgsApplication,
QgsProcessingUtils)
QgsProcessingParameterFeatureSource,
QgsProcessingParameterNumber,
QgsProcessingParameterFeatureSink,
QgsProcessingOutputVectorLayer,
QgsProcessingParameterDefinition)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterNumber
from processing.core.outputs import OutputVector
from processing.tools import dataobjects
pluginPath = os.path.split(os.path.split(os.path.dirname(__file__))[0])[0]
class DensifyGeometries(QgisAlgorithm):
@ -61,14 +58,15 @@ class DensifyGeometries(QgisAlgorithm):
def __init__(self):
super().__init__()
self.addParameter(ParameterVector(self.INPUT,
self.tr('Input layer'),
[dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_LINE]))
self.addParameter(ParameterNumber(self.VERTICES,
self.tr('Vertices to add'), 1, 10000000, 1))
self.addOutput(OutputVector(self.OUTPUT,
self.tr('Densified')))
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
self.tr('Input layer'), [QgsProcessingParameterDefinition.TypeVectorPolygon, QgsProcessingParameterDefinition.TypeVectorLine]))
self.addParameter(QgsProcessingParameterNumber(self.VERTICES,
self.tr('Vertices to add'), QgsProcessingParameterNumber.Integer,
1, False, 1, 10000000))
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Densified')))
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Densified')))
def name(self):
return 'densifygeometries'
@ -77,22 +75,24 @@ class DensifyGeometries(QgisAlgorithm):
return self.tr('Densify geometries')
def processAlgorithm(self, parameters, context, feedback):
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
vertices = self.getParameterValue(self.VERTICES)
source = self.parameterAsSource(parameters, self.INPUT, context)
vertices = self.parameterAsInt(parameters, self.VERTICES, context)
isPolygon = layer.geometryType() == QgsWkbTypes.PolygonGeometry
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
source.fields(), source.wkbType(), source.sourceCrs())
writer = self.getOutputFromName(
self.OUTPUT).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(), context)
features = source.getFeatures()
total = 100.0 / source.featureCount()
features = QgsProcessingUtils.getFeatures(layer, context)
total = 100.0 / QgsProcessingUtils.featureCount(layer, context)
for current, f in enumerate(features):
if feedback.isCanceled():
break
feature = f
if feature.hasGeometry():
new_geometry = feature.geometry().densifyByCount(int(vertices))
new_geometry = feature.geometry().densifyByCount(vertices)
feature.setGeometry(new_geometry)
writer.addFeature(feature)
sink.addFeature(feature)
feedback.setProgress(int(current * total))
del writer
return {self.OUTPUT: dest_id}

View File

@ -31,13 +31,12 @@ from math import sqrt
from qgis.core import (QgsWkbTypes,
QgsApplication,
QgsProcessingUtils)
QgsProcessingParameterFeatureSource,
QgsProcessingParameterNumber,
QgsProcessingParameterFeatureSink,
QgsProcessingOutputVectorLayer,
QgsProcessingParameterDefinition)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.parameters import ParameterVector
from processing.core.parameters import ParameterNumber
from processing.core.outputs import OutputVector
from processing.tools import dataobjects
class DensifyGeometriesInterval(QgisAlgorithm):
@ -57,13 +56,15 @@ class DensifyGeometriesInterval(QgisAlgorithm):
def __init__(self):
super().__init__()
self.addParameter(ParameterVector(self.INPUT,
self.tr('Input layer'),
[dataobjects.TYPE_VECTOR_POLYGON, dataobjects.TYPE_VECTOR_LINE]))
self.addParameter(ParameterNumber(self.INTERVAL,
self.tr('Interval between vertices to add'), 0.0, 10000000.0, 1.0))
self.addOutput(OutputVector(self.OUTPUT, self.tr('Densified')))
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
self.tr('Input layer'), [QgsProcessingParameterDefinition.TypeVectorPolygon, QgsProcessingParameterDefinition.TypeVectorLine]))
self.addParameter(QgsProcessingParameterNumber(self.INTERVAL,
self.tr('Interval between vertices to add'), QgsProcessingParameterNumber.Double,
1, False, 0, 10000000))
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Densified')))
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT, self.tr('Densified')))
def name(self):
return 'densifygeometriesgivenaninterval'
@ -72,23 +73,24 @@ class DensifyGeometriesInterval(QgisAlgorithm):
return self.tr('Densify geometries given an interval')
def processAlgorithm(self, parameters, context, feedback):
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT), context)
interval = self.getParameterValue(self.INTERVAL)
source = self.parameterAsSource(parameters, self.INPUT, context)
interval = self.parameterAsDouble(parameters, self.INTERVAL, context)
isPolygon = layer.geometryType() == QgsWkbTypes.PolygonGeometry
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
source.fields(), source.wkbType(), source.sourceCrs())
writer = self.getOutputFromName(
self.OUTPUT).getVectorWriter(layer.fields(), layer.wkbType(), layer.crs(), context)
features = QgsProcessingUtils.getFeatures(layer, context)
total = 100.0 / QgsProcessingUtils.featureCount(layer, context)
features = source.getFeatures()
total = 100.0 / source.featureCount()
for current, f in enumerate(features):
if feedback.isCanceled():
break
feature = f
if feature.hasGeometry():
new_geometry = feature.geometry().densifyByCount(float(interval))
new_geometry = feature.geometry().densifyByDistance(float(interval))
feature.setGeometry(new_geometry)
writer.addFeature(feature)
sink.addFeature(feature)
feedback.setProgress(int(current * total))
del writer
return {self.OUTPUT: dest_id}

View File

@ -29,11 +29,11 @@ from qgis.core import (QgsFeatureRequest,
QgsWkbTypes,
QgsCoordinateReferenceSystem,
QgsApplication,
QgsProcessingUtils)
QgsProcessingParameterDefinition,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterFeatureSink,
QgsProcessingOutputVectorLayer)
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from processing.core.parameters import ParameterVector
from processing.core.outputs import OutputVector
from processing.tools import dataobjects
class DropGeometry(QgisAlgorithm):
@ -55,11 +55,10 @@ class DropGeometry(QgisAlgorithm):
def __init__(self):
super().__init__()
self.addParameter(ParameterVector(self.INPUT_LAYER,
self.tr('Input layer'), [dataobjects.TYPE_VECTOR_POINT,
dataobjects.TYPE_VECTOR_LINE,
dataobjects.TYPE_VECTOR_POLYGON]))
self.addOutput(OutputVector(self.OUTPUT_TABLE, self.tr('Dropped geometry')))
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT_LAYER, self.tr('Input layer'), [QgsProcessingParameterDefinition.TypeVectorPoint, QgsProcessingParameterDefinition.TypeVectorLine, QgsProcessingParameterDefinition.TypeVectorPolygon]))
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT_TABLE, self.tr('Dropped geometry')))
self.addOutput(QgsProcessingOutputVectorLayer(self.OUTPUT_TABLE, self.tr("Dropped geometry")))
def name(self):
return 'dropgeometries'
@ -68,17 +67,20 @@ class DropGeometry(QgisAlgorithm):
return self.tr('Drop geometries')
def processAlgorithm(self, parameters, context, feedback):
layer = QgsProcessingUtils.mapLayerFromString(self.getParameterValue(self.INPUT_LAYER), context)
writer = self.getOutputFromName(
self.OUTPUT_TABLE).getVectorWriter(layer.fields(), QgsWkbTypes.NoGeometry, QgsCoordinateReferenceSystem(),
context)
source = self.parameterAsSource(parameters, self.INPUT_LAYER, context)
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT_TABLE, context,
source.fields(), QgsWkbTypes.NoGeometry, QgsCoordinateReferenceSystem())
request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry)
features = QgsProcessingUtils.getFeatures(layer, context, request)
total = 100.0 / QgsProcessingUtils.featureCount(layer, context)
features = source.getFeatures(request)
total = 100.0 / source.featureCount()
for current, input_feature in enumerate(features):
writer.addFeature(input_feature)
if feedback.isCanceled():
break
input_feature.clearGeometry()
sink.addFeature(input_feature)
feedback.setProgress(int(current * total))
del writer
return {self.OUTPUT_TABLE: dest_id}

View File

@ -65,7 +65,8 @@ from .ExtractByExpression import ExtractByExpression
# from .Centroids import Centroids
# from .Delaunay import Delaunay
# from .VoronoiPolygons import VoronoiPolygons
# from .DensifyGeometries import DensifyGeometries
from .DensifyGeometries import DensifyGeometries
from .DensifyGeometriesInterval import DensifyGeometriesInterval
from .MultipartToSingleparts import MultipartToSingleparts
# from .SimplifyGeometries import SimplifyGeometries
# from .LinesToPolygons import LinesToPolygons
@ -84,10 +85,9 @@ from .ExtentFromLayer import ExtentFromLayer
# from .RandomSelectionWithinSubsets import RandomSelectionWithinSubsets
# from .SelectByLocation import SelectByLocation
# from .Union import Union
# from .DensifyGeometriesInterval import DensifyGeometriesInterval
# from .SpatialJoin import SpatialJoin
from .DeleteColumn import DeleteColumn
# from .DeleteHoles import DeleteHoles
from .DeleteHoles import DeleteHoles
# from .DeleteDuplicateGeometries import DeleteDuplicateGeometries
# from .TextToFloat import TextToFloat
# from .ExtractByAttribute import ExtractByAttribute
@ -168,8 +168,8 @@ from .Aspect import Aspect
# from .SnapGeometries import SnapGeometriesToLayer
# from .PoleOfInaccessibility import PoleOfInaccessibility
# from .RasterCalculator import RasterCalculator
# from .CreateAttributeIndex import CreateAttributeIndex
# from .DropGeometry import DropGeometry
from .CreateAttributeIndex import CreateAttributeIndex
from .DropGeometry import DropGeometry
from .BasicStatistics import BasicStatisticsForField
# from .Heatmap import Heatmap
# from .Orthogonalize import Orthogonalize
@ -205,14 +205,13 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
# LinesIntersection(), UniqueValues(), PointDistance(),
# ReprojectLayer(), ExportGeometryInfo(), Centroids(),
# Delaunay(), VoronoiPolygons(), SimplifyGeometries(),
# DensifyGeometries(), DensifyGeometriesInterval(),
# , SinglePartsToMultiparts(),
# PolygonsToLines(), LinesToPolygons(), ExtractNodes(),
# ConvexHull(), FixedDistanceBuffer(),
# VariableDistanceBuffer(), Dissolve(), Difference(),
# Intersection(), Union(),
# RandomSelection(), RandomSelectionWithinSubsets(),
# SelectByLocation(), RandomExtract(), DeleteHoles(),
# SelectByLocation(), RandomExtract(),
# RandomExtractWithinSubsets(), ExtractByLocation(),
# SpatialJoin(), RegularPoints(), SymmetricalDifference(),
# VectorSplit(), VectorGridLines(), VectorGridPolygons(),
@ -250,8 +249,8 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
# RemoveNullGeometry(),
# ExtendLines(), ExtractSpecificNodes(),
# GeometryByExpression(), SnapGeometriesToLayer(),
# PoleOfInaccessibility(), CreateAttributeIndex(),
# DropGeometry(),
# PoleOfInaccessibility(),
#
# RasterCalculator(), Heatmap(), Orthogonalize(),
# ShortestPathPointToPoint(), ShortestPathPointToLayer(),
# ShortestPathLayerToPoint(), ServiceAreaFromPoint(),
@ -267,7 +266,12 @@ class QGISAlgorithmProvider(QgsProcessingProvider):
BoundingBox(),
CheckValidity(),
Clip(),
CreateAttributeIndex(),
DeleteColumn(),
DeleteHoles(),
DensifyGeometries(),
DensifyGeometriesInterval(),
DropGeometry(),
ExtentFromLayer(),
ExtractByExpression(),
GridPolygon(),

View File

@ -40,7 +40,7 @@ from qgis.core import (QgsMapLayer,
QgsProcessingParameterMultipleLayers,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterDefinition,
QgsProcessingParameterTable,
QgsProcessingParameterVectorLayer,
QgsProcessingParameterFeatureSource)
from processing.gui.MultipleInputDialog import MultipleInputDialog
@ -105,7 +105,7 @@ class BatchInputSelectionPanel(QWidget):
(isinstance(self.param, QgsProcessingParameterMultipleLayers) and
self.param.layerType() == QgsProcessingParameterDefinition.TypeRaster)):
layers = QgsProcessingUtils.compatibleRasterLayers(QgsProject.instance())
elif isinstance(self.param, QgsProcessingParameterTable):
elif isinstance(self.param, QgsProcessingParameterVectorLayer):
layers = QgsProcessingUtils.compatibleVectorLayers(QgsProject.instance())
else:
datatypes = [QgsProcessingParameterDefinition.TypeVectorAny]

View File

@ -36,7 +36,7 @@ from qgis.core import (QgsMapLayer,
QgsProcessingParameterFolderOutput,
QgsProcessingParameterRasterLayer,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterTable,
QgsProcessingParameterVectorLayer,
QgsProcessingParameterMultipleLayers,
QgsProcessingParameterBoolean,
QgsProcessingParameterEnum,
@ -114,7 +114,7 @@ class BatchOutputSelectionPanel(QWidget):
param = self.alg.parameterDefinitions()[dlg.param_index]
if isinstance(param, (QgsProcessingParameterRasterLayer,
QgsProcessingParameterFeatureSource,
QgsProcessingParameterTable,
QgsProcessingParameterVectorLayer,
QgsProcessingParameterMultipleLayers)):
v = widget.value()
if isinstance(v, QgsMapLayer):

View File

@ -58,8 +58,8 @@ from qgis.core import (
QgsProcessingParameterEnum,
QgsProcessingParameterString,
QgsProcessingParameterExpression,
QgsProcessingParameterTable,
QgsProcessingParameterTableField,
QgsProcessingParameterVectorLayer,
QgsProcessingParameterField,
QgsProcessingParameterFeatureSource,
QgsProcessingFeatureSourceDefinition,
QgsProcessingOutputRasterLayer,
@ -531,7 +531,7 @@ class MultipleInputWidgetWrapper(WidgetWrapper):
elif self.param.layerType() == QgsProcessingParameterDefinition.TypeRaster:
options = self.dialog.getAvailableValuesOfType(QgsProcessingParameterRasterLayer, QgsProcessingOutputRasterLayer)
elif self.param.layerType() == QgsProcessingParameterDefinition.TypeTable:
options = self.dialog.getAvailableValuesOfType(QgsProcessingParameterTable, OutputTable)
options = self.dialog.getAvailableValuesOfType(QgsProcessingParameterVectorLayer, OutputTable)
else:
options = self.dialog.getAvailableValuesOfType(QgsProcessingParameterFile, OutputFile)
options = sorted(options, key=lambda opt: self.dialog.resolveValueDescription(opt))
@ -907,7 +907,7 @@ class StringWidgetWrapper(WidgetWrapper, ExpressionWidgetWrapperMixin):
else:
# strings, numbers, files and table fields are all allowed input types
strings = self.dialog.getAvailableValuesOfType([QgsProcessingParameterString, QgsProcessingParameterNumber, QgsProcessingParameterFile,
QgsProcessingParameterTableField, QgsProcessingParameterExpression], QgsProcessingOutputString)
QgsProcessingParameterField, QgsProcessingParameterExpression], QgsProcessingOutputString)
options = [(self.dialog.resolveValueDescription(s), s) for s in strings]
if self.param.multiLine():
widget = MultilineTextPanel(options)
@ -1079,7 +1079,7 @@ class TableWidgetWrapper(WidgetWrapper):
self.combo = QComboBox()
layers = self.dialog.getAvailableValuesOfType(QgsProcessingParameterRasterLayer, QgsProcessingOutputRasterLayer)
self.combo.setEditable(True)
tables = self.dialog.getAvailableValuesOfType(QgsProcessingParameterTable, OutputTable)
tables = self.dialog.getAvailableValuesOfType(QgsProcessingParameterVectorLayer, OutputTable)
layers = self.dialog.getAvailableValuesOfType(QgsProcessingParameterFeatureSource, QgsProcessingOutputVectorLayer)
if self.param.flags() & QgsProcessingParameterDefinition.FlagOptional:
self.combo.addItem(self.NOT_SELECTED, None)
@ -1154,17 +1154,17 @@ class TableFieldWidgetWrapper(WidgetWrapper):
widget = QgsFieldComboBox()
widget.setAllowEmptyFieldName(self.param.flags() & QgsProcessingParameterDefinition.FlagOptional)
widget.fieldChanged.connect(lambda: self.widgetValueHasChanged.emit(self))
if self.param.dataType() == QgsProcessingParameterTableField.Numeric:
if self.param.dataType() == QgsProcessingParameterField.Numeric:
widget.setFilters(QgsFieldProxyModel.Numeric)
elif self.param.dataType() == QgsProcessingParameterTableField.String:
elif self.param.dataType() == QgsProcessingParameterField.String:
widget.setFilters(QgsFieldProxyModel.String)
elif self.param.dataType() == QgsProcessingParameterTableField.DateTime:
elif self.param.dataType() == QgsProcessingParameterField.DateTime:
widget.setFilters(QgsFieldProxyModel.Date | QgsFieldProxyModel.Time)
return widget
else:
widget = QComboBox()
widget.setEditable(True)
fields = self.dialog.getAvailableValuesOfType([QgsProcessingParameterTableField, QgsProcessingParameterString], [QgsProcessingOutputString])
fields = self.dialog.getAvailableValuesOfType([QgsProcessingParameterField, QgsProcessingParameterString], [QgsProcessingOutputString])
if self.param.flags() & QgsProcessingParameterDefinition.FlagOptional:
widget.addItem(self.NOT_SET, None)
for f in fields:
@ -1202,12 +1202,12 @@ class TableFieldWidgetWrapper(WidgetWrapper):
if self._layer is None:
return []
fieldTypes = []
if self.param.dataType() == QgsProcessingParameterTableField.String:
if self.param.dataType() == QgsProcessingParameterField.String:
fieldTypes = [QVariant.String]
elif self.param.dataType() == QgsProcessingParameterTableField.Numeric:
elif self.param.dataType() == QgsProcessingParameterField.Numeric:
fieldTypes = [QVariant.Int, QVariant.Double, QVariant.LongLong,
QVariant.UInt, QVariant.ULongLong]
elif self.param.dataType() == QgsProcessingParameterTableField.DateTime:
elif self.param.dataType() == QgsProcessingParameterField.DateTime:
fieldTypes = [QVariant.Date, QVariant.Time, QVariant.DateTime]
fieldNames = set()
@ -1303,7 +1303,7 @@ class WidgetWrapperFactory:
wrapper = StringWidgetWrapper
elif param.type() == 'expression':
wrapper = ExpressionWidgetWrapper
elif param.type() == 'table':
elif param.type() == 'vector':
wrapper = TableWidgetWrapper
elif param.type() == 'field':
wrapper = TableFieldWidgetWrapper

View File

@ -52,8 +52,8 @@ from qgis.core import (QgsApplication,
QgsProcessingParameterEnum,
QgsProcessingParameterString,
QgsProcessingParameterExpression,
QgsProcessingParameterTable,
QgsProcessingParameterTableField,
QgsProcessingParameterVectorLayer,
QgsProcessingParameterField,
QgsProcessingParameterFeatureSource,
QgsProcessingModelAlgorithm)
from qgis.gui import QgsMessageBar

View File

@ -45,8 +45,8 @@ from qgis.core import (QgsCoordinateReferenceSystem,
QgsProcessingParameterEnum,
QgsProcessingParameterString,
QgsProcessingParameterExpression,
QgsProcessingParameterTable,
QgsProcessingParameterTableField,
QgsProcessingParameterVectorLayer,
QgsProcessingParameterField,
QgsProcessingParameterFeatureSource)
from qgis.PyQt.QtCore import Qt
from qgis.PyQt.QtWidgets import (QDialog,
@ -123,13 +123,13 @@ class ModelerParameterDefinitionDialog(QDialog):
self.state.setChecked(bool(self.param.defaultValue()))
self.verticalLayout.addWidget(self.state)
elif self.paramType == ModelerParameterDefinitionDialog.PARAMETER_TABLE_FIELD or \
isinstance(self.param, QgsProcessingParameterTableField):
isinstance(self.param, QgsProcessingParameterField):
self.verticalLayout.addWidget(QLabel(self.tr('Parent layer')))
self.parentCombo = QComboBox()
idx = 0
for param in list(self.alg.parameterComponents().values()):
definition = self.alg.parameterDefinition(param.parameterName())
if isinstance(definition, (QgsProcessingParameterFeatureSource, QgsProcessingParameterTable)):
if isinstance(definition, (QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer)):
self.parentCombo.addItem(definition.description(), definition.name())
if self.param is not None:
if self.param.parentLayerParameter() == definition.name():
@ -218,7 +218,7 @@ class ModelerParameterDefinitionDialog(QDialog):
idx = 1
for param in list(self.alg.parameterComponents().values()):
definition = self.alg.parameterDefinition(param.parameterName())
if isinstance(definition, (QgsProcessingParameterFeatureSource, QgsProcessingParameterTable)):
if isinstance(definition, (QgsProcessingParameterFeatureSource, QgsProcessingParameterVectorLayer)):
self.parentCombo.addItem(definition.description(), definition.name())
if self.param is not None:
if self.param.parentLayerParameter() == definition.name():
@ -301,21 +301,21 @@ class ModelerParameterDefinitionDialog(QDialog):
isinstance(self.param, QgsProcessingParameterBoolean)):
self.param = QgsProcessingParameterBoolean(name, description, self.state.isChecked())
elif (self.paramType == ModelerParameterDefinitionDialog.PARAMETER_TABLE_FIELD or
isinstance(self.param, QgsProcessingParameterTableField)):
isinstance(self.param, QgsProcessingParameterField)):
if self.parentCombo.currentIndex() < 0:
QMessageBox.warning(self, self.tr('Unable to define parameter'),
self.tr('Wrong or missing parameter values'))
return
parent = self.parentCombo.currentData()
datatype = self.datatypeCombo.currentData()
self.param = QgsProcessingParameterTableField(name, description, None, parent, datatype, self.multipleCheck.isChecked())
self.param = QgsProcessingParameterField(name, description, None, parent, datatype, self.multipleCheck.isChecked())
elif (self.paramType == ModelerParameterDefinitionDialog.PARAMETER_RASTER or
isinstance(self.param, QgsProcessingParameterRasterLayer)):
self.param = QgsProcessingParameterRasterLayer(
name, description)
elif (self.paramType == ModelerParameterDefinitionDialog.PARAMETER_TABLE or
isinstance(self.param, QgsProcessingParameterTable)):
self.param = QgsProcessingParameterTable(
isinstance(self.param, QgsProcessingParameterVectorLayer)):
self.param = QgsProcessingParameterVectorLayer(
name, description)
elif (self.paramType == ModelerParameterDefinitionDialog.PARAMETER_VECTOR or
isinstance(self.param, QgsProcessingParameterFeatureSource)):

View File

@ -50,7 +50,7 @@ from processing.script.ScriptAlgorithm import ScriptAlgorithm # NOQA
from processing.modeler.ModelerAlgorithmProvider import ModelerAlgorithmProvider # NOQA
from processing.algs.qgis.QGISAlgorithmProvider import QGISAlgorithmProvider # NOQA
from processing.algs.grass7.Grass7AlgorithmProvider import Grass7AlgorithmProvider # NOQA
#from processing.algs.grass7.Grass7AlgorithmProvider import Grass7AlgorithmProvider # NOQA
from processing.algs.gdal.GdalAlgorithmProvider import GdalAlgorithmProvider # NOQA
from processing.algs.saga.SagaAlgorithmProvider import SagaAlgorithmProvider # NOQA
from processing.script.ScriptAlgorithmProvider import ScriptAlgorithmProvider # NOQA

View File

@ -15,16 +15,16 @@ tests:
# geometry:
# precision: 7
#
# - name: Delete Holes
# algorithm: qgis:deleteholes
# params:
# - name: polys.gml
# type: vector
# results:
# OUTPUT:
# name: expected/polys_deleteholes.gml
# type: vector
#
- name: Delete Holes
algorithm: qgis:deleteholes
params:
- name: polys.gml
type: vector
results:
OUTPUT:
name: expected/polys_deleteholes.gml
type: vector
- algorithm: qgis:clip
name: Clip lines by polygons
params:
@ -128,18 +128,18 @@ tests:
# name: expected/intersection_collection_fallback.shp
# type: vector
#
# - name: Densify geometries
# algorithm: qgis:densifygeometries
# params:
# INPUT:
# name: multipolys.gml
# type: vector
# VERTICES: 4
# results:
# OUTPUT:
# name: expected/multipolys_densify.gml
# type: vector
#
- name: Densify geometries
algorithm: qgis:densifygeometries
params:
INPUT:
name: multipolys.gml
type: vector
VERTICES: 4
results:
OUTPUT:
name: expected/multipolys_densify.gml
type: vector
# - name: Polygons to Lines
# algorithm: qgis:polygonstolines
# params:
@ -1258,7 +1258,7 @@ tests:
# name: expected/remove_null_polys.gml
# type: vector
#
- algorithm: qgis:extractbyexpression
- algorithm: native:extractbyexpression
name: Extract by Expression
params:
EXPRESSION: left( "Name",1)='A'
@ -1484,88 +1484,88 @@ tests:
# geometry:
# precision: 7
#
# - algorithm: qgis:extractbyattribute
# name: Extract by attribute (is null)
# params:
# FIELD: intval
# INPUT:
# name: polys.gml
# type: vector
# OPERATOR: '8'
# results:
# OUTPUT:
# name: expected/extract_by_attribute_null.gml
# type: vector
#
# - algorithm: qgis:extractbyattribute
# name: Extract by attribute (is not null)
# params:
# FIELD: intval
# INPUT:
# name: polys.gml
# type: vector
# OPERATOR: '9'
# results:
# OUTPUT:
# name: expected/extract_by_attribute_not_null.gml
# type: vector
#
# - algorithm: qgis:extractbyattribute
# name: Extract by attribute (starts with)
# params:
# FIELD: name
# INPUT:
# name: polys.gml
# type: vector
# OPERATOR: '6'
# VALUE: A
# results:
# OUTPUT:
# name: expected/extract_by_attribute_startswith.gml
# type: vector
#
# - algorithm: qgis:extractbyattribute
# name: Extract by attribute (contains)
# params:
# FIELD: name
# INPUT:
# name: polys.gml
# type: vector
# OPERATOR: '7'
# VALUE: aaa
# results:
# OUTPUT:
# name: expected/extract_by_attribute_contains.gml
# type: vector
#
# - algorithm: qgis:extractbyattribute
# name: Extract by attribute (does not contain)
# params:
# FIELD: name
# INPUT:
# name: polys.gml
# type: vector
# OPERATOR: '10'
# VALUE: a
# results:
# OUTPUT:
# name: expected/extract_by_attribute_does_not_contain.gml
# type: vector
#
# - algorithm: qgis:extractbyattribute
# name: Extract by attribute (greater)
# params:
# FIELD: floatval
# INPUT:
# name: polys.gml
# type: vector
# OPERATOR: '2'
# VALUE: '1'
# results:
# OUTPUT:
# name: expected/extract_by_attribute_greater.gml
# type: vector
#
- algorithm: native:extractbyattribute
name: Extract by attribute (is null)
params:
FIELD: intval
INPUT:
name: polys.gml
type: vector
OPERATOR: '8'
results:
OUTPUT:
name: expected/extract_by_attribute_null.gml
type: vector
- algorithm: native:extractbyattribute
name: Extract by attribute (is not null)
params:
FIELD: intval
INPUT:
name: polys.gml
type: vector
OPERATOR: '9'
results:
OUTPUT:
name: expected/extract_by_attribute_not_null.gml
type: vector
- algorithm: native:extractbyattribute
name: Extract by attribute (starts with)
params:
FIELD: name
INPUT:
name: polys.gml
type: vector
OPERATOR: '6'
VALUE: A
results:
OUTPUT:
name: expected/extract_by_attribute_startswith.gml
type: vector
- algorithm: native:extractbyattribute
name: Extract by attribute (contains)
params:
FIELD: name
INPUT:
name: polys.gml
type: vector
OPERATOR: '7'
VALUE: aaa
results:
OUTPUT:
name: expected/extract_by_attribute_contains.gml
type: vector
- algorithm: native:extractbyattribute
name: Extract by attribute (does not contain)
params:
FIELD: name
INPUT:
name: polys.gml
type: vector
OPERATOR: '10'
VALUE: a
results:
OUTPUT:
name: expected/extract_by_attribute_does_not_contain.gml
type: vector
- algorithm: native:extractbyattribute
name: Extract by attribute (greater)
params:
FIELD: floatval
INPUT:
name: polys.gml
type: vector
OPERATOR: '2'
VALUE: '1'
results:
OUTPUT:
name: expected/extract_by_attribute_greater.gml
type: vector
# - algorithm: qgis:createattributeindex
# name: Create Attribute Index (only tests for python errors, does not check result)
# params:
@ -1665,18 +1665,18 @@ tests:
# compare:
# geometry:
# precision: 7
#
# - algorithm: qgis:dropgeometries
# name: Drop geometries
# params:
# INPUT_LAYER:
# name: polys.gml
# type: vector
# results:
# OUTPUT_TABLE:
# name: expected/dropped_geometry.csv
# type: vector
#
- algorithm: qgis:dropgeometries
name: Drop geometries
params:
INPUT_LAYER:
name: polys.gml
type: vector
results:
OUTPUT_TABLE:
name: expected/dropped_geometry.csv
type: vector
# - algorithm: qgis:creategridlines
# name: Create grid (lines)
# params:
@ -1808,30 +1808,30 @@ tests:
geometry:
precision: 7
# - algorithm: qgis:deleteholes
# name: Delete holes (no min)
# params:
# INPUT:
# name: custom/remove_holes.gml
# type: vector
# MIN_AREA: 0.0
# results:
# OUTPUT:
# name: expected/removed_holes.gml
# type: vector
#
# - algorithm: qgis:deleteholes
# name: Delete holes (with min)
# params:
# INPUT:
# name: custom/remove_holes.gml
# type: vector
# MIN_AREA: 5.0
# results:
# OUTPUT:
# name: expected/removed_holes_min_area.gml
# type: vector
#
- algorithm: qgis:deleteholes
name: Delete holes (no min)
params:
INPUT:
name: custom/remove_holes.gml
type: vector
MIN_AREA: 0.0
results:
OUTPUT:
name: expected/removed_holes.gml
type: vector
- algorithm: qgis:deleteholes
name: Delete holes (with min)
params:
INPUT:
name: custom/remove_holes.gml
type: vector
MIN_AREA: 5.0
results:
OUTPUT:
name: expected/removed_holes_min_area.gml
type: vector
- algorithm: qgis:basicstatisticsforfields
name: Basic stats datetime
params:

View File

@ -3620,7 +3620,7 @@ void QgisApp::updateRecentProjectPaths()
{
QAction *action = mRecentProjectsMenu->addAction( QStringLiteral( "%1 (%2)" ).arg( recentProject.title != recentProject.path ? recentProject.title : QFileInfo( recentProject.path ).baseName(),
QDir::toNativeSeparators( recentProject.path ) ) );
action->setEnabled( QFile::exists( ( recentProject.path ) ) );
//action->setEnabled( QFile::exists( ( recentProject.path ) ) );
action->setData( recentProject.path );
}

View File

@ -58,12 +58,15 @@ bool QgsNativeAlgorithms::supportsNonFileBasedOutput() const
void QgsNativeAlgorithms::loadAlgorithms()
{
addAlgorithm( new QgsCentroidAlgorithm() );
addAlgorithm( new QgsBufferAlgorithm() );
addAlgorithm( new QgsDissolveAlgorithm() );
addAlgorithm( new QgsCentroidAlgorithm() );
addAlgorithm( new QgsClipAlgorithm() );
addAlgorithm( new QgsTransformAlgorithm() );
addAlgorithm( new QgsDissolveAlgorithm() );
addAlgorithm( new QgsExtractByAttributeAlgorithm() );
addAlgorithm( new QgsExtractByExpressionAlgorithm() );
addAlgorithm( new QgsMultipartToSinglepartAlgorithm() );
addAlgorithm( new QgsSubdivideAlgorithm() );
addAlgorithm( new QgsTransformAlgorithm() );
}
@ -244,8 +247,8 @@ QVariantMap QgsBufferAlgorithm::processAlgorithm( const QVariantMap &parameters,
QgsDissolveAlgorithm::QgsDissolveAlgorithm()
{
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
addParameter( new QgsProcessingParameterTableField( QStringLiteral( "FIELD" ), QObject::tr( "Unique ID fields" ), QVariant(),
QStringLiteral( "INPUT" ), QgsProcessingParameterTableField::Any, true, true ) );
addParameter( new QgsProcessingParameterField( QStringLiteral( "FIELD" ), QObject::tr( "Unique ID fields" ), QVariant(),
QStringLiteral( "INPUT" ), QgsProcessingParameterField::Any, true, true ) );
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Dissolved" ) ) );
addOutput( new QgsProcessingOutputVectorLayer( QStringLiteral( "OUTPUT" ), QObject::tr( "Dissolved" ) ) );
@ -664,6 +667,380 @@ QVariantMap QgsSubdivideAlgorithm::processAlgorithm( const QVariantMap &paramete
return outputs;
}
QgsMultipartToSinglepartAlgorithm::QgsMultipartToSinglepartAlgorithm()
{
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Single parts" ) ) );
addOutput( new QgsProcessingOutputVectorLayer( QStringLiteral( "OUTPUT" ), QObject::tr( "Single parts" ) ) );
}
QString QgsMultipartToSinglepartAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm takes a vector layer with multipart geometries and generates a new one in which all geometries contain "
"a single part. Features with multipart geometries are divided in as many different features as parts the geometry "
"contain, and the same attributes are used for each of them." );
}
QVariantMap QgsMultipartToSinglepartAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const
{
std::unique_ptr< QgsFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !source )
return QVariantMap();
QgsWkbTypes::Type sinkType = QgsWkbTypes::singleType( source->wkbType() );
QString dest;
std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, source->fields(),
sinkType, source->sourceCrs(), dest ) );
if ( !sink )
return QVariantMap();
long count = source->featureCount();
if ( count <= 0 )
return QVariantMap();
QgsFeature f;
QgsFeatureIterator it = source->getFeatures();
double step = 100.0 / count;
int current = 0;
while ( it.nextFeature( f ) )
{
if ( feedback->isCanceled() )
{
break;
}
QgsFeature out = f;
if ( out.hasGeometry() )
{
QgsGeometry inputGeometry = f.geometry();
if ( inputGeometry.isMultipart() )
{
Q_FOREACH ( const QgsGeometry &g, inputGeometry.asGeometryCollection() )
{
out.setGeometry( g );
sink->addFeature( out );
}
}
else
{
sink->addFeature( out );
}
}
else
{
// feature with null geometry
sink->addFeature( out );
}
feedback->setProgress( current * step );
current++;
}
QVariantMap outputs;
outputs.insert( QStringLiteral( "OUTPUT" ), dest );
return outputs;
}
QgsExtractByExpressionAlgorithm::QgsExtractByExpressionAlgorithm()
{
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
addParameter( new QgsProcessingParameterExpression( QStringLiteral( "EXPRESSION" ), QObject::tr( "Expression" ), QVariant(), QStringLiteral( "INPUT" ) ) );
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Matching features" ) ) );
addOutput( new QgsProcessingOutputVectorLayer( QStringLiteral( "OUTPUT" ), QObject::tr( "Matching (expression)" ) ) );
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "FAIL_OUTPUT" ), QObject::tr( "Non-matching" ),
QgsProcessingParameterDefinition::TypeVectorAny, QVariant(), true ) );
addOutput( new QgsProcessingOutputVectorLayer( QStringLiteral( "FAIL_OUTPUT" ), QObject::tr( "Non-matching (expression)" ) ) );
}
QString QgsExtractByExpressionAlgorithm::shortHelpString() const
{
return QObject::tr( "This algorithm creates a new vector layer that only contains matching features from an input layer. "
"The criteria for adding features to the resulting layer is based on a QGIS expression.\n\n"
"For more information about expressions see the <a href =\"{qgisdocs}/user_manual/working_with_vector/expression.html\">user manual</a>" );
}
QVariantMap QgsExtractByExpressionAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const
{
std::unique_ptr< QgsFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !source )
return QVariantMap();
QString expressionString = parameterAsExpression( parameters, QStringLiteral( "EXPRESSION" ), context );
QString matchingSinkId;
std::unique_ptr< QgsFeatureSink > matchingSink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, source->fields(),
source->wkbType(), source->sourceCrs(), matchingSinkId ) );
if ( !matchingSink )
return QVariantMap();
QString nonMatchingSinkId;
std::unique_ptr< QgsFeatureSink > nonMatchingSink( parameterAsSink( parameters, QStringLiteral( "FAIL_OUTPUT" ), context, source->fields(),
source->wkbType(), source->sourceCrs(), nonMatchingSinkId ) );
QgsExpression expression( expressionString );
if ( expression.hasParserError() )
{
// raise GeoAlgorithmExecutionException(expression.parserErrorString())
return QVariantMap();
}
QgsExpressionContext expressionContext = createExpressionContext( parameters, context );
long count = source->featureCount();
if ( count <= 0 )
return QVariantMap();
double step = 100.0 / count;
int current = 0;
if ( !nonMatchingSink )
{
// not saving failing features - so only fetch good features
QgsFeatureRequest req;
req.setFilterExpression( expressionString );
req.setExpressionContext( expressionContext );
QgsFeatureIterator it = source->getFeatures( req );
QgsFeature f;
while ( it.nextFeature( f ) )
{
if ( feedback->isCanceled() )
{
break;
}
matchingSink->addFeature( f );
feedback->setProgress( current * step );
current++;
}
}
else
{
// saving non-matching features, so we need EVERYTHING
expressionContext.setFields( source->fields() );
expression.prepare( &expressionContext );
QgsFeatureIterator it = source->getFeatures();
QgsFeature f;
while ( it.nextFeature( f ) )
{
if ( feedback->isCanceled() )
{
break;
}
expressionContext.setFeature( f );
if ( expression.evaluate( &expressionContext ).toBool() )
{
matchingSink->addFeature( f );
}
else
{
nonMatchingSink->addFeature( f );
}
feedback->setProgress( current * step );
current++;
}
}
QVariantMap outputs;
outputs.insert( QStringLiteral( "OUTPUT" ), matchingSinkId );
if ( nonMatchingSink )
outputs.insert( QStringLiteral( "FAIL_OUTPUT" ), nonMatchingSinkId );
return outputs;
}
QgsExtractByAttributeAlgorithm::QgsExtractByAttributeAlgorithm()
{
addParameter( new QgsProcessingParameterFeatureSource( QStringLiteral( "INPUT" ), QObject::tr( "Input layer" ) ) );
addParameter( new QgsProcessingParameterField( QStringLiteral( "FIELD" ), QObject::tr( "Selection attribute" ), QVariant(), QStringLiteral( "INPUT" ) ) );
addParameter( new QgsProcessingParameterEnum( QStringLiteral( "OPERATOR" ), QObject::tr( "Operator" ), QStringList()
<< QObject::tr( "=" )
<< QObject::trUtf8( "" )
<< QObject::tr( ">" )
<< QObject::tr( ">=" )
<< QObject::tr( "<" )
<< QObject::tr( "<=" )
<< QObject::tr( "begins with" )
<< QObject::tr( "contains" )
<< QObject::tr( "is null" )
<< QObject::tr( "is not null" )
<< QObject::tr( "does not contain" ) ) );
addParameter( new QgsProcessingParameterString( QStringLiteral( "VALUE" ), QObject::tr( "Value" ), QVariant(), false, true ) );
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "OUTPUT" ), QObject::tr( "Extracted (attribute)" ) ) );
addOutput( new QgsProcessingOutputVectorLayer( QStringLiteral( "OUTPUT" ), QObject::tr( "Matching (attribute)" ) ) );
addParameter( new QgsProcessingParameterFeatureSink( QStringLiteral( "FAIL_OUTPUT" ), QObject::tr( "Extracted (non-matching)" ),
QgsProcessingParameterDefinition::TypeVectorAny, QVariant(), true ) );
addOutput( new QgsProcessingOutputVectorLayer( QStringLiteral( "FAIL_OUTPUT" ), QObject::tr( "Non-matching (attribute)" ) ) );
}
QString QgsExtractByAttributeAlgorithm::shortHelpString() const
{
return QObject::tr( " This algorithm creates a new vector layer that only contains matching features from an input layer. "
"The criteria for adding features to the resulting layer is defined based on the values "
"of an attribute from the input layer." );
}
QVariantMap QgsExtractByAttributeAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const
{
std::unique_ptr< QgsFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
if ( !source )
return QVariantMap();
QString fieldName = parameterAsString( parameters, QStringLiteral( "FIELD" ), context );
Operation op = static_cast< Operation >( parameterAsEnum( parameters, QStringLiteral( "OPERATOR" ), context ) );
QString value = parameterAsString( parameters, QStringLiteral( "VALUE" ), context );
QString matchingSinkId;
std::unique_ptr< QgsFeatureSink > matchingSink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, source->fields(),
source->wkbType(), source->sourceCrs(), matchingSinkId ) );
if ( !matchingSink )
return QVariantMap();
QString nonMatchingSinkId;
std::unique_ptr< QgsFeatureSink > nonMatchingSink( parameterAsSink( parameters, QStringLiteral( "FAIL_OUTPUT" ), context, source->fields(),
source->wkbType(), source->sourceCrs(), nonMatchingSinkId ) );
int idx = source->fields().lookupField( fieldName );
QVariant::Type fieldType = source->fields().at( idx ).type();
if ( fieldType != QVariant::String && ( op == BeginsWith || op == Contains || op == DoesNotContain ) )
{
#if 0
op = ''.join( ['"%s", ' % o for o in self.STRING_OPERATORS] )
raise GeoAlgorithmExecutionException(
self.tr( 'Operators {0} can be used only with string fields.' ).format( op ) )
#endif
return QVariantMap();
}
QString fieldRef = QgsExpression::quotedColumnRef( fieldName );
QString quotedVal = QgsExpression::quotedValue( value );
QString expr;
switch ( op )
{
case Equals:
expr = QStringLiteral( "%1 = %3" ).arg( fieldRef, quotedVal );
break;
case NotEquals:
expr = QStringLiteral( "%1 != %3" ).arg( fieldRef, quotedVal );
break;
case GreaterThan:
expr = QStringLiteral( "%1 > %3" ).arg( fieldRef, quotedVal );
break;
case GreaterThanEqualTo:
expr = QStringLiteral( "%1 >= %3" ).arg( fieldRef, quotedVal );
break;
case LessThan:
expr = QStringLiteral( "%1 < %3" ).arg( fieldRef, quotedVal );
break;
case LessThanEqualTo:
expr = QStringLiteral( "%1 <= %3" ).arg( fieldRef, quotedVal );
break;
case BeginsWith:
expr = QStringLiteral( "%1 LIKE '%2%'" ).arg( fieldRef, value );
break;
case Contains:
expr = QStringLiteral( "%1 LIKE '%%2%'" ).arg( fieldRef, value );
break;
case IsNull:
expr = QStringLiteral( "%1 IS NULL" ).arg( fieldRef );
break;
case IsNotNull:
expr = QStringLiteral( "%1 IS NOT NULL" ).arg( fieldRef );
break;
case DoesNotContain:
expr = QStringLiteral( "%1 NOT LIKE '%%2%'" ).arg( fieldRef, value );
break;
}
QgsExpression expression( expr );
if ( expression.hasParserError() )
{
// raise GeoAlgorithmExecutionException(expression.parserErrorString())
return QVariantMap();
}
QgsExpressionContext expressionContext = createExpressionContext( parameters, context );
long count = source->featureCount();
if ( count <= 0 )
return QVariantMap();
double step = 100.0 / count;
int current = 0;
if ( !nonMatchingSink )
{
// not saving failing features - so only fetch good features
QgsFeatureRequest req;
req.setFilterExpression( expr );
req.setExpressionContext( expressionContext );
QgsFeatureIterator it = source->getFeatures( req );
QgsFeature f;
while ( it.nextFeature( f ) )
{
if ( feedback->isCanceled() )
{
break;
}
matchingSink->addFeature( f );
feedback->setProgress( current * step );
current++;
}
}
else
{
// saving non-matching features, so we need EVERYTHING
expressionContext.setFields( source->fields() );
expression.prepare( &expressionContext );
QgsFeatureIterator it = source->getFeatures();
QgsFeature f;
while ( it.nextFeature( f ) )
{
if ( feedback->isCanceled() )
{
break;
}
expressionContext.setFeature( f );
if ( expression.evaluate( &expressionContext ).toBool() )
{
matchingSink->addFeature( f );
}
else
{
nonMatchingSink->addFeature( f );
}
feedback->setProgress( current * step );
current++;
}
}
QVariantMap outputs;
outputs.insert( QStringLiteral( "OUTPUT" ), matchingSinkId );
if ( nonMatchingSink )
outputs.insert( QStringLiteral( "FAIL_OUTPUT" ), nonMatchingSinkId );
return outputs;
}
///@endcond

View File

@ -135,6 +135,67 @@ class QgsDissolveAlgorithm : public QgsProcessingAlgorithm
};
/**
* Native extract by attribute algorithm.
*/
class QgsExtractByAttributeAlgorithm : public QgsProcessingAlgorithm
{
public:
enum Operation
{
Equals,
NotEquals,
GreaterThan,
GreaterThanEqualTo,
LessThan,
LessThanEqualTo,
BeginsWith,
Contains,
IsNull,
IsNotNull,
DoesNotContain,
};
QgsExtractByAttributeAlgorithm();
QString name() const override { return QStringLiteral( "extractbyattribute" ); }
QString displayName() const override { return QObject::tr( "Extract by attribute" ); }
virtual QStringList tags() const override { return QObject::tr( "extract,filter,attribute,value,contains,null,field" ).split( ',' ); }
QString group() const override { return QObject::tr( "Vector selection tools" ); }
QString shortHelpString() const override;
protected:
virtual QVariantMap processAlgorithm( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const override;
};
/**
* Native extract by expression algorithm.
*/
class QgsExtractByExpressionAlgorithm : public QgsProcessingAlgorithm
{
public:
QgsExtractByExpressionAlgorithm();
QString name() const override { return QStringLiteral( "extractbyexpression" ); }
QString displayName() const override { return QObject::tr( "Extract by expression" ); }
virtual QStringList tags() const override { return QObject::tr( "extract,filter,expression,field" ).split( ',' ); }
QString group() const override { return QObject::tr( "Vector selection tools" ); }
QString shortHelpString() const override;
protected:
virtual QVariantMap processAlgorithm( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const override;
};
/**
* Native clip algorithm.
*/
@ -182,6 +243,29 @@ class QgsSubdivideAlgorithm : public QgsProcessingAlgorithm
};
/**
* Native multipart to singlepart algorithm.
*/
class QgsMultipartToSinglepartAlgorithm : public QgsProcessingAlgorithm
{
public:
QgsMultipartToSinglepartAlgorithm();
QString name() const override { return QStringLiteral( "multiparttosingleparts" ); }
QString displayName() const override { return QObject::tr( "Multipart to singleparts" ); }
virtual QStringList tags() const override { return QObject::tr( "multi,single,multiple,split,dump" ).split( ',' ); }
QString group() const override { return QObject::tr( "Vector geometry tools" ); }
QString shortHelpString() const override;
protected:
virtual QVariantMap processAlgorithm( const QVariantMap &parameters,
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const override;
};
///@endcond PRIVATE
#endif // QGSNATIVEALGORITHMS_H

View File

@ -744,14 +744,16 @@ QgsProcessingParameterDefinition *QgsProcessingParameters::parameterFromVariantM
def.reset( new QgsProcessingParameterString( name ) );
else if ( type == QStringLiteral( "expression" ) )
def.reset( new QgsProcessingParameterExpression( name ) );
else if ( type == QStringLiteral( "table" ) )
def.reset( new QgsProcessingParameterTable( name ) );
else if ( type == QStringLiteral( "vector" ) )
def.reset( new QgsProcessingParameterVectorLayer( name ) );
else if ( type == QStringLiteral( "field" ) )
def.reset( new QgsProcessingParameterTableField( name ) );
def.reset( new QgsProcessingParameterField( name ) );
else if ( type == QStringLiteral( "source" ) )
def.reset( new QgsProcessingParameterFeatureSource( name ) );
else if ( type == QStringLiteral( "sink" ) )
def.reset( new QgsProcessingParameterFeatureSink( name ) );
else if ( type == QStringLiteral( "vectorOut" ) )
def.reset( new QgsProcessingParameterVectorOutput( name ) );
else if ( type == QStringLiteral( "rasterOut" ) )
def.reset( new QgsProcessingParameterRasterOutput( name ) );
else if ( type == QStringLiteral( "fileOut" ) )
@ -1731,13 +1733,53 @@ bool QgsProcessingParameterExpression::fromVariantMap( const QVariantMap &map )
return true;
}
QgsProcessingParameterTable::QgsProcessingParameterTable( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
QgsProcessingParameterVectorLayer::QgsProcessingParameterVectorLayer( const QString &name, const QString &description, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
{
}
QgsProcessingParameterTableField::QgsProcessingParameterTableField( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, DataType type, bool allowMultiple, bool optional )
bool QgsProcessingParameterVectorLayer::checkValueIsAcceptable( const QVariant &var, QgsProcessingContext *context ) const
{
if ( !var.isValid() )
return mFlags & FlagOptional;
if ( var.canConvert<QgsProperty>() )
{
return true;
}
if ( qobject_cast< QgsVectorLayer * >( qvariant_cast<QObject *>( var ) ) )
return true;
if ( var.type() != QVariant::String || var.toString().isEmpty() )
return mFlags & FlagOptional;
if ( !context )
{
// that's as far as we can get without a context
return true;
}
// try to load as layer
if ( QgsProcessingUtils::mapLayerFromString( var.toString(), *context ) )
return true;
return false;
}
QString QgsProcessingParameterVectorLayer::valueAsPythonString( const QVariant &val, QgsProcessingContext &context ) const
{
if ( val.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( val.value< QgsProperty >().asExpression() );
QVariantMap p;
p.insert( name(), val );
QgsVectorLayer *layer = QgsProcessingParameters::parameterAsVectorLayer( this, p, context );
return layer ? QgsProcessingUtils::normalizeLayerSource( layer->source() ).prepend( '\'' ).append( '\'' ) : QString();
}
QgsProcessingParameterField::QgsProcessingParameterField( const QString &name, const QString &description, const QVariant &defaultValue, const QString &parentLayerParameterName, DataType type, bool allowMultiple, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mParentLayerParameter( parentLayerParameterName )
, mDataType( type )
@ -1746,7 +1788,7 @@ QgsProcessingParameterTableField::QgsProcessingParameterTableField( const QStrin
}
bool QgsProcessingParameterTableField::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
bool QgsProcessingParameterField::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
if ( !input.isValid() )
return mFlags & FlagOptional;
@ -1778,7 +1820,7 @@ bool QgsProcessingParameterTableField::checkValueIsAcceptable( const QVariant &i
return true;
}
QString QgsProcessingParameterTableField::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
QString QgsProcessingParameterField::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
{
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
@ -1805,37 +1847,37 @@ QString QgsProcessingParameterTableField::valueAsPythonString( const QVariant &v
return value.toString().prepend( '\'' ).append( '\'' );
}
QString QgsProcessingParameterTableField::parentLayerParameter() const
QString QgsProcessingParameterField::parentLayerParameter() const
{
return mParentLayerParameter;
}
void QgsProcessingParameterTableField::setParentLayerParameter( const QString &parentLayerParameter )
void QgsProcessingParameterField::setParentLayerParameter( const QString &parentLayerParameter )
{
mParentLayerParameter = parentLayerParameter;
}
QgsProcessingParameterTableField::DataType QgsProcessingParameterTableField::dataType() const
QgsProcessingParameterField::DataType QgsProcessingParameterField::dataType() const
{
return mDataType;
}
void QgsProcessingParameterTableField::setDataType( const DataType &dataType )
void QgsProcessingParameterField::setDataType( const DataType &dataType )
{
mDataType = dataType;
}
bool QgsProcessingParameterTableField::allowMultiple() const
bool QgsProcessingParameterField::allowMultiple() const
{
return mAllowMultiple;
}
void QgsProcessingParameterTableField::setAllowMultiple( bool allowMultiple )
void QgsProcessingParameterField::setAllowMultiple( bool allowMultiple )
{
mAllowMultiple = allowMultiple;
}
QVariantMap QgsProcessingParameterTableField::toVariantMap() const
QVariantMap QgsProcessingParameterField::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "parent_layer" ), mParentLayerParameter );
@ -1844,7 +1886,7 @@ QVariantMap QgsProcessingParameterTableField::toVariantMap() const
return map;
}
bool QgsProcessingParameterTableField::fromVariantMap( const QVariantMap &map )
bool QgsProcessingParameterField::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mParentLayerParameter = map.value( QStringLiteral( "parent_layer" ) ).toString();
@ -2208,3 +2250,100 @@ bool QgsProcessingParameterFolderOutput::checkValueIsAcceptable( const QVariant
return true;
}
QgsProcessingParameterVectorOutput::QgsProcessingParameterVectorOutput( const QString &name, const QString &description, QgsProcessingParameterDefinition::LayerType type, const QVariant &defaultValue, bool optional )
: QgsProcessingParameterDefinition( name, description, defaultValue, optional )
, mDataType( type )
{
}
bool QgsProcessingParameterVectorOutput::checkValueIsAcceptable( const QVariant &input, QgsProcessingContext * ) const
{
QVariant var = input;
if ( !var.isValid() )
return mFlags & FlagOptional;
if ( var.canConvert<QgsProcessingOutputLayerDefinition>() )
{
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( var );
var = fromVar.sink;
}
if ( var.canConvert<QgsProperty>() )
{
return true;
}
if ( var.type() != QVariant::String )
return false;
if ( var.toString().isEmpty() )
return mFlags & FlagOptional;
return true;
}
QString QgsProcessingParameterVectorOutput::valueAsPythonString( const QVariant &value, QgsProcessingContext & ) const
{
if ( value.canConvert<QgsProperty>() )
return QStringLiteral( "QgsProperty.fromExpression('%1')" ).arg( value.value< QgsProperty >().asExpression() );
if ( value.canConvert<QgsProcessingOutputLayerDefinition>() )
{
QgsProcessingOutputLayerDefinition fromVar = qvariant_cast<QgsProcessingOutputLayerDefinition>( value );
if ( fromVar.sink.propertyType() == QgsProperty::StaticProperty )
{
return QStringLiteral( "QgsProcessingOutputLayerDefinition('%1')" ).arg( fromVar.sink.staticValue().toString() );
}
else
{
return QStringLiteral( "QgsProcessingOutputLayerDefinition(QgsProperty.fromExpression('%1'))" ).arg( fromVar.sink.asExpression() );
}
}
return value.toString().prepend( '\'' ).append( '\'' );
}
QgsProcessingParameterDefinition::LayerType QgsProcessingParameterVectorOutput::dataType() const
{
return mDataType;
}
bool QgsProcessingParameterVectorOutput::hasGeometry() const
{
switch ( mDataType )
{
case TypeAny:
case TypeVectorAny:
case TypeVectorPoint:
case TypeVectorLine:
case TypeVectorPolygon:
case TypeTable:
return true;
case TypeRaster:
case TypeFile:
return false;
}
return true;
}
void QgsProcessingParameterVectorOutput::setDataType( QgsProcessingParameterDefinition::LayerType type )
{
mDataType = type;
}
QVariantMap QgsProcessingParameterVectorOutput::toVariantMap() const
{
QVariantMap map = QgsProcessingParameterDefinition::toVariantMap();
map.insert( QStringLiteral( "data_type" ), mDataType );
return map;
}
bool QgsProcessingParameterVectorOutput::fromVariantMap( const QVariantMap &map )
{
QgsProcessingParameterDefinition::fromVariantMap( map );
mDataType = static_cast< QgsProcessingParameterDefinition::LayerType >( map.value( QStringLiteral( "data_type" ) ).toInt() );
return true;
}

View File

@ -198,14 +198,16 @@ class CORE_EXPORT QgsProcessingParameterDefinition
sipType = sipType_QgsProcessingParameterString;
else if ( sipCpp->type() == "expression" )
sipType = sipType_QgsProcessingParameterExpression;
else if ( sipCpp->type() == "table" )
sipType = sipType_QgsProcessingParameterTable;
else if ( sipCpp->type() == "vector" )
sipType = sipType_QgsProcessingParameterVectorLayer;
else if ( sipCpp->type() == "field" )
sipType = sipType_QgsProcessingParameterTableField;
sipType = sipType_QgsProcessingParameterField;
else if ( sipCpp->type() == "source" )
sipType = sipType_QgsProcessingParameterFeatureSource;
else if ( sipCpp->type() == "sink" )
sipType = sipType_QgsProcessingParameterFeatureSink;
else if ( sipCpp->type() == "vectorOut" )
sipType = sipType_QgsProcessingParameterVectorOutput;
else if ( sipCpp->type() == "rasterOut" )
sipType = sipType_QgsProcessingParameterRasterOutput;
else if ( sipCpp->type() == "fileOut" )
@ -1121,32 +1123,35 @@ class CORE_EXPORT QgsProcessingParameterExpression : public QgsProcessingParamet
};
/**
* \class QgsProcessingParameterTable
* \class QgsProcessingParameterVectorLayer
* \ingroup core
* A table (i.e. vector layers with or without geometry) parameter for processing algorithms.
* A vector layer (with or without geometry) parameter for processing algorithms. Consider using
* the more versatile QgsProcessingParameterFeatureSource wherever possible.
* \since QGIS 3.0
*/
class CORE_EXPORT QgsProcessingParameterTable : public QgsProcessingParameterDefinition
class CORE_EXPORT QgsProcessingParameterVectorLayer : public QgsProcessingParameterDefinition
{
public:
/**
* Constructor for QgsProcessingParameterTable.
* Constructor for QgsProcessingParameterVectorLayer.
*/
QgsProcessingParameterTable( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
bool optional = false );
QgsProcessingParameterVectorLayer( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
bool optional = false );
QString type() const override { return QStringLiteral( "table" ); }
QString type() const override { return QStringLiteral( "vector" ); }
bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = nullptr ) const override;
QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const override;
};
/**
* \class QgsProcessingParameterTableField
* \class QgsProcessingParameterField
* \ingroup core
* A table field parameter for processing algorithms.
* A vector layer or feature source field parameter for processing algorithms.
* \since QGIS 3.0
*/
class CORE_EXPORT QgsProcessingParameterTableField : public QgsProcessingParameterDefinition
class CORE_EXPORT QgsProcessingParameterField : public QgsProcessingParameterDefinition
{
public:
@ -1160,13 +1165,13 @@ class CORE_EXPORT QgsProcessingParameterTableField : public QgsProcessingParamet
};
/**
* Constructor for QgsProcessingParameterTableField.
* Constructor for QgsProcessingParameterField.
*/
QgsProcessingParameterTableField( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
const QString &parentLayerParameterName = QString(),
DataType type = Any,
bool allowMultiple = false,
bool optional = false );
QgsProcessingParameterField( const QString &name, const QString &description = QString(), const QVariant &defaultValue = QVariant(),
const QString &parentLayerParameterName = QString(),
DataType type = Any,
bool allowMultiple = false,
bool optional = false );
QString type() const override { return QStringLiteral( "field" ); }
bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = nullptr ) const override;
@ -1311,6 +1316,55 @@ class CORE_EXPORT QgsProcessingParameterFeatureSink : public QgsProcessingParame
QgsProcessingParameterDefinition::LayerType mDataType = QgsProcessingParameterDefinition::TypeVectorAny;
};
/**
* \class QgsProcessingParameterVectorOutput
* \ingroup core
* A vector layer output parameter. Consider using the more flexible QgsProcessingParameterFeatureSink wherever
* possible.
* \since QGIS 3.0
*/
class CORE_EXPORT QgsProcessingParameterVectorOutput : public QgsProcessingParameterDefinition
{
public:
/**
* Constructor for QgsProcessingParameterVectorOutput.
*/
QgsProcessingParameterVectorOutput( const QString &name, const QString &description = QString(), QgsProcessingParameterDefinition::LayerType type = QgsProcessingParameterDefinition::TypeVectorAny, const QVariant &defaultValue = QVariant(),
bool optional = false );
QString type() const override { return QStringLiteral( "vectorOut" ); }
bool isDestination() const override { return true; }
bool checkValueIsAcceptable( const QVariant &input, QgsProcessingContext *context = nullptr ) const override;
QString valueAsPythonString( const QVariant &value, QgsProcessingContext &context ) const override;
/**
* Returns the layer type for layers associated with the parameter.
* \see setDataType()
*/
QgsProcessingParameterDefinition::LayerType dataType() const;
/**
* Returns true if the layer is likely to include geometries. In cases were presence of geometry
* cannot be reliably determined in advance, this method will default to returning true.
*/
bool hasGeometry() const;
/**
* Sets the layer \a type for the layers associated with the parameter.
* \see dataType()
*/
void setDataType( QgsProcessingParameterDefinition::LayerType type );
QVariantMap toVariantMap() const override;
bool fromVariantMap( const QVariantMap &map ) override;
private:
QgsProcessingParameterDefinition::LayerType mDataType = QgsProcessingParameterDefinition::TypeVectorAny;
};
/**
* \class QgsProcessingParameterRasterOutput
* \ingroup core

View File

@ -314,8 +314,10 @@ class TestQgsProcessing: public QObject
void parameterString();
void parameterExpression();
void parameterField();
void parameterVectorLayer();
void parameterFeatureSource();
void parameterFeatureSink();
void parameterVectorOut();
void parameterRasterOut();
void parameterFileOut();
void parameterFolderOut();
@ -2507,7 +2509,7 @@ void TestQgsProcessing::parameterField()
QgsProcessingContext context;
// not optional!
std::unique_ptr< QgsProcessingParameterTableField > def( new QgsProcessingParameterTableField( "non_optional", QString(), QString(), QString(), QgsProcessingParameterTableField::Any, false, false ) );
std::unique_ptr< QgsProcessingParameterField > def( new QgsProcessingParameterField( "non_optional", QString(), QString(), QString(), QgsProcessingParameterField::Any, false, false ) );
QVERIFY( def->checkValueIsAcceptable( 1 ) );
QVERIFY( def->checkValueIsAcceptable( "test" ) );
QVERIFY( !def->checkValueIsAcceptable( QStringList() << "a" << "b" ) );
@ -2525,7 +2527,7 @@ void TestQgsProcessing::parameterField()
QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) );
// multiple
def.reset( new QgsProcessingParameterTableField( "non_optional", QString(), QString(), QString(), QgsProcessingParameterTableField::Any, true, false ) );
def.reset( new QgsProcessingParameterField( "non_optional", QString(), QString(), QString(), QgsProcessingParameterField::Any, true, false ) );
QVERIFY( def->checkValueIsAcceptable( 1 ) );
QVERIFY( def->checkValueIsAcceptable( "test" ) );
QVERIFY( def->checkValueIsAcceptable( QStringList() << "a" << "b" ) );
@ -2544,7 +2546,7 @@ void TestQgsProcessing::parameterField()
QCOMPARE( def->valueAsPythonString( QStringList() << "a" << "b", context ), QStringLiteral( "['a','b']" ) );
QVariantMap map = def->toVariantMap();
QgsProcessingParameterTableField fromMap( "x" );
QgsProcessingParameterField fromMap( "x" );
QVERIFY( fromMap.fromVariantMap( map ) );
QCOMPARE( fromMap.name(), def->name() );
QCOMPARE( fromMap.description(), def->description() );
@ -2553,11 +2555,11 @@ void TestQgsProcessing::parameterField()
QCOMPARE( fromMap.parentLayerParameter(), def->parentLayerParameter() );
QCOMPARE( fromMap.dataType(), def->dataType() );
QCOMPARE( fromMap.allowMultiple(), def->allowMultiple() );
def.reset( dynamic_cast< QgsProcessingParameterTableField *>( QgsProcessingParameters::parameterFromVariantMap( map ) ) );
QVERIFY( dynamic_cast< QgsProcessingParameterTableField *>( def.get() ) );
def.reset( dynamic_cast< QgsProcessingParameterField *>( QgsProcessingParameters::parameterFromVariantMap( map ) ) );
QVERIFY( dynamic_cast< QgsProcessingParameterField *>( def.get() ) );
// optional
def.reset( new QgsProcessingParameterTableField( "optional", QString(), QString( "def" ), QString(), QgsProcessingParameterTableField::Any, false, true ) );
def.reset( new QgsProcessingParameterField( "optional", QString(), QString( "def" ), QString(), QgsProcessingParameterField::Any, false, true ) );
QVERIFY( def->checkValueIsAcceptable( 1 ) );
QVERIFY( def->checkValueIsAcceptable( "test" ) );
QVERIFY( !def->checkValueIsAcceptable( QStringList() << "a" << "b" ) );
@ -2570,13 +2572,13 @@ void TestQgsProcessing::parameterField()
QCOMPARE( fields, QStringList() << "def" );
// optional, no default
def.reset( new QgsProcessingParameterTableField( "optional", QString(), QVariant(), QString(), QgsProcessingParameterTableField::Any, false, true ) );
def.reset( new QgsProcessingParameterField( "optional", QString(), QVariant(), QString(), QgsProcessingParameterField::Any, false, true ) );
params.insert( "optional", QVariant() );
fields = QgsProcessingParameters::parameterAsFields( def.get(), params, context );
QVERIFY( fields.isEmpty() );
//optional with multiples
def.reset( new QgsProcessingParameterTableField( "optional", QString(), QString( "abc;def" ), QString(), QgsProcessingParameterTableField::Any, true, true ) );
def.reset( new QgsProcessingParameterField( "optional", QString(), QString( "abc;def" ), QString(), QgsProcessingParameterField::Any, true, true ) );
QVERIFY( def->checkValueIsAcceptable( 1 ) );
QVERIFY( def->checkValueIsAcceptable( "test" ) );
QVERIFY( def->checkValueIsAcceptable( QStringList() << "a" << "b" ) );
@ -2587,12 +2589,102 @@ void TestQgsProcessing::parameterField()
params.insert( "optional", QVariant() );
fields = QgsProcessingParameters::parameterAsFields( def.get(), params, context );
QCOMPARE( fields, QStringList() << "abc" << "def" );
def.reset( new QgsProcessingParameterTableField( "optional", QString(), QVariantList() << "abc" << "def", QString(), QgsProcessingParameterTableField::Any, true, true ) );
def.reset( new QgsProcessingParameterField( "optional", QString(), QVariantList() << "abc" << "def", QString(), QgsProcessingParameterField::Any, true, true ) );
params.insert( "optional", QVariant() );
fields = QgsProcessingParameters::parameterAsFields( def.get(), params, context );
QCOMPARE( fields, QStringList() << "abc" << "def" );
}
void TestQgsProcessing::parameterVectorLayer()
{
// setup a context
QgsProject p;
p.setCrs( QgsCoordinateReferenceSystem::fromEpsgId( 28353 ) );
QString testDataDir = QStringLiteral( TEST_DATA_DIR ) + '/'; //defined in CmakeLists.txt
QString vector1 = testDataDir + "multipoint.shp";
QString raster = testDataDir + "landsat.tif";
QFileInfo fi1( raster );
QFileInfo fi2( vector1 );
QgsRasterLayer *r1 = new QgsRasterLayer( fi1.filePath(), "R1" );
QgsVectorLayer *v1 = new QgsVectorLayer( fi2.filePath(), "V4", "ogr" );
p.addMapLayers( QList<QgsMapLayer *>() << v1 << r1 );
QgsProcessingContext context;
context.setProject( &p );
// not optional!
std::unique_ptr< QgsProcessingParameterVectorLayer > def( new QgsProcessingParameterVectorLayer( "non_optional", QString(), QString( "somelayer" ), false ) );
QVERIFY( !def->checkValueIsAcceptable( false ) );
QVERIFY( !def->checkValueIsAcceptable( true ) );
QVERIFY( !def->checkValueIsAcceptable( 5 ) );
QVERIFY( def->checkValueIsAcceptable( "layer12312312" ) );
QVERIFY( !def->checkValueIsAcceptable( "" ) );
QVERIFY( !def->checkValueIsAcceptable( QVariant() ) );
QVERIFY( !def->checkValueIsAcceptable( QgsProcessingFeatureSourceDefinition( "layer1231123" ) ) );
QVERIFY( def->checkValueIsAcceptable( QVariant::fromValue( v1 ) ) );
QVERIFY( !def->checkValueIsAcceptable( QVariant::fromValue( r1 ) ) );
// should be OK
QVERIFY( def->checkValueIsAcceptable( "c:/Users/admin/Desktop/roads_clipped_transformed_v1_reprojected_final_clipped_aAAA.shp" ) );
// ... unless we use context, when the check that the layer actually exists is performed
QVERIFY( !def->checkValueIsAcceptable( "c:/Users/admin/Desktop/roads_clipped_transformed_v1_reprojected_final_clipped_aAAA.shp", &context ) );
// using existing map layer ID
QVariantMap params;
params.insert( "non_optional", v1->id() );
QCOMPARE( QgsProcessingParameters::parameterAsVectorLayer( def.get(), params, context )->id(), v1->id() );
// using existing layer
params.insert( "non_optional", QVariant::fromValue( v1 ) );
QCOMPARE( QgsProcessingParameters::parameterAsVectorLayer( def.get(), params, context )->id(), v1->id() );
// not vector layer
params.insert( "non_optional", r1->id() );
QVERIFY( !QgsProcessingParameters::parameterAsVectorLayer( def.get(), params, context ) );
// using existing non-vector layer
params.insert( "non_optional", QVariant::fromValue( r1 ) );
QVERIFY( !QgsProcessingParameters::parameterAsVectorLayer( def.get(), params, context ) );
// string representing a layer source
params.insert( "non_optional", vector1 );
QCOMPARE( QgsProcessingParameters::parameterAsVectorLayer( def.get(), params, context )->publicSource(), vector1 );
// nonsense string
params.insert( "non_optional", QString( "i'm not a layer, and nothing you can do will make me one" ) );
QVERIFY( !QgsProcessingParameters::parameterAsVectorLayer( def.get(), params, context ) );
QCOMPARE( def->valueAsPythonString( vector1, context ), QString( "'" ) + testDataDir + QStringLiteral( "multipoint.shp'" ) );
QCOMPARE( def->valueAsPythonString( v1->id(), context ), QString( "'" ) + testDataDir + QStringLiteral( "multipoint.shp'" ) );
QCOMPARE( def->valueAsPythonString( QVariant::fromValue( v1 ), context ), QString( "'" ) + testDataDir + QStringLiteral( "multipoint.shp'" ) );
QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) );
QVariantMap map = def->toVariantMap();
QgsProcessingParameterVectorLayer fromMap( "x" );
QVERIFY( fromMap.fromVariantMap( map ) );
QCOMPARE( fromMap.name(), def->name() );
QCOMPARE( fromMap.description(), def->description() );
QCOMPARE( fromMap.flags(), def->flags() );
QCOMPARE( fromMap.defaultValue(), def->defaultValue() );
def.reset( dynamic_cast< QgsProcessingParameterVectorLayer *>( QgsProcessingParameters::parameterFromVariantMap( map ) ) );
QVERIFY( dynamic_cast< QgsProcessingParameterVectorLayer *>( def.get() ) );
// optional
def.reset( new QgsProcessingParameterVectorLayer( "optional", QString(), v1->id(), true ) );
params.insert( "optional", QVariant() );
QCOMPARE( QgsProcessingParameters::parameterAsVectorLayer( def.get(), params, context )->id(), v1->id() );
QVERIFY( def->checkValueIsAcceptable( false ) );
QVERIFY( def->checkValueIsAcceptable( true ) );
QVERIFY( def->checkValueIsAcceptable( 5 ) );
QVERIFY( def->checkValueIsAcceptable( "layer12312312" ) );
QVERIFY( def->checkValueIsAcceptable( "c:/Users/admin/Desktop/roads_clipped_transformed_v1_reprojected_final_clipped_aAAA.shp" ) );
QVERIFY( def->checkValueIsAcceptable( "" ) );
QVERIFY( def->checkValueIsAcceptable( QVariant() ) );
QVERIFY( def->checkValueIsAcceptable( QgsProcessingFeatureSourceDefinition( "layer1231123" ) ) );
//optional with direct layer default
def.reset( new QgsProcessingParameterVectorLayer( "optional", QString(), QVariant::fromValue( v1 ), true ) );
QCOMPARE( QgsProcessingParameters::parameterAsVectorLayer( def.get(), params, context )->id(), v1->id() );
}
void TestQgsProcessing::parameterFeatureSource()
{
// setup a context
@ -2747,6 +2839,68 @@ void TestQgsProcessing::parameterFeatureSink()
}
void TestQgsProcessing::parameterVectorOut()
{
// setup a context
QgsProject p;
p.setCrs( QgsCoordinateReferenceSystem::fromEpsgId( 28353 ) );
QgsProcessingContext context;
context.setProject( &p );
// not optional!
std::unique_ptr< QgsProcessingParameterVectorOutput > def( new QgsProcessingParameterVectorOutput( "non_optional", QString(), QgsProcessingParameterDefinition::TypeVectorAny, QString( "EPSG:3113" ), false ) );
QVERIFY( !def->checkValueIsAcceptable( false ) );
QVERIFY( !def->checkValueIsAcceptable( true ) );
QVERIFY( !def->checkValueIsAcceptable( 5 ) );
QVERIFY( def->checkValueIsAcceptable( "layer12312312" ) );
QVERIFY( !def->checkValueIsAcceptable( "" ) );
QVERIFY( !def->checkValueIsAcceptable( QVariant() ) );
QVERIFY( def->checkValueIsAcceptable( QgsProcessingOutputLayerDefinition( "layer1231123" ) ) );
// should be OK with or without context - it's an output layer!
QVERIFY( def->checkValueIsAcceptable( "c:/Users/admin/Desktop/roads_clipped_transformed_v1_reprojected_final_clipped_aAAA.shp" ) );
QVERIFY( def->checkValueIsAcceptable( "c:/Users/admin/Desktop/roads_clipped_transformed_v1_reprojected_final_clipped_aAAA.shp", &context ) );
QCOMPARE( def->valueAsPythonString( QStringLiteral( "abc" ), context ), QStringLiteral( "'abc'" ) );
QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( "abc" ) ), context ), QStringLiteral( "QgsProcessingOutputLayerDefinition('abc')" ) );
QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromValue( "abc" ) ) ), context ), QStringLiteral( "QgsProcessingOutputLayerDefinition('abc')" ) );
QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProcessingOutputLayerDefinition( QgsProperty::fromExpression( "\"abc\" || \"def\"" ) ) ), context ), QStringLiteral( "QgsProcessingOutputLayerDefinition(QgsProperty.fromExpression('\"abc\" || \"def\"'))" ) );
QCOMPARE( def->valueAsPythonString( QVariant::fromValue( QgsProperty::fromExpression( "\"a\"=1" ) ), context ), QStringLiteral( "QgsProperty.fromExpression('\"a\"=1')" ) );
QVariantMap map = def->toVariantMap();
QgsProcessingParameterVectorOutput fromMap( "x" );
QVERIFY( fromMap.fromVariantMap( map ) );
QCOMPARE( fromMap.name(), def->name() );
QCOMPARE( fromMap.description(), def->description() );
QCOMPARE( fromMap.flags(), def->flags() );
QCOMPARE( fromMap.defaultValue(), def->defaultValue() );
QCOMPARE( fromMap.dataType(), def->dataType() );
def.reset( dynamic_cast< QgsProcessingParameterVectorOutput *>( QgsProcessingParameters::parameterFromVariantMap( map ) ) );
QVERIFY( dynamic_cast< QgsProcessingParameterVectorOutput *>( def.get() ) );
// optional
def.reset( new QgsProcessingParameterVectorOutput( "optional", QString(), QgsProcessingParameterDefinition::TypeVectorAny, QString(), true ) );
QVERIFY( !def->checkValueIsAcceptable( false ) );
QVERIFY( !def->checkValueIsAcceptable( true ) );
QVERIFY( !def->checkValueIsAcceptable( 5 ) );
QVERIFY( def->checkValueIsAcceptable( "layer12312312" ) );
QVERIFY( def->checkValueIsAcceptable( "c:/Users/admin/Desktop/roads_clipped_transformed_v1_reprojected_final_clipped_aAAA.shp" ) );
QVERIFY( def->checkValueIsAcceptable( "" ) );
QVERIFY( def->checkValueIsAcceptable( QVariant() ) );
QVERIFY( def->checkValueIsAcceptable( QgsProcessingOutputLayerDefinition( "layer1231123" ) ) );
// test hasGeometry
QVERIFY( QgsProcessingParameterVectorOutput( "test", QString(), QgsProcessingParameterDefinition::TypeAny ).hasGeometry() );
QVERIFY( QgsProcessingParameterVectorOutput( "test", QString(), QgsProcessingParameterDefinition::TypeVectorAny ).hasGeometry() );
QVERIFY( QgsProcessingParameterVectorOutput( "test", QString(), QgsProcessingParameterDefinition::TypeVectorPoint ).hasGeometry() );
QVERIFY( QgsProcessingParameterVectorOutput( "test", QString(), QgsProcessingParameterDefinition::TypeVectorLine ).hasGeometry() );
QVERIFY( QgsProcessingParameterVectorOutput( "test", QString(), QgsProcessingParameterDefinition::TypeVectorPolygon ).hasGeometry() );
QVERIFY( !QgsProcessingParameterVectorOutput( "test", QString(), QgsProcessingParameterDefinition::TypeRaster ).hasGeometry() );
QVERIFY( !QgsProcessingParameterVectorOutput( "test", QString(), QgsProcessingParameterDefinition::TypeFile ).hasGeometry() );
QVERIFY( QgsProcessingParameterVectorOutput( "test", QString(), QgsProcessingParameterDefinition::TypeTable ).hasGeometry() );
}
void TestQgsProcessing::parameterRasterOut()
{
// setup a context