Merge pull request #5154 from nyalldawson/stats

[processing] Improve Stats by Categories algorithm, remove duplicate algs
This commit is contained in:
Nyall Dawson 2017-09-11 15:50:16 +10:00 committed by GitHub
commit 7f5bd00cbf
19 changed files with 1098 additions and 151 deletions

View File

@ -28,6 +28,8 @@ __revision__ = '$Format:%H$'
from qgis.core import (QgsProcessingParameterFeatureSource,
QgsStatisticalSummary,
QgsDateTimeStatisticalSummary,
QgsStringStatisticalSummary,
QgsFeatureRequest,
QgsProcessingParameterField,
QgsProcessingParameterFeatureSink,
@ -36,13 +38,16 @@ from qgis.core import (QgsProcessingParameterFeatureSource,
QgsWkbTypes,
QgsCoordinateReferenceSystem,
QgsFeature,
QgsFeatureSink)
QgsFeatureSink,
QgsProcessing,
NULL)
from qgis.PyQt.QtCore import QVariant
from processing.algs.qgis.QgisAlgorithm import QgisAlgorithm
from collections import defaultdict
class StatisticsByCategories(QgisAlgorithm):
INPUT = 'INPUT'
VALUES_FIELD_NAME = 'VALUES_FIELD_NAME'
CATEGORIES_FIELD_NAME = 'CATEGORIES_FIELD_NAME'
@ -56,13 +61,16 @@ class StatisticsByCategories(QgisAlgorithm):
def initAlgorithm(self, config=None):
self.addParameter(QgsProcessingParameterFeatureSource(self.INPUT,
self.tr('Input vector layer')))
self.tr('Input vector layer'),
types=[QgsProcessing.TypeVector]))
self.addParameter(QgsProcessingParameterField(self.VALUES_FIELD_NAME,
self.tr('Field to calculate statistics on'),
parentLayerParameterName=self.INPUT, type=QgsProcessingParameterField.Numeric))
self.tr(
'Field to calculate statistics on (if empty, only count is calculated)'),
parentLayerParameterName=self.INPUT, optional=True))
self.addParameter(QgsProcessingParameterField(self.CATEGORIES_FIELD_NAME,
self.tr('Field with categories'),
parentLayerParameterName=self.INPUT, type=QgsProcessingParameterField.Any))
self.tr('Field(s) with categories'),
parentLayerParameterName=self.INPUT,
type=QgsProcessingParameterField.Any, allowMultiple=True))
self.addParameter(QgsProcessingParameterFeatureSink(self.OUTPUT, self.tr('Statistics by category')))
@ -75,49 +83,213 @@ class StatisticsByCategories(QgisAlgorithm):
def processAlgorithm(self, parameters, context, feedback):
source = self.parameterAsSource(parameters, self.INPUT, context)
value_field_name = self.parameterAsString(parameters, self.VALUES_FIELD_NAME, context)
category_field_name = self.parameterAsString(parameters, self.CATEGORIES_FIELD_NAME, context)
category_field_names = self.parameterAsFields(parameters, self.CATEGORIES_FIELD_NAME, context)
value_field_index = source.fields().lookupField(value_field_name)
category_field_index = source.fields().lookupField(category_field_name)
if value_field_index >= 0:
value_field = source.fields().at(value_field_index)
else:
value_field = None
category_field_indexes = [source.fields().lookupField(n) for n in category_field_names]
features = source.getFeatures(QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry))
total = 100.0 / source.featureCount() if source.featureCount() else 0
values = {}
# generate output fields
fields = QgsFields()
for c in category_field_indexes:
fields.append(source.fields().at(c))
def addField(name):
"""
Adds a field to the output, keeping the same data type as the value_field
"""
field = value_field
field.setName(name)
fields.append(field)
if value_field is None:
field_type = 'none'
fields.append(QgsField('count', QVariant.Int))
elif value_field.isNumeric():
field_type = 'numeric'
fields.append(QgsField('count', QVariant.Int))
fields.append(QgsField('unique', QVariant.Int))
fields.append(QgsField('min', QVariant.Double))
fields.append(QgsField('max', QVariant.Double))
fields.append(QgsField('range', QVariant.Double))
fields.append(QgsField('sum', QVariant.Double))
fields.append(QgsField('mean', QVariant.Double))
fields.append(QgsField('median', QVariant.Double))
fields.append(QgsField('stddev', QVariant.Double))
fields.append(QgsField('minority', QVariant.Double))
fields.append(QgsField('majority', QVariant.Double))
fields.append(QgsField('q1', QVariant.Double))
fields.append(QgsField('q3', QVariant.Double))
fields.append(QgsField('iqr', QVariant.Double))
elif value_field.type() in (QVariant.Date, QVariant.Time, QVariant.DateTime):
field_type = 'datetime'
fields.append(QgsField('count', QVariant.Int))
fields.append(QgsField('unique', QVariant.Int))
fields.append(QgsField('empty', QVariant.Int))
fields.append(QgsField('filled', QVariant.Int))
# keep same data type for these fields
addField('min')
addField('max')
else:
field_type = 'string'
fields.append(QgsField('count', QVariant.Int))
fields.append(QgsField('unique', QVariant.Int))
fields.append(QgsField('empty', QVariant.Int))
fields.append(QgsField('filled', QVariant.Int))
# keep same data type for these fields
addField('min')
addField('max')
fields.append(QgsField('min_length', QVariant.Int))
fields.append(QgsField('max_length', QVariant.Int))
fields.append(QgsField('mean_length', QVariant.Double))
request = QgsFeatureRequest().setFlags(QgsFeatureRequest.NoGeometry)
if value_field is not None:
attrs = [value_field_index]
else:
attrs = []
attrs.extend(category_field_indexes)
request.setSubsetOfAttributes(attrs)
features = source.getFeatures(request)
total = 50.0 / source.featureCount() if source.featureCount() else 0
if field_type == 'none':
values = defaultdict(lambda: 0)
else:
values = defaultdict(list)
for current, feat in enumerate(features):
if feedback.isCanceled():
break
feedback.setProgress(int(current * total))
attrs = feat.attributes()
try:
value = float(attrs[value_field_index])
cat = attrs[category_field_index]
if cat not in values:
values[cat] = []
values[cat].append(value)
except:
pass
fields = QgsFields()
fields.append(source.fields().at(category_field_index))
fields.append(QgsField('min', QVariant.Double))
fields.append(QgsField('max', QVariant.Double))
fields.append(QgsField('mean', QVariant.Double))
fields.append(QgsField('stddev', QVariant.Double))
fields.append(QgsField('sum', QVariant.Double))
fields.append(QgsField('count', QVariant.Int))
cat = tuple([attrs[c] for c in category_field_indexes])
if field_type == 'none':
values[cat] += 1
continue
if field_type == 'numeric':
if attrs[value_field_index] == NULL:
continue
else:
value = float(attrs[value_field_index])
elif field_type == 'string':
if attrs[value_field_index] == NULL:
value = ''
else:
value = str(attrs[value_field_index])
elif attrs[value_field_index] == NULL:
value = NULL
else:
value = attrs[value_field_index]
values[cat].append(value)
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
fields, QgsWkbTypes.NoGeometry, QgsCoordinateReferenceSystem())
stat = QgsStatisticalSummary(QgsStatisticalSummary.Min | QgsStatisticalSummary.Max |
QgsStatisticalSummary.Mean | QgsStatisticalSummary.StDevSample |
QgsStatisticalSummary.Sum | QgsStatisticalSummary.Count)
for (cat, v) in list(values.items()):
stat.calculate(v)
f = QgsFeature()
f.setAttributes([cat, stat.min(), stat.max(), stat.mean(), stat.sampleStDev(), stat.sum(), stat.count()])
sink.addFeature(f, QgsFeatureSink.FastInsert)
if field_type == 'none':
self.saveCounts(values, sink, feedback)
elif field_type == 'numeric':
self.calcNumericStats(values, sink, feedback)
elif field_type == 'datetime':
self.calcDateTimeStats(values, sink, feedback)
else:
self.calcStringStats(values, sink, feedback)
return {self.OUTPUT: dest_id}
def saveCounts(self, values, sink, feedback):
total = 50.0 / len(values) if values else 0
current = 0
for cat, v in values.items():
if feedback.isCanceled():
break
feedback.setProgress(int(current * total) + 50)
f = QgsFeature()
f.setAttributes(list(cat) + [v])
sink.addFeature(f, QgsFeatureSink.FastInsert)
current += 1
def calcNumericStats(self, values, sink, feedback):
stat = QgsStatisticalSummary()
total = 50.0 / len(values) if values else 0
current = 0
for cat, v in values.items():
if feedback.isCanceled():
break
feedback.setProgress(int(current * total) + 50)
stat.calculate(v)
f = QgsFeature()
f.setAttributes(list(cat) + [stat.count(),
stat.variety(),
stat.min(),
stat.max(),
stat.range(),
stat.sum(),
stat.mean(),
stat.median(),
stat.stDev(),
stat.minority(),
stat.majority(),
stat.firstQuartile(),
stat.thirdQuartile(),
stat.interQuartileRange()])
sink.addFeature(f, QgsFeatureSink.FastInsert)
current += 1
def calcDateTimeStats(self, values, sink, feedback):
stat = QgsDateTimeStatisticalSummary()
total = 50.0 / len(values) if values else 0
current = 0
for cat, v in values.items():
if feedback.isCanceled():
break
feedback.setProgress(int(current * total) + 50)
stat.calculate(v)
f = QgsFeature()
f.setAttributes(list(cat) + [stat.count(),
stat.countDistinct(),
stat.countMissing(),
stat.count() - stat.countMissing(),
stat.statistic(QgsDateTimeStatisticalSummary.Min),
stat.statistic(QgsDateTimeStatisticalSummary.Max)
])
sink.addFeature(f, QgsFeatureSink.FastInsert)
current += 1
def calcStringStats(self, values, sink, feedback):
stat = QgsStringStatisticalSummary()
total = 50.0 / len(values) if values else 0
current = 0
for cat, v in values.items():
if feedback.isCanceled():
break
feedback.setProgress(int(current * total) + 50)
stat.calculate(v)
f = QgsFeature()
f.setAttributes(list(cat) + [stat.count(),
stat.countDistinct(),
stat.countMissing(),
stat.count() - stat.countMissing(),
stat.min(),
stat.max(),
stat.minLength(),
stat.maxLength(),
stat.meanLength()
])
sink.addFeature(f, QgsFeatureSink.FastInsert)
current += 1

View File

@ -1,47 +0,0 @@
##Vector analysis=group
#inputs
##Input=source
##Fields=field multiple Input
##Frequency=sink table
from processing.tools.vector import TableWriter
from collections import defaultdict
from qgis.core import QgsProcessingUtils, QgsFields, QgsField, QgsWkbTypes, QgsFeature
from qgis.PyQt.QtCore import QVariant
from processing.core.GeoAlgorithmExecutionException import GeoAlgorithmExecutionException
inputFields = Input.fields()
fieldIdxs = []
out_fields = QgsFields()
for f in Fields:
idx = inputFields.indexFromName(f)
if idx == -1:
raise GeoAlgorithmExecutionException('Field not found:' + f)
fieldIdxs.append(idx)
out_fields.append(inputFields.at(idx))
out_fields.append(QgsField('FREQ', QVariant.Int))
(sink, Frequency) = self.parameterAsSink(parameters, 'Frequency', context,
out_fields)
counts = {}
feats = Input.getFeatures()
nFeats = Input.featureCount()
counts = defaultdict(int)
for i, feat in enumerate(feats):
feedback.setProgress(int(100 * i / nFeats))
if feedback.isCanceled():
break
attrs = feat.attributes()
clazz = tuple([attrs[i] for i in fieldIdxs])
counts[clazz] += 1
for c in counts:
f = QgsFeature()
f.setAttributes(list(c) + [counts[c]])
sink.addFeature(f)

View File

@ -1,52 +0,0 @@
##Vector analysis=group
# inputs
##input=source
##class_field=field input
##value_field=field input
##N_unique_values=sink
from qgis.PyQt.QtCore import QVariant
from qgis.core import QgsFeature, QgsField, QgsProcessingUtils
fields = input.fields()
fields.append(QgsField('UNIQ_COUNT', QVariant.Int))
(sink, N_unique_values) = self.parameterAsSink(parameters, 'N_unique_values', context,
fields, input.wkbType(), input.sourceCrs())
class_field_index = input.fields().lookupField(class_field)
value_field_index = input.fields().lookupField(value_field)
outFeat = QgsFeature()
classes = {}
feats = input.getFeatures()
nFeat = input.featureCount()
for n, inFeat in enumerate(feats):
if feedback.isCanceled():
break
feedback.setProgress(int(100 * n / nFeat))
attrs = inFeat.attributes()
clazz = attrs[class_field_index]
value = attrs[value_field_index]
if clazz not in classes:
classes[clazz] = []
if value not in classes[clazz]:
classes[clazz].append(value)
feats = input.getFeatures()
for n, inFeat in enumerate(feats):
if feedback.isCanceled():
break
feedback.setProgress(int(100 * n / nFeat))
inGeom = inFeat.geometry()
outFeat.setGeometry(inGeom)
attrs = inFeat.attributes()
clazz = attrs[class_field_index]
attrs.append(len(classes[clazz]))
outFeat.setAttributes(attrs)
sink.addFeature(outFeat)

View File

@ -0,0 +1,48 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>stats_by_cat_date</Name>
<ElementPath>stats_by_cat_date</ElementPath>
<GeometryType>100</GeometryType>
<DatasetSpecificInfo>
<FeatureCount>4</FeatureCount>
</DatasetSpecificInfo>
<PropertyDefn>
<Name>date</Name>
<ElementPath>date</ElementPath>
<Type>String</Type>
<Width>10</Width>
</PropertyDefn>
<PropertyDefn>
<Name>count</Name>
<ElementPath>count</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>unique</Name>
<ElementPath>unique</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>empty</Name>
<ElementPath>empty</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>filled</Name>
<ElementPath>filled</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>min</Name>
<ElementPath>min</ElementPath>
<Type>String</Type>
<Width>10</Width>
</PropertyDefn>
<PropertyDefn>
<Name>max</Name>
<ElementPath>max</ElementPath>
<Type>String</Type>
<Width>10</Width>
</PropertyDefn>
</GMLFeatureClass>
</GMLFeatureClassList>

View File

@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy><gml:null>missing</gml:null></gml:boundedBy>
<gml:featureMember>
<ogr:stats_by_cat_date fid="stats_by_cat_date.0">
<ogr:date>2016/11/30</ogr:date>
<ogr:count>1</ogr:count>
<ogr:unique>1</ogr:unique>
<ogr:empty>0</ogr:empty>
<ogr:filled>1</ogr:filled>
<ogr:min>2016/11/30</ogr:min>
<ogr:max>2016/11/30</ogr:max>
</ogr:stats_by_cat_date>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_date fid="stats_by_cat_date.1">
<ogr:date>2016/11/10</ogr:date>
<ogr:count>1</ogr:count>
<ogr:unique>1</ogr:unique>
<ogr:empty>0</ogr:empty>
<ogr:filled>1</ogr:filled>
<ogr:min>2016/11/10</ogr:min>
<ogr:max>2016/11/10</ogr:max>
</ogr:stats_by_cat_date>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_date fid="stats_by_cat_date.2">
<ogr:count>1</ogr:count>
<ogr:unique>0</ogr:unique>
<ogr:empty>1</ogr:empty>
<ogr:filled>0</ogr:filled>
</ogr:stats_by_cat_date>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_date fid="stats_by_cat_date.3">
<ogr:date>2014/11/30</ogr:date>
<ogr:count>1</ogr:count>
<ogr:unique>1</ogr:unique>
<ogr:empty>0</ogr:empty>
<ogr:filled>1</ogr:filled>
<ogr:min>2014/11/30</ogr:min>
<ogr:max>2014/11/30</ogr:max>
</ogr:stats_by_cat_date>
</gml:featureMember>
</ogr:FeatureCollection>

View File

@ -0,0 +1,86 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>stats_by_cat_float</Name>
<ElementPath>stats_by_cat_float</ElementPath>
<GeometryType>100</GeometryType>
<DatasetSpecificInfo>
<FeatureCount>5</FeatureCount>
</DatasetSpecificInfo>
<PropertyDefn>
<Name>name</Name>
<ElementPath>name</ElementPath>
<Type>String</Type>
<Width>2</Width>
</PropertyDefn>
<PropertyDefn>
<Name>count</Name>
<ElementPath>count</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>unique</Name>
<ElementPath>unique</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>min</Name>
<ElementPath>min</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>max</Name>
<ElementPath>max</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>range</Name>
<ElementPath>range</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>sum</Name>
<ElementPath>sum</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>mean</Name>
<ElementPath>mean</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>median</Name>
<ElementPath>median</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>stddev</Name>
<ElementPath>stddev</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>minority</Name>
<ElementPath>minority</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>majority</Name>
<ElementPath>majority</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>q1</Name>
<ElementPath>q1</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>q3</Name>
<ElementPath>q3</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>iqr</Name>
<ElementPath>iqr</ElementPath>
<Type>Real</Type>
</PropertyDefn>
</GMLFeatureClass>
</GMLFeatureClassList>

View File

@ -0,0 +1,103 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy><gml:null>missing</gml:null></gml:boundedBy>
<gml:featureMember>
<ogr:stats_by_cat_float fid="stats_by_cat_float.0">
<ogr:name>aa</ogr:name>
<ogr:count>2</ogr:count>
<ogr:unique>2</ogr:unique>
<ogr:min>3.33</ogr:min>
<ogr:max>44.123456</ogr:max>
<ogr:range>40.793456</ogr:range>
<ogr:sum>47.453456</ogr:sum>
<ogr:mean>23.726728</ogr:mean>
<ogr:median>23.726728</ogr:median>
<ogr:stddev>20.396728</ogr:stddev>
<ogr:minority>3.33</ogr:minority>
<ogr:majority>3.33</ogr:majority>
<ogr:q1>3.33</ogr:q1>
<ogr:q3>44.123456</ogr:q3>
<ogr:iqr>40.793456</ogr:iqr>
</ogr:stats_by_cat_float>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_float fid="stats_by_cat_float.1">
<ogr:name>dd</ogr:name>
<ogr:count>1</ogr:count>
<ogr:unique>1</ogr:unique>
<ogr:min>0</ogr:min>
<ogr:max>0</ogr:max>
<ogr:range>0</ogr:range>
<ogr:sum>0</ogr:sum>
<ogr:mean>0</ogr:mean>
<ogr:median>0</ogr:median>
<ogr:stddev>0</ogr:stddev>
<ogr:minority>0</ogr:minority>
<ogr:majority>0</ogr:majority>
<ogr:q1>0</ogr:q1>
<ogr:q3>0</ogr:q3>
<ogr:iqr>0</ogr:iqr>
</ogr:stats_by_cat_float>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_float fid="stats_by_cat_float.2">
<ogr:name>bb</ogr:name>
<ogr:count>4</ogr:count>
<ogr:unique>1</ogr:unique>
<ogr:min>0.123</ogr:min>
<ogr:max>0.123</ogr:max>
<ogr:range>0</ogr:range>
<ogr:sum>0.492</ogr:sum>
<ogr:mean>0.123</ogr:mean>
<ogr:median>0.123</ogr:median>
<ogr:stddev>0</ogr:stddev>
<ogr:minority>0.123</ogr:minority>
<ogr:majority>0.123</ogr:majority>
<ogr:q1>0.123</ogr:q1>
<ogr:q3>0.123</ogr:q3>
<ogr:iqr>0</ogr:iqr>
</ogr:stats_by_cat_float>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_float fid="stats_by_cat_float.3">
<ogr:count>1</ogr:count>
<ogr:unique>1</ogr:unique>
<ogr:min>-100291.43213</ogr:min>
<ogr:max>-100291.43213</ogr:max>
<ogr:range>0</ogr:range>
<ogr:sum>-100291.43213</ogr:sum>
<ogr:mean>-100291.43213</ogr:mean>
<ogr:median>-100291.43213</ogr:median>
<ogr:stddev>0</ogr:stddev>
<ogr:minority>-100291.43213</ogr:minority>
<ogr:majority>-100291.43213</ogr:majority>
<ogr:q1>-100291.43213</ogr:q1>
<ogr:q3>-100291.43213</ogr:q3>
<ogr:iqr>0</ogr:iqr>
</ogr:stats_by_cat_float>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_float fid="stats_by_cat_float.4">
<ogr:name>cc</ogr:name>
<ogr:count>1</ogr:count>
<ogr:unique>1</ogr:unique>
<ogr:min>0.123</ogr:min>
<ogr:max>0.123</ogr:max>
<ogr:range>0</ogr:range>
<ogr:sum>0.123</ogr:sum>
<ogr:mean>0.123</ogr:mean>
<ogr:median>0.123</ogr:median>
<ogr:stddev>0</ogr:stddev>
<ogr:minority>0.123</ogr:minority>
<ogr:majority>0.123</ogr:majority>
<ogr:q1>0.123</ogr:q1>
<ogr:q3>0.123</ogr:q3>
<ogr:iqr>0</ogr:iqr>
</ogr:stats_by_cat_float>
</gml:featureMember>
</ogr:FeatureCollection>

View File

@ -0,0 +1,26 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>stats_by_cat_no_value</Name>
<ElementPath>stats_by_cat_no_value</ElementPath>
<GeometryType>100</GeometryType>
<DatasetSpecificInfo>
<FeatureCount>6</FeatureCount>
</DatasetSpecificInfo>
<PropertyDefn>
<Name>intval</Name>
<ElementPath>intval</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>name</Name>
<ElementPath>name</ElementPath>
<Type>String</Type>
<Width>2</Width>
</PropertyDefn>
<PropertyDefn>
<Name>count</Name>
<ElementPath>count</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
</GMLFeatureClass>
</GMLFeatureClassList>

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy><gml:null>missing</gml:null></gml:boundedBy>
<gml:featureMember>
<ogr:stats_by_cat_no_value fid="stats_by_cat_no_value.0">
<ogr:intval>1</ogr:intval>
<ogr:name>aa</ogr:name>
<ogr:count>2</ogr:count>
</ogr:stats_by_cat_no_value>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_no_value fid="stats_by_cat_no_value.1">
<ogr:name>dd</ogr:name>
<ogr:count>2</ogr:count>
</ogr:stats_by_cat_no_value>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_no_value fid="stats_by_cat_no_value.2">
<ogr:intval>1</ogr:intval>
<ogr:name>bb</ogr:name>
<ogr:count>3</ogr:count>
</ogr:stats_by_cat_no_value>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_no_value fid="stats_by_cat_no_value.3">
<ogr:intval>120</ogr:intval>
<ogr:count>1</ogr:count>
</ogr:stats_by_cat_no_value>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_no_value fid="stats_by_cat_no_value.4">
<ogr:name>cc</ogr:name>
<ogr:count>1</ogr:count>
</ogr:stats_by_cat_no_value>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_no_value fid="stats_by_cat_no_value.5">
<ogr:intval>2</ogr:intval>
<ogr:name>bb</ogr:name>
<ogr:count>1</ogr:count>
</ogr:stats_by_cat_no_value>
</gml:featureMember>
</ogr:FeatureCollection>

View File

@ -0,0 +1,62 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>stats_by_cat_string</Name>
<ElementPath>stats_by_cat_string</ElementPath>
<GeometryType>100</GeometryType>
<DatasetSpecificInfo>
<FeatureCount>4</FeatureCount>
</DatasetSpecificInfo>
<PropertyDefn>
<Name>intval</Name>
<ElementPath>intval</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>count</Name>
<ElementPath>count</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>unique</Name>
<ElementPath>unique</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>empty</Name>
<ElementPath>empty</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>filled</Name>
<ElementPath>filled</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>min</Name>
<ElementPath>min</ElementPath>
<Type>String</Type>
<Width>2</Width>
</PropertyDefn>
<PropertyDefn>
<Name>max</Name>
<ElementPath>max</ElementPath>
<Type>String</Type>
<Width>2</Width>
</PropertyDefn>
<PropertyDefn>
<Name>min_length</Name>
<ElementPath>min_length</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>max_length</Name>
<ElementPath>max_length</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>mean_length</Name>
<ElementPath>mean_length</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
</GMLFeatureClass>
</GMLFeatureClassList>

View File

@ -0,0 +1,64 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy><gml:null>missing</gml:null></gml:boundedBy>
<gml:featureMember>
<ogr:stats_by_cat_string fid="stats_by_cat_string.0">
<ogr:intval>1</ogr:intval>
<ogr:count>5</ogr:count>
<ogr:unique>2</ogr:unique>
<ogr:empty>0</ogr:empty>
<ogr:filled>5</ogr:filled>
<ogr:min>aa</ogr:min>
<ogr:max>bb</ogr:max>
<ogr:min_length>2</ogr:min_length>
<ogr:max_length>2</ogr:max_length>
<ogr:mean_length>2</ogr:mean_length>
</ogr:stats_by_cat_string>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_string fid="stats_by_cat_string.1">
<ogr:count>3</ogr:count>
<ogr:unique>2</ogr:unique>
<ogr:empty>0</ogr:empty>
<ogr:filled>3</ogr:filled>
<ogr:min>cc</ogr:min>
<ogr:max>dd</ogr:max>
<ogr:min_length>2</ogr:min_length>
<ogr:max_length>2</ogr:max_length>
<ogr:mean_length>2</ogr:mean_length>
</ogr:stats_by_cat_string>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_string fid="stats_by_cat_string.2">
<ogr:intval>120</ogr:intval>
<ogr:count>1</ogr:count>
<ogr:unique>1</ogr:unique>
<ogr:empty>1</ogr:empty>
<ogr:filled>0</ogr:filled>
<ogr:min></ogr:min>
<ogr:max></ogr:max>
<ogr:min_length>0</ogr:min_length>
<ogr:max_length>0</ogr:max_length>
<ogr:mean_length>0</ogr:mean_length>
</ogr:stats_by_cat_string>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_string fid="stats_by_cat_string.3">
<ogr:intval>2</ogr:intval>
<ogr:count>1</ogr:count>
<ogr:unique>1</ogr:unique>
<ogr:empty>0</ogr:empty>
<ogr:filled>1</ogr:filled>
<ogr:min>bb</ogr:min>
<ogr:max>bb</ogr:max>
<ogr:min_length>2</ogr:min_length>
<ogr:max_length>2</ogr:max_length>
<ogr:mean_length>2</ogr:mean_length>
</ogr:stats_by_cat_string>
</gml:featureMember>
</ogr:FeatureCollection>

View File

@ -0,0 +1,91 @@
<GMLFeatureClassList>
<GMLFeatureClass>
<Name>stats_by_cat_two_fields</Name>
<ElementPath>stats_by_cat_two_fields</ElementPath>
<GeometryType>100</GeometryType>
<DatasetSpecificInfo>
<FeatureCount>6</FeatureCount>
</DatasetSpecificInfo>
<PropertyDefn>
<Name>intval</Name>
<ElementPath>intval</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>name</Name>
<ElementPath>name</ElementPath>
<Type>String</Type>
<Width>2</Width>
</PropertyDefn>
<PropertyDefn>
<Name>count</Name>
<ElementPath>count</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>unique</Name>
<ElementPath>unique</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>min</Name>
<ElementPath>min</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>max</Name>
<ElementPath>max</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>range</Name>
<ElementPath>range</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>sum</Name>
<ElementPath>sum</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>mean</Name>
<ElementPath>mean</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>median</Name>
<ElementPath>median</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>stddev</Name>
<ElementPath>stddev</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>minority</Name>
<ElementPath>minority</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>majority</Name>
<ElementPath>majority</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>q1</Name>
<ElementPath>q1</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>q3</Name>
<ElementPath>q3</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>iqr</Name>
<ElementPath>iqr</ElementPath>
<Type>Real</Type>
</PropertyDefn>
</GMLFeatureClass>
</GMLFeatureClassList>

View File

@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8" ?>
<ogr:FeatureCollection
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=""
xmlns:ogr="http://ogr.maptools.org/"
xmlns:gml="http://www.opengis.net/gml">
<gml:boundedBy><gml:null>missing</gml:null></gml:boundedBy>
<gml:featureMember>
<ogr:stats_by_cat_two_fields fid="stats_by_cat_two_fields.0">
<ogr:intval>1</ogr:intval>
<ogr:name>aa</ogr:name>
<ogr:count>2</ogr:count>
<ogr:unique>2</ogr:unique>
<ogr:min>3.33</ogr:min>
<ogr:max>44.123456</ogr:max>
<ogr:range>40.793456</ogr:range>
<ogr:sum>47.453456</ogr:sum>
<ogr:mean>23.726728</ogr:mean>
<ogr:median>23.726728</ogr:median>
<ogr:stddev>20.396728</ogr:stddev>
<ogr:minority>3.33</ogr:minority>
<ogr:majority>3.33</ogr:majority>
<ogr:q1>3.33</ogr:q1>
<ogr:q3>44.123456</ogr:q3>
<ogr:iqr>40.793456</ogr:iqr>
</ogr:stats_by_cat_two_fields>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_two_fields fid="stats_by_cat_two_fields.1">
<ogr:name>dd</ogr:name>
<ogr:count>1</ogr:count>
<ogr:unique>1</ogr:unique>
<ogr:min>0</ogr:min>
<ogr:max>0</ogr:max>
<ogr:range>0</ogr:range>
<ogr:sum>0</ogr:sum>
<ogr:mean>0</ogr:mean>
<ogr:median>0</ogr:median>
<ogr:stddev>0</ogr:stddev>
<ogr:minority>0</ogr:minority>
<ogr:majority>0</ogr:majority>
<ogr:q1>0</ogr:q1>
<ogr:q3>0</ogr:q3>
<ogr:iqr>0</ogr:iqr>
</ogr:stats_by_cat_two_fields>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_two_fields fid="stats_by_cat_two_fields.2">
<ogr:intval>1</ogr:intval>
<ogr:name>bb</ogr:name>
<ogr:count>3</ogr:count>
<ogr:unique>1</ogr:unique>
<ogr:min>0.123</ogr:min>
<ogr:max>0.123</ogr:max>
<ogr:range>0</ogr:range>
<ogr:sum>0.369</ogr:sum>
<ogr:mean>0.123</ogr:mean>
<ogr:median>0.123</ogr:median>
<ogr:stddev>0</ogr:stddev>
<ogr:minority>0.123</ogr:minority>
<ogr:majority>0.123</ogr:majority>
<ogr:q1>0.123</ogr:q1>
<ogr:q3>0.123</ogr:q3>
<ogr:iqr>0</ogr:iqr>
</ogr:stats_by_cat_two_fields>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_two_fields fid="stats_by_cat_two_fields.3">
<ogr:intval>120</ogr:intval>
<ogr:count>1</ogr:count>
<ogr:unique>1</ogr:unique>
<ogr:min>-100291.43213</ogr:min>
<ogr:max>-100291.43213</ogr:max>
<ogr:range>0</ogr:range>
<ogr:sum>-100291.43213</ogr:sum>
<ogr:mean>-100291.43213</ogr:mean>
<ogr:median>-100291.43213</ogr:median>
<ogr:stddev>0</ogr:stddev>
<ogr:minority>-100291.43213</ogr:minority>
<ogr:majority>-100291.43213</ogr:majority>
<ogr:q1>-100291.43213</ogr:q1>
<ogr:q3>-100291.43213</ogr:q3>
<ogr:iqr>0</ogr:iqr>
</ogr:stats_by_cat_two_fields>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_two_fields fid="stats_by_cat_two_fields.4">
<ogr:name>cc</ogr:name>
<ogr:count>1</ogr:count>
<ogr:unique>1</ogr:unique>
<ogr:min>0.123</ogr:min>
<ogr:max>0.123</ogr:max>
<ogr:range>0</ogr:range>
<ogr:sum>0.123</ogr:sum>
<ogr:mean>0.123</ogr:mean>
<ogr:median>0.123</ogr:median>
<ogr:stddev>0</ogr:stddev>
<ogr:minority>0.123</ogr:minority>
<ogr:majority>0.123</ogr:majority>
<ogr:q1>0.123</ogr:q1>
<ogr:q3>0.123</ogr:q3>
<ogr:iqr>0</ogr:iqr>
</ogr:stats_by_cat_two_fields>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_cat_two_fields fid="stats_by_cat_two_fields.5">
<ogr:intval>2</ogr:intval>
<ogr:name>bb</ogr:name>
<ogr:count>1</ogr:count>
<ogr:unique>1</ogr:unique>
<ogr:min>0.123</ogr:min>
<ogr:max>0.123</ogr:max>
<ogr:range>0</ogr:range>
<ogr:sum>0.123</ogr:sum>
<ogr:mean>0.123</ogr:mean>
<ogr:median>0.123</ogr:median>
<ogr:stddev>0</ogr:stddev>
<ogr:minority>0.123</ogr:minority>
<ogr:majority>0.123</ogr:majority>
<ogr:q1>0.123</ogr:q1>
<ogr:q3>0.123</ogr:q3>
<ogr:iqr>0</ogr:iqr>
</ogr:stats_by_cat_two_fields>
</gml:featureMember>
</ogr:FeatureCollection>

View File

@ -11,6 +11,16 @@
<ElementPath>id2</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>count</Name>
<ElementPath>count</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>unique</Name>
<ElementPath>unique</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>min</Name>
<ElementPath>min</ElementPath>
@ -21,24 +31,54 @@
<ElementPath>max</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>range</Name>
<ElementPath>range</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>sum</Name>
<ElementPath>sum</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>mean</Name>
<ElementPath>mean</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>median</Name>
<ElementPath>median</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>stddev</Name>
<ElementPath>stddev</ElementPath>
<Type>Real</Type>
</PropertyDefn>
<PropertyDefn>
<Name>sum</Name>
<ElementPath>sum</ElementPath>
<Name>minority</Name>
<ElementPath>minority</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>count</Name>
<ElementPath>count</ElementPath>
<Name>majority</Name>
<ElementPath>majority</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>q1</Name>
<ElementPath>q1</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>q3</Name>
<ElementPath>q3</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
<PropertyDefn>
<Name>iqr</Name>
<ElementPath>iqr</ElementPath>
<Type>Integer</Type>
</PropertyDefn>
</GMLFeatureClass>

View File

@ -9,34 +9,58 @@
<gml:featureMember>
<ogr:stats_by_category fid="stats_by_category.0">
<ogr:id2>2</ogr:id2>
<ogr:count>2</ogr:count>
<ogr:unique>2</ogr:unique>
<ogr:min>1</ogr:min>
<ogr:max>4</ogr:max>
<ogr:mean>2.5</ogr:mean>
<ogr:stddev>2.12132034355964</ogr:stddev>
<ogr:range>3</ogr:range>
<ogr:sum>5</ogr:sum>
<ogr:count>2</ogr:count>
<ogr:mean>2.5</ogr:mean>
<ogr:median>2.5</ogr:median>
<ogr:stddev>1.5</ogr:stddev>
<ogr:minority>1</ogr:minority>
<ogr:majority>1</ogr:majority>
<ogr:q1>1</ogr:q1>
<ogr:q3>4</ogr:q3>
<ogr:iqr>3</ogr:iqr>
</ogr:stats_by_category>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_category fid="stats_by_category.1">
<ogr:id2>1</ogr:id2>
<ogr:count>2</ogr:count>
<ogr:unique>2</ogr:unique>
<ogr:min>2</ogr:min>
<ogr:max>5</ogr:max>
<ogr:mean>3.5</ogr:mean>
<ogr:stddev>2.12132034355964</ogr:stddev>
<ogr:range>3</ogr:range>
<ogr:sum>7</ogr:sum>
<ogr:count>2</ogr:count>
<ogr:mean>3.5</ogr:mean>
<ogr:median>3.5</ogr:median>
<ogr:stddev>1.5</ogr:stddev>
<ogr:minority>2</ogr:minority>
<ogr:majority>2</ogr:majority>
<ogr:q1>2</ogr:q1>
<ogr:q3>5</ogr:q3>
<ogr:iqr>3</ogr:iqr>
</ogr:stats_by_category>
</gml:featureMember>
<gml:featureMember>
<ogr:stats_by_category fid="stats_by_category.2">
<ogr:id2>0</ogr:id2>
<ogr:count>5</ogr:count>
<ogr:unique>5</ogr:unique>
<ogr:min>3</ogr:min>
<ogr:max>9</ogr:max>
<ogr:mean>6.6</ogr:mean>
<ogr:stddev>2.30217288664427</ogr:stddev>
<ogr:range>6</ogr:range>
<ogr:sum>33</ogr:sum>
<ogr:count>5</ogr:count>
<ogr:mean>6.6</ogr:mean>
<ogr:median>7</ogr:median>
<ogr:stddev>2.0591260281974</ogr:stddev>
<ogr:minority>3</ogr:minority>
<ogr:majority>3</ogr:majority>
<ogr:q1>6</ogr:q1>
<ogr:q3>8</ogr:q3>
<ogr:iqr>2</ogr:iqr>
</ogr:stats_by_category>
</gml:featureMember>
</ogr:FeatureCollection>

View File

@ -3476,3 +3476,98 @@ tests:
name: expected/collect_two_fields.gml
type: vector
- algorithm: qgis:statisticsbycategories
name: Stats by cat (float field)
params:
CATEGORIES_FIELD_NAME:
- name
INPUT:
name: dissolve_polys.gml
type: vector
VALUES_FIELD_NAME: floatval
results:
OUTPUT:
name: expected/stats_by_cat_float.gml
type: vector
pk: name
compare:
fields:
fid: skip
- algorithm: qgis:statisticsbycategories
name: Stats by cat (string field)
params:
CATEGORIES_FIELD_NAME:
- intval
INPUT:
name: dissolve_polys.gml
type: vector
VALUES_FIELD_NAME: name
results:
OUTPUT:
name: expected/stats_by_cat_string.gml
type: vector
pk: intval
compare:
fields:
fid: skip
- algorithm: qgis:statisticsbycategories
name: Stats by cat (two category fields)
params:
CATEGORIES_FIELD_NAME:
- intval
- name
INPUT:
name: dissolve_polys.gml
type: vector
VALUES_FIELD_NAME: floatval
results:
OUTPUT:
name: expected/stats_by_cat_two_fields.gml
type: vector
pk:
- intval
- name
compare:
fields:
fid: skip
- algorithm: qgis:statisticsbycategories
name: Stats by cat (no value field)
params:
CATEGORIES_FIELD_NAME:
- intval
- name
INPUT:
name: dissolve_polys.gml
type: vector
results:
OUTPUT:
name: expected/stats_by_cat_no_value.gml
type: vector
pk:
- intval
- name
compare:
fields:
fid: skip
- algorithm: qgis:statisticsbycategories
name: Stats by cat (date field)
params:
CATEGORIES_FIELD_NAME:
- date
INPUT:
name: custom/datetimes.tab
type: vector
VALUES_FIELD_NAME: date
results:
OUTPUT:
name: expected/stats_by_cat_date.gml
type: vector
pk: date
compare:
fields:
fid: skip

View File

@ -105,7 +105,11 @@ class TestCase(_TestCase):
def sort_by_pk_or_fid(f):
if 'pk' in kwargs and kwargs['pk'] is not None:
return f[kwargs['pk']]
key = kwargs['pk']
if isinstance(key, list) or isinstance(key, tuple):
return [f[k] for k in key]
else:
return f[kwargs['pk']]
else:
return f.id()

View File

@ -2301,6 +2301,9 @@ bool QgsProcessingParameterField::checkValueIsAcceptable( const QVariant &input,
{
if ( !mAllowMultiple )
return false;
if ( input.toList().isEmpty() && !( mFlags & FlagOptional ) )
return false;
}
else if ( input.type() == QVariant::String )
{

View File

@ -2258,6 +2258,8 @@ void TestQgsProcessing::parameterLayerList()
QVERIFY( !def->checkValueIsAcceptable( true ) );
QVERIFY( !def->checkValueIsAcceptable( 5 ) );
QVERIFY( !def->checkValueIsAcceptable( "layer12312312" ) );
QVERIFY( !def->checkValueIsAcceptable( QVariantList() ) );
QVERIFY( !def->checkValueIsAcceptable( QStringList() ) );
QVERIFY( def->checkValueIsAcceptable( QStringList() << "layer12312312" << "layerB" ) );
QVERIFY( def->checkValueIsAcceptable( QVariantList() << "layer12312312" << "layerB" ) );
QVERIFY( !def->checkValueIsAcceptable( "" ) );
@ -3183,6 +3185,8 @@ void TestQgsProcessing::parameterField()
QVERIFY( def->checkValueIsAcceptable( QVariantList() << "a" << "b" ) );
QVERIFY( !def->checkValueIsAcceptable( "" ) );
QVERIFY( !def->checkValueIsAcceptable( QVariant() ) );
QVERIFY( !def->checkValueIsAcceptable( QStringList() ) );
QVERIFY( !def->checkValueIsAcceptable( QVariantList() ) );
params.insert( "non_optional", QString( "a;b" ) );
fields = QgsProcessingParameters::parameterAsFields( def.get(), params, context );