mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-19 00:04:52 -04:00
Make value field in 'Stats by category' optional
If not set, only the feature counts for each category will be calculated
This commit is contained in:
parent
30c663eaef
commit
ea2e537cd7
@ -64,8 +64,9 @@ class StatisticsByCategories(QgisAlgorithm):
|
||||
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))
|
||||
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(s) with categories'),
|
||||
parentLayerParameterName=self.INPUT,
|
||||
@ -85,7 +86,10 @@ class StatisticsByCategories(QgisAlgorithm):
|
||||
category_field_names = self.parameterAsFields(parameters, self.CATEGORIES_FIELD_NAME, context)
|
||||
|
||||
value_field_index = source.fields().lookupField(value_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]
|
||||
|
||||
# generate output fields
|
||||
@ -101,7 +105,10 @@ class StatisticsByCategories(QgisAlgorithm):
|
||||
field.setName(name)
|
||||
fields.append(field)
|
||||
|
||||
if value_field.isNumeric():
|
||||
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))
|
||||
@ -140,11 +147,17 @@ class StatisticsByCategories(QgisAlgorithm):
|
||||
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():
|
||||
@ -152,7 +165,10 @@ class StatisticsByCategories(QgisAlgorithm):
|
||||
|
||||
feedback.setProgress(int(current * total))
|
||||
attrs = feat.attributes()
|
||||
if True:
|
||||
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
|
||||
@ -167,15 +183,14 @@ class StatisticsByCategories(QgisAlgorithm):
|
||||
value = NULL
|
||||
else:
|
||||
value = attrs[value_field_index]
|
||||
cat = tuple([attrs[c] for c in category_field_indexes])
|
||||
values[cat].append(value)
|
||||
else:
|
||||
pass
|
||||
|
||||
(sink, dest_id) = self.parameterAsSink(parameters, self.OUTPUT, context,
|
||||
fields, QgsWkbTypes.NoGeometry, QgsCoordinateReferenceSystem())
|
||||
|
||||
if field_type == 'numeric':
|
||||
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)
|
||||
@ -184,6 +199,19 @@ class StatisticsByCategories(QgisAlgorithm):
|
||||
|
||||
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()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user