|
22 | 22 | #include "qgsvectorlayer.h"
|
23 | 23 | #include "qgslogger.h"
|
24 | 24 | #include "qgsvectordataprovider.h"
|
25 |
| - |
| 25 | +#include "qgsexpression.h" |
26 | 26 | #include <QDomDocument>
|
27 | 27 | #include <QDomElement>
|
28 | 28 | #include <QSettings> // for legend
|
@@ -184,18 +184,22 @@ QgsSymbolV2* QgsGraduatedSymbolRendererV2::symbolForValue( double value )
|
184 | 184 | QgsSymbolV2* QgsGraduatedSymbolRendererV2::symbolForFeature( QgsFeature& feature )
|
185 | 185 | {
|
186 | 186 | const QgsAttributes& attrs = feature.attributes();
|
| 187 | + QVariant value; |
187 | 188 | if ( mAttrNum < 0 || mAttrNum >= attrs.count() )
|
188 | 189 | {
|
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]; |
191 | 195 | }
|
192 | 196 |
|
193 | 197 | // Null values should not be categorized
|
194 |
| - if ( attrs[mAttrNum].isNull() ) |
| 198 | + if ( value.isNull() ) |
195 | 199 | return NULL;
|
196 | 200 |
|
197 | 201 | // find the right category
|
198 |
| - QgsSymbolV2* symbol = symbolForValue( attrs[mAttrNum].toDouble() ); |
| 202 | + QgsSymbolV2* symbol = symbolForValue( value.toDouble() ); |
199 | 203 | if ( symbol == NULL )
|
200 | 204 | return NULL;
|
201 | 205 |
|
@@ -237,6 +241,12 @@ void QgsGraduatedSymbolRendererV2::startRender( QgsRenderContext& context, const
|
237 | 241 | // find out classification attribute index from name
|
238 | 242 | mAttrNum = vlayer ? vlayer->fieldNameIndex( mAttrName ) : -1;
|
239 | 243 |
|
| 244 | + if ( mAttrNum == -1 ) |
| 245 | + { |
| 246 | + mExpression = new QgsExpression( mAttrName ); |
| 247 | + mExpression->prepare( vlayer->pendingFields() ); |
| 248 | + } |
| 249 | + |
240 | 250 | mRotationFieldIdx = ( mRotationField.isEmpty() ? -1 : vlayer->fieldNameIndex( mRotationField ) );
|
241 | 251 | mSizeScaleFieldIdx = ( mSizeScaleField.isEmpty() ? -1 : vlayer->fieldNameIndex( mSizeScaleField ) );
|
242 | 252 |
|
@@ -279,7 +289,11 @@ void QgsGraduatedSymbolRendererV2::stopRender( QgsRenderContext& context )
|
279 | 289 | QList<QString> QgsGraduatedSymbolRendererV2::usedAttributes()
|
280 | 290 | {
|
281 | 291 | QSet<QString> attributes;
|
282 |
| - attributes.insert( mAttrName ); |
| 292 | + QgsExpression exp( mAttrName ); |
| 293 | + foreach (QString attr, exp.referencedColumns() ) |
| 294 | + { |
| 295 | + attributes << attr; |
| 296 | + } |
283 | 297 | if ( !mRotationField.isEmpty() )
|
284 | 298 | {
|
285 | 299 | attributes.insert( mRotationField );
|
@@ -780,11 +794,29 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
|
780 | 794 | return NULL;
|
781 | 795 |
|
782 | 796 | 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 | + } |
783 | 818 |
|
784 |
| - double minimum = vlayer->minimumValue( attrNum ).toDouble(); |
785 |
| - double maximum = vlayer->maximumValue( attrNum ).toDouble(); |
786 | 819 | QgsDebugMsg( QString( "min %1 // max %2" ).arg( minimum ).arg( maximum ) );
|
787 |
| - |
788 | 820 | QList<double> breaks;
|
789 | 821 | QList<int> labels;
|
790 | 822 | if ( mode == EqualInterval )
|
|
0 commit comments