Skip to content

Commit 3717e57

Browse files
author
mhugent
committed
Fix graduated classifications for joined fields
git-svn-id: http://svn.osgeo.org/qgis/trunk@15389 c8812cc2-4d05-0410-92ff-de0c093fc19c
1 parent caa0cae commit 3717e57

File tree

5 files changed

+153
-41
lines changed

5 files changed

+153
-41
lines changed

python/core/qgsvectorlayer.sip

+8
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,14 @@ public:
598598
@note: this method was added in version 1.7*/
599599
void uniqueValues( int index, QList<QVariant>& uniqueValues /Out/, int limit );
600600

601+
/**Returns minimum value for an attribute column or invalid variant in case of error
602+
@note added in 1.7*/
603+
QVariant minimumValue( int index );
604+
605+
/**Returns maximum value for an attribute column or invalid variant in case of error
606+
@note added in 1.7*/
607+
QVariant maximumValue( int index );
608+
601609
public slots:
602610

603611
/** Select feature by its ID, optionally emit signal selectionChanged() */

src/app/qgsgraduatedsymboldialog.cpp

+26-36
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,6 @@ void QgsGraduatedSymbolDialog::adjustClassification()
265265
{
266266
mClassListWidget->clear();
267267
QGis::GeometryType m_type = mVectorLayer->geometryType();
268-
QgsVectorDataProvider *provider = dynamic_cast<QgsVectorDataProvider *>( mVectorLayer->dataProvider() );
269268
double minimum = 0;
270269
double maximum = 0;
271270

@@ -288,20 +287,16 @@ void QgsGraduatedSymbolDialog::adjustClassification()
288287
std::map < QString, int >::iterator iter = mFieldMap.find( fieldstring );
289288
int field = iter->second;
290289

291-
292-
if ( provider )
290+
if ( modeComboBox->currentText() == tr( "Equal Interval" ) ||
291+
modeComboBox->currentText() == tr( "Quantiles" ) )
293292
{
294-
if ( modeComboBox->currentText() == tr( "Equal Interval" ) ||
295-
modeComboBox->currentText() == tr( "Quantiles" ) )
296-
{
297-
minimum = provider->minimumValue( field ).toDouble();
298-
maximum = provider->maximumValue( field ).toDouble();
299-
}
300-
else //don't waste performance if mMode is QgsGraduatedSymbolDialog::EMPTY
301-
{
302-
minimum = 0;
303-
maximum = 0;
304-
}
293+
minimum = mVectorLayer->minimumValue( field ).toDouble();
294+
maximum = mVectorLayer->maximumValue( field ).toDouble();
295+
}
296+
else //don't waste performance if mMode is QgsGraduatedSymbolDialog::EMPTY
297+
{
298+
minimum = 0;
299+
maximum = 0;
305300
}
306301

307302
//todo: setup a data structure which holds the symbols
@@ -500,30 +495,25 @@ int QgsGraduatedSymbolDialog::quantilesFromVectorLayer( std::list<double>& resul
500495
{
501496
if ( mVectorLayer )
502497
{
503-
QgsVectorDataProvider* provider = mVectorLayer->dataProvider();
504-
505-
if ( provider )
498+
std::vector<double> attributeValues( mVectorLayer->featureCount() );
499+
QgsAttributeList attList;
500+
attList.push_back( attributeIndex );
501+
QgsFeature currentFeature;
502+
QgsAttributeMap currentAttributeMap;
503+
double currentValue;
504+
int index = 0;
505+
506+
mVectorLayer->select( attList, QgsRectangle(), false );
507+
while ( mVectorLayer->nextFeature( currentFeature ) )
506508
{
507-
std::vector<double> attributeValues( provider->featureCount() );
508-
QgsAttributeList attList;
509-
attList.push_back( attributeIndex );
510-
QgsFeature currentFeature;
511-
QgsAttributeMap currentAttributeMap;
512-
double currentValue;
513-
int index = 0;
514-
515-
provider->select( attList, QgsRectangle(), false );
516-
while ( provider->nextFeature( currentFeature ) )
517-
{
518-
currentAttributeMap = currentFeature.attributeMap();
519-
currentValue = currentAttributeMap[attributeIndex].toDouble();
520-
attributeValues[index] = currentValue;
521-
++index;
522-
}
523-
524-
sort( attributeValues.begin(), attributeValues.end() );
525-
return calculateQuantiles( result, attributeValues, numQuantiles );
509+
currentAttributeMap = currentFeature.attributeMap();
510+
currentValue = currentAttributeMap[attributeIndex].toDouble();
511+
attributeValues[index] = currentValue;
512+
++index;
526513
}
514+
515+
sort( attributeValues.begin(), attributeValues.end() );
516+
return calculateQuantiles( result, attributeValues, numQuantiles );
527517
}
528518
return 1;
529519
}

src/core/qgsvectorlayer.cpp

+108
Original file line numberDiff line numberDiff line change
@@ -5003,6 +5003,114 @@ void QgsVectorLayer::uniqueValues( int index, QList<QVariant> &uniqueValues, int
50035003
uniqueValues = val.values();
50045004
}
50055005

5006+
QVariant QgsVectorLayer::minimumValue( int index )
5007+
{
5008+
if ( !mDataProvider )
5009+
{
5010+
return QVariant();
5011+
}
5012+
5013+
int maxProviderIndex;
5014+
QgsVectorLayerJoinBuffer::maximumIndex( mDataProvider->fields(), maxProviderIndex );
5015+
5016+
if ( index <= maxProviderIndex && !mEditable ) //a provider field
5017+
{
5018+
return mDataProvider->minimumValue( index );
5019+
}
5020+
else // a joined field?
5021+
{
5022+
int indexOffset; //offset between layer index and joined provider index
5023+
const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, maxProviderIndex, indexOffset );
5024+
if ( join )
5025+
{
5026+
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( join->joinLayerId ) );
5027+
if ( vl )
5028+
{
5029+
return vl->minimumValue( index );
5030+
}
5031+
}
5032+
}
5033+
5034+
//the layer is editable, but in certain cases it can still be avoided going through all features
5035+
if ( mDeletedFeatureIds.size() < 1 && mAddedFeatures.size() < 1 && !mDeletedAttributeIds.contains( index ) && mChangedAttributeValues.size() < 1 )
5036+
{
5037+
return mDataProvider->minimumValue( index );
5038+
}
5039+
5040+
//we need to go through each feature
5041+
QgsAttributeList attList;
5042+
attList << index;
5043+
5044+
select( attList, QgsRectangle(), false, false );
5045+
5046+
QgsFeature f;
5047+
double minimumValue = std::numeric_limits<double>::max();
5048+
double currentValue = 0;
5049+
while ( nextFeature( f ) )
5050+
{
5051+
currentValue = f.attributeMap()[index].toDouble();
5052+
if ( currentValue < minimumValue )
5053+
{
5054+
minimumValue = currentValue;
5055+
}
5056+
}
5057+
return QVariant( minimumValue );
5058+
}
5059+
5060+
QVariant QgsVectorLayer::maximumValue( int index )
5061+
{
5062+
if ( !mDataProvider )
5063+
{
5064+
return QVariant();
5065+
}
5066+
5067+
int maxProviderIndex;
5068+
QgsVectorLayerJoinBuffer::maximumIndex( mDataProvider->fields(), maxProviderIndex );
5069+
5070+
if ( index <= maxProviderIndex && !mEditable ) //a provider field
5071+
{
5072+
return mDataProvider->maximumValue( index );
5073+
}
5074+
else // a joined field?
5075+
{
5076+
int indexOffset; //offset between layer index and joined provider index
5077+
const QgsVectorJoinInfo* join = mJoinBuffer->joinForFieldIndex( index, maxProviderIndex, indexOffset );
5078+
if ( join )
5079+
{
5080+
QgsVectorLayer* vl = dynamic_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( join->joinLayerId ) );
5081+
if ( vl )
5082+
{
5083+
return vl->maximumValue( index );
5084+
}
5085+
}
5086+
}
5087+
5088+
//the layer is editable, but in certain cases it can still be avoided going through all features
5089+
if ( mDeletedFeatureIds.size() < 1 && mAddedFeatures.size() < 1 && !mDeletedAttributeIds.contains( index ) && mChangedAttributeValues.size() < 1 )
5090+
{
5091+
return mDataProvider->maximumValue( index );
5092+
}
5093+
5094+
//we need to go through each feature
5095+
QgsAttributeList attList;
5096+
attList << index;
5097+
5098+
select( attList, QgsRectangle(), false, false );
5099+
5100+
QgsFeature f;
5101+
double maximumValue = -std::numeric_limits<double>::max();
5102+
double currentValue = 0;
5103+
while ( nextFeature( f ) )
5104+
{
5105+
currentValue = f.attributeMap()[index].toDouble();
5106+
if ( currentValue > maximumValue )
5107+
{
5108+
maximumValue = currentValue;
5109+
}
5110+
}
5111+
return QVariant( maximumValue );
5112+
}
5113+
50065114
void QgsVectorLayer::stopRendererV2( QgsRenderContext& rendererContext, QgsSingleSymbolRendererV2* selRenderer )
50075115
{
50085116
mRendererV2->stopRender( rendererContext );

src/core/qgsvectorlayer.h

+7
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,13 @@ class CORE_EXPORT QgsVectorLayer : public QgsMapLayer
651651
@note this method was added in version 1.7*/
652652
void uniqueValues( int index, QList<QVariant> &uniqueValues, int limit = -1 );
653653

654+
/**Returns minimum value for an attribute column or invalid variant in case of error
655+
@note added in 1.7*/
656+
QVariant minimumValue( int index );
657+
658+
/**Returns maximum value for an attribute column or invalid variant in case of error
659+
@note added in 1.7*/
660+
QVariant maximumValue( int index );
654661

655662
public slots:
656663
/** Select feature by its ID, optionally emit signal selectionChanged() */

src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp

+4-5
Original file line numberDiff line numberDiff line change
@@ -684,12 +684,11 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
684684
QgsSymbolV2* symbol,
685685
QgsVectorColorRampV2* ramp )
686686
{
687-
QgsVectorDataProvider* provider = vlayer->dataProvider();
688687

689688
int attrNum = vlayer->fieldNameIndex( attrName );
690689

691-
double minimum = provider->minimumValue( attrNum ).toDouble();
692-
double maximum = provider->maximumValue( attrNum ).toDouble();
690+
double minimum = vlayer->minimumValue( attrNum ).toDouble();
691+
double maximum = vlayer->maximumValue( attrNum ).toDouble();
693692
QgsDebugMsg( QString( "min %1 // max %2" ).arg( minimum ).arg( maximum ) );
694693

695694
QList<double> breaks;
@@ -709,8 +708,8 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
709708
QgsFeature f;
710709
QgsAttributeList lst;
711710
lst.append( attrNum );
712-
provider->select( lst, QgsRectangle(), false );
713-
while ( provider->nextFeature( f ) )
711+
vlayer->select( lst, QgsRectangle(), false );
712+
while ( vlayer->nextFeature( f ) )
714713
values.append( f.attributeMap()[attrNum].toDouble() );
715714
// calculate the breaks
716715
if ( mode == Quantile )

0 commit comments

Comments
 (0)