Skip to content
Permalink
Browse files
Add expression to categorized renderer
  • Loading branch information
NathanW2 committed Sep 15, 2013
1 parent e049f84 commit 6cf3b9fa88f088484e4107b89e5691df1657fb0a
@@ -197,14 +197,18 @@ QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForValue( QVariant value )
QgsSymbolV2* QgsCategorizedSymbolRendererV2::symbolForFeature( QgsFeature& feature )
{
const QgsAttributes& attrs = feature.attributes();
QVariant value;
if ( mAttrNum < 0 || mAttrNum >= attrs.count() )
{
QgsDebugMsg( "attribute '" + mAttrName + "' (index " + QString::number( mAttrNum ) + ") required by renderer not found" );
return NULL;
value = mExpression->evaluate( &feature );
}
else
{
value = attrs[mAttrNum];
}

// find the right symbol for the category
QgsSymbolV2* symbol = symbolForValue( attrs[mAttrNum] );
QgsSymbolV2* symbol = symbolForValue( value );
if ( symbol == NULL )
{
// if no symbol found use default one
@@ -361,6 +365,11 @@ void QgsCategorizedSymbolRendererV2::startRender( QgsRenderContext& context, con

// find out classification attribute index from name
mAttrNum = vlayer ? vlayer->fieldNameIndex( mAttrName ) : -1;
if ( mAttrNum == -1 )
{
mExpression = new QgsExpression( mAttrName );
mExpression->prepare( vlayer->pendingFields() );
}

mRotationFieldIdx = ( mRotationField.isEmpty() ? -1 : vlayer->fieldNameIndex( mRotationField ) );
mSizeScaleFieldIdx = ( mSizeScaleField.isEmpty() ? -1 : vlayer->fieldNameIndex( mSizeScaleField ) );
@@ -401,7 +410,11 @@ void QgsCategorizedSymbolRendererV2::stopRender( QgsRenderContext& context )
QList<QString> QgsCategorizedSymbolRendererV2::usedAttributes()
{
QSet<QString> attributes;
attributes.insert( mAttrName );
QgsExpression exp( mAttrName );
foreach (QString attr, exp.referencedColumns() )
{
attributes << attr;
}
if ( !mRotationField.isEmpty() )
{
attributes.insert( mRotationField );
@@ -17,6 +17,7 @@

#include "qgssymbolv2.h"
#include "qgsrendererv2.h"
#include "qgsexpression.h"

#include <QHash>

@@ -155,6 +156,7 @@ class CORE_EXPORT QgsCategorizedSymbolRendererV2 : public QgsFeatureRendererV2
QString mRotationField;
QString mSizeScaleField;
QgsSymbolV2::ScaleMethod mScaleMethod;
QgsExpression* mExpression;

//! attribute index (derived from attribute name in startRender)
int mAttrNum;
@@ -23,10 +23,12 @@
#include "qgsstylev2.h"

#include "qgssymbolv2selectordialog.h"
#include "qgsexpressionbuilderdialog.h"

#include "qgsvectorlayer.h"

#include "qgsproject.h"
#include "qgsexpression.h"

#include <QMenu>
#include <QMessageBox>
@@ -387,6 +389,7 @@ QgsCategorizedSymbolRendererV2Widget::QgsCategorizedSymbolRendererV2Widget( QgsV
connect( btnDeleteAllCategories, SIGNAL( clicked() ), this, SLOT( deleteAllCategories() ) );
connect( btnAddCategory, SIGNAL( clicked() ), this, SLOT( addCategory() ) );

connect( btnExpression, SIGNAL( clicked() ), this, SLOT( setExpression() ) );
// update GUI from renderer
updateUiFromRenderer();

@@ -420,7 +423,12 @@ void QgsCategorizedSymbolRendererV2Widget::updateUiFromRenderer()
QString attrName = mRenderer->classAttribute();
mOldClassificationAttribute = attrName;
int idx = cboCategorizedColumn->findText( attrName, Qt::MatchExactly );
cboCategorizedColumn->setCurrentIndex( idx >= 0 ? idx : 0 );
if ( idx == -1 )
{
cboCategorizedColumn->addItem( attrName );
idx = cboCategorizedColumn->count() - 1;
}
cboCategorizedColumn->setCurrentIndex( idx );
connect( cboCategorizedColumn, SIGNAL( currentIndexChanged( int ) ), this, SLOT( categoryColumnChanged() ) );

// set source symbol
@@ -590,7 +598,25 @@ void QgsCategorizedSymbolRendererV2Widget::addCategories()
QString attrName = cboCategorizedColumn->currentText();
int idx = mLayer->fieldNameIndex( attrName );
QList<QVariant> unique_vals;
mLayer->uniqueValues( idx, unique_vals );
if ( idx == -1 )
{
// Lets assume it's an expression
QgsExpression* expression = new QgsExpression( attrName );
expression->prepare( mLayer->pendingFields() );
QgsFeatureIterator fit = mLayer->getFeatures();
QgsFeature feature;
while ( fit.nextFeature( feature ) )
{
QVariant value = expression->evaluate( feature ) ;
if ( unique_vals.contains( value ) )
continue;
unique_vals << value;
}
}
else
{
mLayer->uniqueValues( idx, unique_vals );
}

// ask to abort if too many classes
if ( unique_vals.size() >= 1000 )
@@ -733,6 +759,22 @@ void QgsCategorizedSymbolRendererV2Widget::deleteAllCategories()
mModel->removeAllRows();
}

void QgsCategorizedSymbolRendererV2Widget::setExpression()
{
QgsExpressionBuilderDialog dlg( mLayer, cboCategorizedColumn->currentText(), this );
dlg.setWindowTitle( "Set column expression" );
if ( dlg.exec() )
{
QString expression = dlg.expressionText();
if ( !expression.isEmpty() )
{
cboCategorizedColumn->addItem( expression );
cboCategorizedColumn->setCurrentIndex( cboCategorizedColumn->count() - 1 );
}
}

}

void QgsCategorizedSymbolRendererV2Widget::addCategory()
{
if ( !mModel ) return;
@@ -86,6 +86,7 @@ class GUI_EXPORT QgsCategorizedSymbolRendererV2Widget : public QgsRendererV2Widg
void addCategories();
void deleteCategories();
void deleteAllCategories();
void setExpression();

void rotationFieldChanged( QString fldName );
void sizeScaleFieldChanged( QString fldName );
@@ -31,6 +31,32 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>300</width>
<height>16777215</height>
</size>
</property>
<property name="editable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="btnExpression">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">
<normaloff>:/images/themes/default/mIconExpressionEditorOpen.svg</normaloff>:/images/themes/default/mIconExpressionEditorOpen.svg</iconset>
</property>
<property name="iconSize">
<size>
<width>24</width>
<height>16</height>
</size>
</property>
</widget>
</item>
<item>
@@ -207,6 +233,8 @@
<tabstop>btnDeleteAllCategories</tabstop>
<tabstop>btnJoinCategories</tabstop>
</tabstops>
<resources/>
<resources>
<include location="../../images/images.qrc"/>
</resources>
<connections/>
</ui>

0 comments on commit 6cf3b9f

Please sign in to comment.