Skip to content

Commit a0ff6d5

Browse files
committed
Add expression to graduated renderer
1 parent 6cf3b9f commit a0ff6d5

5 files changed

+182
-84
lines changed

src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp

Lines changed: 41 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include "qgsvectorlayer.h"
2323
#include "qgslogger.h"
2424
#include "qgsvectordataprovider.h"
25-
25+
#include "qgsexpression.h"
2626
#include <QDomDocument>
2727
#include <QDomElement>
2828
#include <QSettings> // for legend
@@ -184,18 +184,22 @@ QgsSymbolV2* QgsGraduatedSymbolRendererV2::symbolForValue( double value )
184184
QgsSymbolV2* QgsGraduatedSymbolRendererV2::symbolForFeature( QgsFeature& feature )
185185
{
186186
const QgsAttributes& attrs = feature.attributes();
187+
QVariant value;
187188
if ( mAttrNum < 0 || mAttrNum >= attrs.count() )
188189
{
189-
QgsDebugMsg( "attribute required by renderer not found: " + mAttrName + "(index " + QString::number( mAttrNum ) + ")" );
190-
return NULL;
190+
value = mExpression->evaluate( &feature );
191+
}
192+
else
193+
{
194+
value = attrs[mAttrNum];
191195
}
192196

193197
// Null values should not be categorized
194-
if ( attrs[mAttrNum].isNull() )
198+
if ( value.isNull() )
195199
return NULL;
196200

197201
// find the right category
198-
QgsSymbolV2* symbol = symbolForValue( attrs[mAttrNum].toDouble() );
202+
QgsSymbolV2* symbol = symbolForValue( value.toDouble() );
199203
if ( symbol == NULL )
200204
return NULL;
201205

@@ -237,6 +241,12 @@ void QgsGraduatedSymbolRendererV2::startRender( QgsRenderContext& context, const
237241
// find out classification attribute index from name
238242
mAttrNum = vlayer ? vlayer->fieldNameIndex( mAttrName ) : -1;
239243

244+
if ( mAttrNum == -1 )
245+
{
246+
mExpression = new QgsExpression( mAttrName );
247+
mExpression->prepare( vlayer->pendingFields() );
248+
}
249+
240250
mRotationFieldIdx = ( mRotationField.isEmpty() ? -1 : vlayer->fieldNameIndex( mRotationField ) );
241251
mSizeScaleFieldIdx = ( mSizeScaleField.isEmpty() ? -1 : vlayer->fieldNameIndex( mSizeScaleField ) );
242252

@@ -279,7 +289,11 @@ void QgsGraduatedSymbolRendererV2::stopRender( QgsRenderContext& context )
279289
QList<QString> QgsGraduatedSymbolRendererV2::usedAttributes()
280290
{
281291
QSet<QString> attributes;
282-
attributes.insert( mAttrName );
292+
QgsExpression exp( mAttrName );
293+
foreach (QString attr, exp.referencedColumns() )
294+
{
295+
attributes << attr;
296+
}
283297
if ( !mRotationField.isEmpty() )
284298
{
285299
attributes.insert( mRotationField );
@@ -780,11 +794,29 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
780794
return NULL;
781795

782796
int attrNum = vlayer->fieldNameIndex( attrName );
797+
double minimum;
798+
double maximum;
799+
if ( attrNum == -1 )
800+
{
801+
QList<double> values;
802+
QgsFeatureIterator fit = vlayer->getFeatures();
803+
QgsFeature feature;
804+
QgsExpression expression( attrName );
805+
while ( fit.nextFeature( feature ) )
806+
{
807+
values << expression.evaluate( feature ).toDouble();
808+
}
809+
qSort( values );
810+
minimum = values.first();
811+
maximum = values.last();
812+
}
813+
else
814+
{
815+
minimum = vlayer->minimumValue( attrNum ).toDouble();
816+
maximum = vlayer->maximumValue( attrNum ).toDouble();
817+
}
783818

784-
double minimum = vlayer->minimumValue( attrNum ).toDouble();
785-
double maximum = vlayer->maximumValue( attrNum ).toDouble();
786819
QgsDebugMsg( QString( "min %1 // max %2" ).arg( minimum ).arg( maximum ) );
787-
788820
QList<double> breaks;
789821
QList<int> labels;
790822
if ( mode == EqualInterval )

src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include "qgssymbolv2.h"
1919
#include "qgsrendererv2.h"
20+
#include "qgsexpression.h"
2021

2122
class CORE_EXPORT QgsRendererRangeV2
2223
{
@@ -177,7 +178,7 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
177178
QString mRotationField;
178179
QString mSizeScaleField;
179180
QgsSymbolV2::ScaleMethod mScaleMethod;
180-
181+
QgsExpression* mExpression;
181182
//! attribute index (derived from attribute name in startRender)
182183
int mAttrNum;
183184
int mRotationFieldIdx, mSizeScaleFieldIdx;

src/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "qgsvectorlayer.h"
2323

2424
#include "qgssymbolv2selectordialog.h"
25+
#include "qgsexpressionbuilderdialog.h"
2526

2627
#include "qgsludialog.h"
2728

@@ -359,6 +360,7 @@ QgsGraduatedSymbolRendererV2Widget::QgsGraduatedSymbolRendererV2Widget( QgsVecto
359360
mGraduatedSymbol = QgsSymbolV2::defaultSymbol( mLayer->geometryType() );
360361

361362
connect( cboGraduatedColumn, SIGNAL( currentIndexChanged( int ) ), this, SLOT( graduatedColumnChanged() ) );
363+
connect( btnExpression, SIGNAL( clicked() ), this, SLOT( setExpression() ) );
362364
connect( viewGraduated, SIGNAL( doubleClicked( const QModelIndex & ) ), this, SLOT( rangesDoubleClicked( const QModelIndex & ) ) );
363365
connect( viewGraduated, SIGNAL( clicked( const QModelIndex & ) ), this, SLOT( rangesClicked( const QModelIndex & ) ) );
364366
connect( viewGraduated, SIGNAL( customContextMenuRequested( const QPoint& ) ), this, SLOT( contextMenuViewCategories( const QPoint& ) ) );
@@ -417,7 +419,12 @@ void QgsGraduatedSymbolRendererV2Widget::updateUiFromRenderer()
417419
disconnect( cboGraduatedColumn, SIGNAL( currentIndexChanged( int ) ), this, SLOT( graduatedColumnChanged() ) );
418420
QString attrName = mRenderer->classAttribute();
419421
int idx = cboGraduatedColumn->findText( attrName, Qt::MatchExactly );
420-
cboGraduatedColumn->setCurrentIndex( idx >= 0 ? idx : 0 );
422+
if ( idx == -1 )
423+
{
424+
cboGraduatedColumn->addItem( attrName );
425+
idx = cboGraduatedColumn->count() - 1;
426+
}
427+
cboGraduatedColumn->setCurrentIndex( idx );
421428
connect( cboGraduatedColumn, SIGNAL( currentIndexChanged( int ) ), this, SLOT( graduatedColumnChanged() ) );
422429

423430
// set source symbol
@@ -453,6 +460,22 @@ void QgsGraduatedSymbolRendererV2Widget::graduatedColumnChanged()
453460
}
454461

455462

463+
void QgsGraduatedSymbolRendererV2Widget::setExpression()
464+
{
465+
QgsExpressionBuilderDialog dlg( mLayer, cboGraduatedColumn->currentText(), this );
466+
dlg.setWindowTitle( "Set column expression" );
467+
if ( dlg.exec() )
468+
{
469+
QString expression = dlg.expressionText();
470+
if ( !expression.isEmpty() )
471+
{
472+
cboGraduatedColumn->addItem( expression );
473+
cboGraduatedColumn->setCurrentIndex( cboGraduatedColumn->count() - 1 );
474+
}
475+
}
476+
477+
}
478+
456479
void QgsGraduatedSymbolRendererV2Widget::classifyGraduated()
457480
{
458481
QString attrName = cboGraduatedColumn->currentText();

src/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class GUI_EXPORT QgsGraduatedSymbolRendererV2Widget : public QgsRendererV2Widget
8080
public slots:
8181
void changeGraduatedSymbol();
8282
void graduatedColumnChanged();
83+
void setExpression();
8384
void classifyGraduated();
8485
void reapplyColorRamp();
8586
void rangesDoubleClicked( const QModelIndex & idx );

0 commit comments

Comments
 (0)