Skip to content

Commit eb0c301

Browse files
committed
Push minimumValues/maximumValues up to QgsFeatureSource base class
Allows these methods to be called on feature sources
1 parent cfbed91 commit eb0c301

13 files changed

+205
-6
lines changed

python/core/processing/qgsprocessingutils.sip

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,12 @@ class QgsProcessingFeatureSource : QgsFeatureSource
232232

233233
virtual QString sourceName() const;
234234

235+
virtual QSet<QVariant> uniqueValues( int fieldIndex, int limit = -1 ) const;
236+
237+
virtual QVariant minimumValue( int fieldIndex ) const;
238+
239+
virtual QVariant maximumValue( int fieldIndex ) const;
240+
235241

236242
};
237243

python/core/qgsfeaturesource.sip

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,31 @@ class QgsFeatureSource
8181
If specified, the ``limit`` option can be used to limit the number of returned values.
8282
The base class implementation uses a non-optimised approach of looping through
8383
all features in the source.
84+
.. seealso:: minimumValue()
85+
.. seealso:: maximumValue()
8486
:rtype: set of QVariant
8587
%End
8688

89+
virtual QVariant minimumValue( int fieldIndex ) const;
90+
%Docstring
91+
Returns the minimum value for an attribute column or an invalid variant in case of error.
92+
The base class implementation uses a non-optimised approach of looping through
93+
all features in the source.
94+
.. seealso:: maximumValue()
95+
.. seealso:: uniqueValues()
96+
:rtype: QVariant
97+
%End
98+
99+
virtual QVariant maximumValue( int fieldIndex ) const;
100+
%Docstring
101+
Returns the maximum value for an attribute column or an invalid variant in case of error.
102+
The base class implementation uses a non-optimised approach of looping through
103+
all features in the source.
104+
.. seealso:: minimumValue()
105+
.. seealso:: uniqueValues()
106+
:rtype: QVariant
107+
%End
108+
87109
virtual QgsRectangle sourceExtent() const;
88110
%Docstring
89111
Returns the extent of all geometries from the source.

python/core/qgsvectorlayer.sip

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,7 +1537,8 @@ Assembles mUpdatedFields considering provider fields, joined fields and added fi
15371537
:rtype: list of str
15381538
%End
15391539

1540-
QVariant minimumValue( int index ) const;
1540+
virtual QVariant minimumValue( int index ) const;
1541+
15411542
%Docstring
15421543
Returns the minimum value for an attribute column or an invalid variant in case of error.
15431544
Note that in some circumstances when unsaved changes are present for the layer then the
@@ -1548,7 +1549,8 @@ Assembles mUpdatedFields considering provider fields, joined fields and added fi
15481549
:rtype: QVariant
15491550
%End
15501551

1551-
QVariant maximumValue( int index ) const;
1552+
virtual QVariant maximumValue( int index ) const;
1553+
15521554
%Docstring
15531555
Returns the maximum value for an attribute column or an invalid variant in case of error.
15541556
Note that in some circumstances when unsaved changes are present for the layer then the

src/core/processing/qgsprocessingutils.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -566,3 +566,18 @@ QString QgsProcessingFeatureSource::sourceName() const
566566
return mSource->sourceName();
567567

568568
}
569+
570+
QSet<QVariant> QgsProcessingFeatureSource::uniqueValues( int fieldIndex, int limit ) const
571+
{
572+
return mSource->uniqueValues( fieldIndex, limit );
573+
}
574+
575+
QVariant QgsProcessingFeatureSource::minimumValue( int fieldIndex ) const
576+
{
577+
return mSource->minimumValue( fieldIndex );
578+
}
579+
580+
QVariant QgsProcessingFeatureSource::maximumValue( int fieldIndex ) const
581+
{
582+
return mSource->maximumValue( fieldIndex );
583+
}

src/core/processing/qgsprocessingutils.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,9 @@ class CORE_EXPORT QgsProcessingFeatureSource : public QgsFeatureSource
282282
QgsWkbTypes::Type wkbType() const override;
283283
long featureCount() const override;
284284
QString sourceName() const override;
285+
QSet<QVariant> uniqueValues( int fieldIndex, int limit = -1 ) const override;
286+
QVariant minimumValue( int fieldIndex ) const override;
287+
QVariant maximumValue( int fieldIndex ) const override;
285288

286289
private:
287290

src/core/qgsfeaturesource.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,52 @@ QSet<QVariant> QgsFeatureSource::uniqueValues( int fieldIndex, int limit ) const
4040
return values;
4141
}
4242

43+
QVariant QgsFeatureSource::minimumValue( int fieldIndex ) const
44+
{
45+
if ( fieldIndex < 0 || fieldIndex >= fields().count() )
46+
return QVariant();
47+
48+
QgsFeatureRequest req;
49+
req.setFlags( QgsFeatureRequest::NoGeometry );
50+
req.setSubsetOfAttributes( QgsAttributeList() << fieldIndex );
51+
52+
QVariant min;
53+
QgsFeatureIterator it = getFeatures( req );
54+
QgsFeature f;
55+
while ( it.nextFeature( f ) )
56+
{
57+
QVariant v = f.attribute( fieldIndex );
58+
if ( v.isValid() && qgsVariantLessThan( v, min ) )
59+
{
60+
min = v;
61+
}
62+
}
63+
return min;
64+
}
65+
66+
QVariant QgsFeatureSource::maximumValue( int fieldIndex ) const
67+
{
68+
if ( fieldIndex < 0 || fieldIndex >= fields().count() )
69+
return QVariant();
70+
71+
QgsFeatureRequest req;
72+
req.setFlags( QgsFeatureRequest::NoGeometry );
73+
req.setSubsetOfAttributes( QgsAttributeList() << fieldIndex );
74+
75+
QVariant max;
76+
QgsFeatureIterator it = getFeatures( req );
77+
QgsFeature f;
78+
while ( it.nextFeature( f ) )
79+
{
80+
QVariant v = f.attribute( fieldIndex );
81+
if ( v.isValid() && qgsVariantGreaterThan( v, max ) )
82+
{
83+
max = v;
84+
}
85+
}
86+
return max;
87+
}
88+
4389
QgsRectangle QgsFeatureSource::sourceExtent() const
4490
{
4591
QgsRectangle r;

src/core/qgsfeaturesource.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,27 @@ class CORE_EXPORT QgsFeatureSource
8989
* If specified, the \a limit option can be used to limit the number of returned values.
9090
* The base class implementation uses a non-optimised approach of looping through
9191
* all features in the source.
92+
* \see minimumValue()
93+
* \see maximumValue()
9294
*/
9395
virtual QSet<QVariant> uniqueValues( int fieldIndex, int limit = -1 ) const;
9496

97+
/** Returns the minimum value for an attribute column or an invalid variant in case of error.
98+
* The base class implementation uses a non-optimised approach of looping through
99+
* all features in the source.
100+
* \see maximumValue()
101+
* \see uniqueValues()
102+
*/
103+
virtual QVariant minimumValue( int fieldIndex ) const;
104+
105+
/** Returns the maximum value for an attribute column or an invalid variant in case of error.
106+
* The base class implementation uses a non-optimised approach of looping through
107+
* all features in the source.
108+
* \see minimumValue()
109+
* \see uniqueValues()
110+
*/
111+
virtual QVariant maximumValue( int fieldIndex ) const;
112+
95113
/**
96114
* Returns the extent of all geometries from the source.
97115
* The base class implementation uses a non-optimised approach of looping through

src/core/qgsvectordataprovider.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider, public QgsFeat
177177
* and maximal values. If provider has facilities to retrieve minimal
178178
* value directly, override this function.
179179
*/
180-
virtual QVariant minimumValue( int index ) const;
180+
virtual QVariant minimumValue( int index ) const override;
181181

182182
/**
183183
* Returns the maximum value of an attribute
@@ -187,7 +187,7 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider, public QgsFeat
187187
* and maximal values. If provider has facilities to retrieve maximal
188188
* value directly, override this function.
189189
*/
190-
virtual QVariant maximumValue( int index ) const;
190+
virtual QVariant maximumValue( int index ) const override;
191191

192192
/**
193193
* Returns unique string values of an attribute which contain a specified subset string. Subset

src/core/qgsvectorlayer.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1452,7 +1452,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
14521452
* \see maximumValue()
14531453
* \see uniqueValues()
14541454
*/
1455-
QVariant minimumValue( int index ) const;
1455+
QVariant minimumValue( int index ) const override;
14561456

14571457
/** Returns the maximum value for an attribute column or an invalid variant in case of error.
14581458
* Note that in some circumstances when unsaved changes are present for the layer then the
@@ -1461,7 +1461,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
14611461
* \see minimumValue()
14621462
* \see uniqueValues()
14631463
*/
1464-
QVariant maximumValue( int index ) const;
1464+
QVariant maximumValue( int index ) const override;
14651465

14661466
/** Calculates an aggregated value from the layer's features.
14671467
* \param aggregate aggregate to calculate

tests/src/python/featuresourcetestbase.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,3 +635,15 @@ def testGetFeaturesWithGeometry(self):
635635

636636
assert f.hasGeometry(), 'Expected geometry, got none'
637637
self.assertTrue(f.isValid())
638+
639+
def testUniqueValues(self):
640+
self.assertEqual(set(self.source.uniqueValues(1)), set([-200, 100, 200, 300, 400]))
641+
assert set(['Apple', 'Honey', 'Orange', 'Pear', NULL]) == set(self.source.uniqueValues(2)), 'Got {}'.format(set(self.source.uniqueValues(2)))
642+
643+
def testMinimumValue(self):
644+
self.assertEqual(self.source.minimumValue(1), -200)
645+
self.assertEqual(self.source.minimumValue(2), 'Apple')
646+
647+
def testMaximumValue(self):
648+
self.assertEqual(self.source.maximumValue(1), 400)
649+
self.assertEqual(self.source.maximumValue(2), 'Pear')

0 commit comments

Comments
 (0)