Skip to content
Permalink
Browse files

Make QgsVectorLayer uniqueValues/min/maxValue consider edits

Previously these methods would inconsistently handle the
edit buffer, eg uniqueValues would consider changed attributes
but not added features. Now uniqueValues, minimumValue and
maximumValue all consider both added features and changed
attribute values when performing their calculation.

The most noticable effect of this fix is that the unique
values widget now correctly shows values for features which
have been added but not yet committed to the provider.

(cherry-picked from 50c3592)
  • Loading branch information
nyalldawson committed Aug 17, 2016
1 parent e37ffd0 commit 64b7defd3fd9fc130eaa88a02f1a738355f4c9ec
Showing with 119 additions and 10 deletions.
  1. +22 −4 python/core/qgsvectorlayer.sip
  2. +75 −2 src/core/qgsvectorlayer.cpp
  3. +22 −4 src/core/qgsvectorlayer.h
@@ -1317,17 +1317,35 @@ class QgsVectorLayer : QgsMapLayer
/** Caches joined attributes if required (and not already done) */
void createJoinCaches();

/** Returns unique values for column
/** Calculates a list of unique values contained within an attribute in the layer. Note that
* in some circumstances when unsaved changes are present for the layer then the returned list
* may contain outdated values (for instance when the attribute value in a saved feature has
* been changed inside the edit buffer then the previous saved value will be included in the
* returned list).
* @param index column index for attribute
* @param uniqueValues out: result list
* @param limit maximum number of values to return (-1 if unlimited)
* @param limit maximum number of values to return (or -1 if unlimited)
* @see minimumValue()
* @see maximumValue()
*/
void uniqueValues( int index, QList<QVariant> &uniqueValues /Out/, int limit = -1 );

/** Returns minimum value for an attribute column or invalid variant in case of error */
/** 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
* returned value may be outdated (for instance when the attribute value in a saved feature has
* been changed inside the edit buffer then the previous saved value may be returned as the minimum).
* @see maximumValue()
* @see uniqueValues()
*/
QVariant minimumValue( int index );

/** Returns maximum value for an attribute column or invalid variant in case of error */
/** 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
* returned value may be outdated (for instance when the attribute value in a saved feature has
* been changed inside the edit buffer then the previous saved value may be returned as the maximum).
* @see minimumValue()
* @see uniqueValues()
*/
QVariant maximumValue( int index );

/** Calculates an aggregated value from the layer's features.
@@ -3156,6 +3156,23 @@ void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int
vals << v.toString();
}

QgsFeatureMap added = mEditBuffer->addedFeatures();
QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
while ( addedIt.hasNext() && ( limit < 0 || uniqueValues.count() < limit ) )
{
addedIt.next();
QVariant v = addedIt.value().attribute( index );
if ( v.isValid() )
{
QString vs = v.toString();
if ( !vals.contains( vs ) )
{
vals << vs;
uniqueValues << v;
}
}
}

QMapIterator< QgsFeatureId, QgsAttributeMap > it( mEditBuffer->changedAttributeValues() );
while ( it.hasNext() && ( limit < 0 || uniqueValues.count() < limit ) )
{
@@ -3234,7 +3251,35 @@ QVariant QgsVectorLayer::minimumValue( int index )
return QVariant();

case QgsFields::OriginProvider: //a provider field
return mDataProvider->minimumValue( index );
{
QVariant min = mDataProvider->minimumValue( index );
if ( mEditBuffer )
{
QgsFeatureMap added = mEditBuffer->addedFeatures();
QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
while ( addedIt.hasNext() )
{
addedIt.next();
QVariant v = addedIt.value().attribute( index );
if ( v.isValid() && qgsVariantLessThan( v, min ) )
{
min = v;
}
}

QMapIterator< QgsFeatureId, QgsAttributeMap > it( mEditBuffer->changedAttributeValues() );
while ( it.hasNext() )
{
it.next();
QVariant v = it.value().value( index );
if ( v.isValid() && qgsVariantLessThan( v, min ) )
{
min = v;
}
}
}
return min;
}

case QgsFields::OriginEdit:
{
@@ -3293,7 +3338,35 @@ QVariant QgsVectorLayer::maximumValue( int index )
return QVariant();

case QgsFields::OriginProvider: //a provider field
return mDataProvider->maximumValue( index );
{
QVariant min = mDataProvider->maximumValue( index );
if ( mEditBuffer )
{
QgsFeatureMap added = mEditBuffer->addedFeatures();
QMapIterator< QgsFeatureId, QgsFeature > addedIt( added );
while ( addedIt.hasNext() )
{
addedIt.next();
QVariant v = addedIt.value().attribute( index );
if ( v.isValid() && qgsVariantGreaterThan( v, min ) )
{
min = v;
}
}

QMapIterator< QgsFeatureId, QgsAttributeMap > it( mEditBuffer->changedAttributeValues() );
while ( it.hasNext() )
{
it.next();
QVariant v = it.value().value( index );
if ( v.isValid() && qgsVariantGreaterThan( v, min ) )
{
min = v;
}
}
}
return min;
}

case QgsFields::OriginEdit:
// the layer is editable, but in certain cases it can still be avoided going through all features
@@ -1707,17 +1707,35 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
/** Caches joined attributes if required (and not already done) */
void createJoinCaches();

/** Returns unique values for column
/** Calculates a list of unique values contained within an attribute in the layer. Note that
* in some circumstances when unsaved changes are present for the layer then the returned list
* may contain outdated values (for instance when the attribute value in a saved feature has
* been changed inside the edit buffer then the previous saved value will be included in the
* returned list).
* @param index column index for attribute
* @param uniqueValues out: result list
* @param limit maximum number of values to return (-1 if unlimited)
* @param limit maximum number of values to return (or -1 if unlimited)
* @see minimumValue()
* @see maximumValue()
*/
void uniqueValues( int index, QList<QVariant> &uniqueValues, int limit = -1 );

/** Returns minimum value for an attribute column or invalid variant in case of error */
/** 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
* returned value may be outdated (for instance when the attribute value in a saved feature has
* been changed inside the edit buffer then the previous saved value may be returned as the minimum).
* @see maximumValue()
* @see uniqueValues()
*/
QVariant minimumValue( int index );

/** Returns maximum value for an attribute column or invalid variant in case of error */
/** 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
* returned value may be outdated (for instance when the attribute value in a saved feature has
* been changed inside the edit buffer then the previous saved value may be returned as the maximum).
* @see minimumValue()
* @see uniqueValues()
*/
QVariant maximumValue( int index );

/** Calculates an aggregated value from the layer's features.

0 comments on commit 64b7def

Please sign in to comment.
You can’t perform that action at this time.