mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-12 00:06:43 -04:00
Push minimumValues/maximumValues up to QgsFeatureSource base class
Allows these methods to be called on feature sources
This commit is contained in:
parent
cfbed91103
commit
eb0c3015f9
@ -232,6 +232,12 @@ class QgsProcessingFeatureSource : QgsFeatureSource
|
||||
|
||||
virtual QString sourceName() const;
|
||||
|
||||
virtual QSet<QVariant> uniqueValues( int fieldIndex, int limit = -1 ) const;
|
||||
|
||||
virtual QVariant minimumValue( int fieldIndex ) const;
|
||||
|
||||
virtual QVariant maximumValue( int fieldIndex ) const;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
@ -81,9 +81,31 @@ class QgsFeatureSource
|
||||
If specified, the ``limit`` option can be used to limit the number of returned values.
|
||||
The base class implementation uses a non-optimised approach of looping through
|
||||
all features in the source.
|
||||
.. seealso:: minimumValue()
|
||||
.. seealso:: maximumValue()
|
||||
:rtype: set of QVariant
|
||||
%End
|
||||
|
||||
virtual QVariant minimumValue( int fieldIndex ) const;
|
||||
%Docstring
|
||||
Returns the minimum value for an attribute column or an invalid variant in case of error.
|
||||
The base class implementation uses a non-optimised approach of looping through
|
||||
all features in the source.
|
||||
.. seealso:: maximumValue()
|
||||
.. seealso:: uniqueValues()
|
||||
:rtype: QVariant
|
||||
%End
|
||||
|
||||
virtual QVariant maximumValue( int fieldIndex ) const;
|
||||
%Docstring
|
||||
Returns the maximum value for an attribute column or an invalid variant in case of error.
|
||||
The base class implementation uses a non-optimised approach of looping through
|
||||
all features in the source.
|
||||
.. seealso:: minimumValue()
|
||||
.. seealso:: uniqueValues()
|
||||
:rtype: QVariant
|
||||
%End
|
||||
|
||||
virtual QgsRectangle sourceExtent() const;
|
||||
%Docstring
|
||||
Returns the extent of all geometries from the source.
|
||||
|
@ -1537,7 +1537,8 @@ Assembles mUpdatedFields considering provider fields, joined fields and added fi
|
||||
:rtype: list of str
|
||||
%End
|
||||
|
||||
QVariant minimumValue( int index ) const;
|
||||
virtual QVariant minimumValue( int index ) const;
|
||||
|
||||
%Docstring
|
||||
Returns the minimum value for an attribute column or an invalid variant in case of error.
|
||||
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
|
||||
:rtype: QVariant
|
||||
%End
|
||||
|
||||
QVariant maximumValue( int index ) const;
|
||||
virtual QVariant maximumValue( int index ) const;
|
||||
|
||||
%Docstring
|
||||
Returns the maximum value for an attribute column or an invalid variant in case of error.
|
||||
Note that in some circumstances when unsaved changes are present for the layer then the
|
||||
|
@ -566,3 +566,18 @@ QString QgsProcessingFeatureSource::sourceName() const
|
||||
return mSource->sourceName();
|
||||
|
||||
}
|
||||
|
||||
QSet<QVariant> QgsProcessingFeatureSource::uniqueValues( int fieldIndex, int limit ) const
|
||||
{
|
||||
return mSource->uniqueValues( fieldIndex, limit );
|
||||
}
|
||||
|
||||
QVariant QgsProcessingFeatureSource::minimumValue( int fieldIndex ) const
|
||||
{
|
||||
return mSource->minimumValue( fieldIndex );
|
||||
}
|
||||
|
||||
QVariant QgsProcessingFeatureSource::maximumValue( int fieldIndex ) const
|
||||
{
|
||||
return mSource->maximumValue( fieldIndex );
|
||||
}
|
||||
|
@ -282,6 +282,9 @@ class CORE_EXPORT QgsProcessingFeatureSource : public QgsFeatureSource
|
||||
QgsWkbTypes::Type wkbType() const override;
|
||||
long featureCount() const override;
|
||||
QString sourceName() const override;
|
||||
QSet<QVariant> uniqueValues( int fieldIndex, int limit = -1 ) const override;
|
||||
QVariant minimumValue( int fieldIndex ) const override;
|
||||
QVariant maximumValue( int fieldIndex ) const override;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -40,6 +40,52 @@ QSet<QVariant> QgsFeatureSource::uniqueValues( int fieldIndex, int limit ) const
|
||||
return values;
|
||||
}
|
||||
|
||||
QVariant QgsFeatureSource::minimumValue( int fieldIndex ) const
|
||||
{
|
||||
if ( fieldIndex < 0 || fieldIndex >= fields().count() )
|
||||
return QVariant();
|
||||
|
||||
QgsFeatureRequest req;
|
||||
req.setFlags( QgsFeatureRequest::NoGeometry );
|
||||
req.setSubsetOfAttributes( QgsAttributeList() << fieldIndex );
|
||||
|
||||
QVariant min;
|
||||
QgsFeatureIterator it = getFeatures( req );
|
||||
QgsFeature f;
|
||||
while ( it.nextFeature( f ) )
|
||||
{
|
||||
QVariant v = f.attribute( fieldIndex );
|
||||
if ( v.isValid() && qgsVariantLessThan( v, min ) )
|
||||
{
|
||||
min = v;
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
QVariant QgsFeatureSource::maximumValue( int fieldIndex ) const
|
||||
{
|
||||
if ( fieldIndex < 0 || fieldIndex >= fields().count() )
|
||||
return QVariant();
|
||||
|
||||
QgsFeatureRequest req;
|
||||
req.setFlags( QgsFeatureRequest::NoGeometry );
|
||||
req.setSubsetOfAttributes( QgsAttributeList() << fieldIndex );
|
||||
|
||||
QVariant max;
|
||||
QgsFeatureIterator it = getFeatures( req );
|
||||
QgsFeature f;
|
||||
while ( it.nextFeature( f ) )
|
||||
{
|
||||
QVariant v = f.attribute( fieldIndex );
|
||||
if ( v.isValid() && qgsVariantGreaterThan( v, max ) )
|
||||
{
|
||||
max = v;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
QgsRectangle QgsFeatureSource::sourceExtent() const
|
||||
{
|
||||
QgsRectangle r;
|
||||
|
@ -89,9 +89,27 @@ class CORE_EXPORT QgsFeatureSource
|
||||
* If specified, the \a limit option can be used to limit the number of returned values.
|
||||
* The base class implementation uses a non-optimised approach of looping through
|
||||
* all features in the source.
|
||||
* \see minimumValue()
|
||||
* \see maximumValue()
|
||||
*/
|
||||
virtual QSet<QVariant> uniqueValues( int fieldIndex, int limit = -1 ) const;
|
||||
|
||||
/** Returns the minimum value for an attribute column or an invalid variant in case of error.
|
||||
* The base class implementation uses a non-optimised approach of looping through
|
||||
* all features in the source.
|
||||
* \see maximumValue()
|
||||
* \see uniqueValues()
|
||||
*/
|
||||
virtual QVariant minimumValue( int fieldIndex ) const;
|
||||
|
||||
/** Returns the maximum value for an attribute column or an invalid variant in case of error.
|
||||
* The base class implementation uses a non-optimised approach of looping through
|
||||
* all features in the source.
|
||||
* \see minimumValue()
|
||||
* \see uniqueValues()
|
||||
*/
|
||||
virtual QVariant maximumValue( int fieldIndex ) const;
|
||||
|
||||
/**
|
||||
* Returns the extent of all geometries from the source.
|
||||
* The base class implementation uses a non-optimised approach of looping through
|
||||
|
@ -177,7 +177,7 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider, public QgsFeat
|
||||
* and maximal values. If provider has facilities to retrieve minimal
|
||||
* value directly, override this function.
|
||||
*/
|
||||
virtual QVariant minimumValue( int index ) const;
|
||||
virtual QVariant minimumValue( int index ) const override;
|
||||
|
||||
/**
|
||||
* Returns the maximum value of an attribute
|
||||
@ -187,7 +187,7 @@ class CORE_EXPORT QgsVectorDataProvider : public QgsDataProvider, public QgsFeat
|
||||
* and maximal values. If provider has facilities to retrieve maximal
|
||||
* value directly, override this function.
|
||||
*/
|
||||
virtual QVariant maximumValue( int index ) const;
|
||||
virtual QVariant maximumValue( int index ) const override;
|
||||
|
||||
/**
|
||||
* Returns unique string values of an attribute which contain a specified subset string. Subset
|
||||
|
@ -1452,7 +1452,7 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer, public QgsExpressionConte
|
||||
* \see maximumValue()
|
||||
* \see uniqueValues()
|
||||
*/
|
||||
QVariant minimumValue( int index ) const;
|
||||
QVariant minimumValue( int index ) const override;
|
||||
|
||||
/** Returns the maximum value for an attribute column or an invalid variant in case of error.
|
||||
* 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
|
||||
* \see minimumValue()
|
||||
* \see uniqueValues()
|
||||
*/
|
||||
QVariant maximumValue( int index ) const;
|
||||
QVariant maximumValue( int index ) const override;
|
||||
|
||||
/** Calculates an aggregated value from the layer's features.
|
||||
* \param aggregate aggregate to calculate
|
||||
|
@ -635,3 +635,15 @@ class FeatureSourceTestCase(object):
|
||||
|
||||
assert f.hasGeometry(), 'Expected geometry, got none'
|
||||
self.assertTrue(f.isValid())
|
||||
|
||||
def testUniqueValues(self):
|
||||
self.assertEqual(set(self.source.uniqueValues(1)), set([-200, 100, 200, 300, 400]))
|
||||
assert set(['Apple', 'Honey', 'Orange', 'Pear', NULL]) == set(self.source.uniqueValues(2)), 'Got {}'.format(set(self.source.uniqueValues(2)))
|
||||
|
||||
def testMinimumValue(self):
|
||||
self.assertEqual(self.source.minimumValue(1), -200)
|
||||
self.assertEqual(self.source.minimumValue(2), 'Apple')
|
||||
|
||||
def testMaximumValue(self):
|
||||
self.assertEqual(self.source.maximumValue(1), 400)
|
||||
self.assertEqual(self.source.maximumValue(2), 'Pear')
|
||||
|
@ -62,6 +62,30 @@ class TestQgsFeatureSource(unittest.TestCase):
|
||||
self.assertEqual(layer.dataProvider().uniqueValues(0), {'test', 'test2', 'test3', 'test4'})
|
||||
self.assertEqual(layer.dataProvider().uniqueValues(1), {1, 3, 3, 4})
|
||||
|
||||
def testMinValues(self):
|
||||
"""
|
||||
Test retrieving min values using base class method
|
||||
"""
|
||||
|
||||
# memory provider uses base class method
|
||||
layer = createLayerWithFivePoints()
|
||||
self.assertFalse(layer.dataProvider().minimumValue(-1))
|
||||
self.assertFalse(layer.dataProvider().minimumValue(100))
|
||||
self.assertEqual(layer.dataProvider().minimumValue(0), 'test')
|
||||
self.assertEqual(layer.dataProvider().minimumValue(1), 1)
|
||||
|
||||
def testMaxValues(self):
|
||||
"""
|
||||
Test retrieving min values using base class method
|
||||
"""
|
||||
|
||||
# memory provider uses base class method
|
||||
layer = createLayerWithFivePoints()
|
||||
self.assertFalse(layer.dataProvider().maximumValue(-1))
|
||||
self.assertFalse(layer.dataProvider().maximumValue(100))
|
||||
self.assertEqual(layer.dataProvider().maximumValue(0), 'test4')
|
||||
self.assertEqual(layer.dataProvider().maximumValue(1), 4)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
@ -2511,6 +2511,12 @@ class TestQgsVectorLayerSourceAddedFeaturesInBuffer(unittest.TestCase, FeatureSo
|
||||
"""
|
||||
pass
|
||||
|
||||
def testMinimumValue(self):
|
||||
""" Skip min values test - due to inconsistencies in how null values are treated by providers.
|
||||
They are included here, but providers don't include them.... which is right?
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class TestQgsVectorLayerSourceChangedGeometriesInBuffer(unittest.TestCase, FeatureSourceTestCase):
|
||||
|
||||
@ -2661,6 +2667,21 @@ class TestQgsVectorLayerSourceChangedAttributesInBuffer(unittest.TestCase, Featu
|
||||
"""
|
||||
pass
|
||||
|
||||
def testUniqueValues(self):
|
||||
""" Skip unique values test - as noted in the docs this is unreliable when features are in the buffer
|
||||
"""
|
||||
pass
|
||||
|
||||
def testMinimumValue(self):
|
||||
""" Skip min values test - as noted in the docs this is unreliable when features are in the buffer
|
||||
"""
|
||||
pass
|
||||
|
||||
def testMaximumValue(self):
|
||||
""" Skip max values test - as noted in the docs this is unreliable when features are in the buffer
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class TestQgsVectorLayerSourceDeletedFeaturesInBuffer(unittest.TestCase, FeatureSourceTestCase):
|
||||
|
||||
@ -2746,6 +2767,21 @@ class TestQgsVectorLayerSourceDeletedFeaturesInBuffer(unittest.TestCase, Feature
|
||||
"""
|
||||
pass
|
||||
|
||||
def testUniqueValues(self):
|
||||
""" Skip unique values test - as noted in the docs this is unreliable when features are in the buffer
|
||||
"""
|
||||
pass
|
||||
|
||||
def testMinimumValue(self):
|
||||
""" Skip min values test - as noted in the docs this is unreliable when features are in the buffer
|
||||
"""
|
||||
pass
|
||||
|
||||
def testMaximumValue(self):
|
||||
""" Skip max values test - as noted in the docs this is unreliable when features are in the buffer
|
||||
"""
|
||||
pass
|
||||
|
||||
# TODO:
|
||||
# - fetch rect: feat with changed geometry: 1. in rect, 2. out of rect
|
||||
# - more join tests
|
||||
|
@ -90,6 +90,21 @@ class TestQgsVectorLayerCache(unittest.TestCase, FeatureSourceTestCase):
|
||||
"""
|
||||
pass
|
||||
|
||||
def testUniqueValues(self):
|
||||
""" Skip unique values test - not implemented by the cache (yet)
|
||||
"""
|
||||
pass
|
||||
|
||||
def testMinimumValue(self):
|
||||
""" Skip min values test - not implemented by the cache (yet)
|
||||
"""
|
||||
pass
|
||||
|
||||
def testMaximumValue(self):
|
||||
""" Skip max values test - not implemented by the cache (yet)
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Loading…
x
Reference in New Issue
Block a user