Skip to content

Commit

Permalink
Add uniqueValues() method for vector layer. Fixes #3528
Browse files Browse the repository at this point in the history
git-svn-id: http://svn.osgeo.org/qgis/trunk@15310 c8812cc2-4d05-0410-92ff-de0c093fc19c
  • Loading branch information
mhugent committed Mar 2, 2011
1 parent a75d755 commit 2c0e214
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 10 deletions.
7 changes: 7 additions & 0 deletions python/core/qgsvectorlayer.sip
Expand Up @@ -549,6 +549,13 @@ public:
@note public and static from version 1.4 */
static void drawVertexMarker( double x, double y, QPainter& p, QgsVectorLayer::VertexMarkerType type, int vertexSize );

/**Returns unique values for column
@param index column index for attribute
@param uniqueValues out: result list
@limit maximum number of values to return (-1 if unlimited)
@note: this method was added in version 1.7*/
void uniqueValues( int index, QList<QVariant>& uniqueValues, int limit );

public slots:

/** Select feature by its ID, optionally emit signal selectionChanged() */
Expand Down
61 changes: 61 additions & 0 deletions src/core/qgsvectorlayer.cpp
Expand Up @@ -4942,6 +4942,67 @@ void QgsVectorLayer::createJoinCaches()
}
}

void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int limit )
{
uniqueValues.clear();
if ( !mDataProvider )
{
return;
}

int maxProviderIndex;
QgsVectorLayerJoinBuffer::maximumIndex( mDataProvider->fields(), maxProviderIndex );

if ( index <= maxProviderIndex && !mEditable ) //a provider field
{
return mDataProvider->uniqueValues( index, uniqueValues, limit );
}
else // a joined field?
{
if ( mJoinBuffer )
{
int indexOffset; //offset between layer index and joined provider index
const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, maxProviderIndex, indexOffset );
if ( join )
{
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( join->joinLayerId ) );
if ( vl && vl->dataProvider() )
{
return vl->dataProvider()->uniqueValues( index - indexOffset, uniqueValues, limit );
}
}
}
}


//the layer is editable, but in certain cases it can still be avoided going through all features
if ( mDeletedFeatureIds.size() < 1 && mAddedFeatures.size() < 1 && !mDeletedAttributeIds.contains( index ) && mChangedAttributeValues.size() < 1 )
{
return mDataProvider->uniqueValues( index, uniqueValues, limit );
}

//we need to go through each feature
QgsAttributeList attList;
attList << index;

select( attList, QgsRectangle(), false, false );

QgsFeature f;
QVariant currentValue;
QHash<QString, QVariant> val;
while ( nextFeature( f ) )
{
currentValue = f.attributeMap()[index];
val.insert( currentValue.toString(), currentValue );
if ( limit >= 0 && val.size() >= limit )
{
break;
}
}

uniqueValues = val.values();
}

void QgsVectorLayer::stopRendererV2( QgsRenderContext& rendererContext, QgsSingleSymbolRendererV2* selRenderer )
{
mRendererV2->stopRender( rendererContext );
Expand Down
7 changes: 7 additions & 0 deletions src/core/qgsvectorlayer.h
Expand Up @@ -638,6 +638,13 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
/**Caches joined attributes if required (and not already done)*/
void createJoinCaches();

/**Returns unique values for column
@param index column index for attribute
@param uniqueValues out: result list
@limit maximum number of values to return (-1 if unlimited)
@note: this method was added in version 1.7*/
void uniqueValues( int index, QList<QVariant> &uniqueValues, int limit = -1 );


public slots:
/** Select feature by its ID, optionally emit signal selectionChanged() */
Expand Down
14 changes: 7 additions & 7 deletions src/core/qgsvectorlayerjoinbuffer.h
Expand Up @@ -66,6 +66,13 @@ class CORE_EXPORT QgsVectorLayerJoinBuffer

const QList< QgsVectorJoinInfo >& vectorJoins() const { return mVectorJoins; }

/**Finds the vector join for a layer field index.
@param index this layers attribute index
@param maxProviderIndex maximum attribute index of the vectorlayer provider
@param indexOffset out: offset between layer index and original provider index
@return pointer to the join if the index belongs to a joined field, otherwise 0 (possibily provider field or added field)*/
const QgsVectorJoinInfo* joinForFieldIndex( int index, int maxProviderIndex, int& indexOffset ) const;

/** Helper function to find out the maximum index of a field map
@return true in case of success, otherwise false (e.g. empty map)*/
static bool maximumIndex( const QgsFieldMap& fMap, int& index );
Expand All @@ -91,13 +98,6 @@ class CORE_EXPORT QgsVectorLayerJoinBuffer
@param attributeIndexOffset index offset to get from join layer attribute index to layer index*/
void addJoinedFeatureAttributes( QgsFeature& f, const QgsVectorJoinInfo& joinInfo, const QString& joinFieldName, const QVariant& joinValue,
const QgsAttributeList& attributes, int attributeIndexOffset );

/**Finds the vector join for a layer field index.
@param index this layers attribute index
@param maxProviderIndex maximum attribute index of the vectorlayer provider
@param indexOffset out: offset between layer index and original provider index
@return pointer to the join if the index belongs to a joined field, otherwise 0 (possibily provider field or added field)*/
const QgsVectorJoinInfo* joinForFieldIndex( int index, int maxProviderIndex, int& indexOffset ) const;
};

#endif // QGSVECTORLAYERJOINBUFFER_H
Expand Up @@ -10,8 +10,6 @@
#include "qgssymbolv2selectordialog.h"

#include "qgsvectorlayer.h"
#include "qgsvectordataprovider.h" // for uniqueValues

#include <QMenu>
#include <QMessageBox>
#include <QStandardItemModel>
Expand Down Expand Up @@ -245,7 +243,7 @@ void QgsCategorizedSymbolRendererV2Widget::addCategories()
QString attrName = cboCategorizedColumn->currentText();
int idx = mLayer->fieldNameIndex( attrName );
QList<QVariant> unique_vals;
mLayer->dataProvider()->uniqueValues( idx, unique_vals );
mLayer->uniqueValues( idx, unique_vals );

//DlgAddCategories dlg(mStyle, createDefaultSymbol(), unique_vals, this);
//if (!dlg.exec())
Expand Down

0 comments on commit 2c0e214

Please sign in to comment.