mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-01 00:46:20 -05:00
Merge pull request #4761 from nyalldawson/algs2
Port more processing algs to new API
This commit is contained in:
commit
b01cae0740
@ -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
|
||||
|
@ -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)')))
|
||||
|
||||
|
@ -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')))
|
||||
|
@ -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()}
|
||||
|
@ -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")))
|
||||
|
@ -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}
|
||||
|
@ -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}
|
||||
|
@ -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}
|
||||
|
@ -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}
|
||||
|
@ -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(),
|
||||
|
@ -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]
|
||||
|
@ -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):
|
||||
|
@ -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
|
||||
|
@ -52,8 +52,8 @@ from qgis.core import (QgsApplication,
|
||||
QgsProcessingParameterEnum,
|
||||
QgsProcessingParameterString,
|
||||
QgsProcessingParameterExpression,
|
||||
QgsProcessingParameterTable,
|
||||
QgsProcessingParameterTableField,
|
||||
QgsProcessingParameterVectorLayer,
|
||||
QgsProcessingParameterField,
|
||||
QgsProcessingParameterFeatureSource,
|
||||
QgsProcessingModelAlgorithm)
|
||||
from qgis.gui import QgsMessageBar
|
||||
|
@ -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)):
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
@ -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 ¶meters,
|
||||
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 ¶mete
|
||||
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 ¶meters, 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 ¶meters, 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 ¶meters, 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
|
||||
|
||||
|
||||
|
@ -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 ¶meters,
|
||||
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 ¶meters,
|
||||
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 ¶meters,
|
||||
QgsProcessingContext &context, QgsProcessingFeedback *feedback ) const override;
|
||||
|
||||
};
|
||||
|
||||
///@endcond PRIVATE
|
||||
|
||||
#endif // QGSNATIVEALGORITHMS_H
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user