[QGIS Commit] r15389 - in trunk/qgis: python/core src/app src/core
src/core/symbology-ng
svn_qgis at osgeo.org
svn_qgis at osgeo.org
Tue Mar 8 11:32:01 EST 2011
Author: mhugent
Date: 2011-03-08 08:32:01 -0800 (Tue, 08 Mar 2011)
New Revision: 15389
Modified:
trunk/qgis/python/core/qgsvectorlayer.sip
trunk/qgis/src/app/qgsgraduatedsymboldialog.cpp
trunk/qgis/src/core/qgsvectorlayer.cpp
trunk/qgis/src/core/qgsvectorlayer.h
trunk/qgis/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp
Log:
Fix graduated classifications for joined fields
Modified: trunk/qgis/python/core/qgsvectorlayer.sip
===================================================================
--- trunk/qgis/python/core/qgsvectorlayer.sip 2011-03-08 08:10:37 UTC (rev 15388)
+++ trunk/qgis/python/core/qgsvectorlayer.sip 2011-03-08 16:32:01 UTC (rev 15389)
@@ -598,6 +598,14 @@
@note: this method was added in version 1.7*/
void uniqueValues( int index, QList<QVariant>& uniqueValues /Out/, int limit );
+ /**Returns minimum value for an attribute column or invalid variant in case of error
+ @note added in 1.7*/
+ QVariant minimumValue( int index );
+
+ /**Returns maximum value for an attribute column or invalid variant in case of error
+ @note added in 1.7*/
+ QVariant maximumValue( int index );
+
public slots:
/** Select feature by its ID, optionally emit signal selectionChanged() */
Modified: trunk/qgis/src/app/qgsgraduatedsymboldialog.cpp
===================================================================
--- trunk/qgis/src/app/qgsgraduatedsymboldialog.cpp 2011-03-08 08:10:37 UTC (rev 15388)
+++ trunk/qgis/src/app/qgsgraduatedsymboldialog.cpp 2011-03-08 16:32:01 UTC (rev 15389)
@@ -265,7 +265,6 @@
{
mClassListWidget->clear();
QGis::GeometryType m_type = mVectorLayer->geometryType();
- QgsVectorDataProvider *provider = dynamic_cast<QgsVectorDataProvider *>( mVectorLayer->dataProvider() );
double minimum = 0;
double maximum = 0;
@@ -288,21 +287,17 @@
std::map < QString, int >::iterator iter = mFieldMap.find( fieldstring );
int field = iter->second;
-
- if ( provider )
+ if ( modeComboBox->currentText() == tr( "Equal Interval" ) ||
+ modeComboBox->currentText() == tr( "Quantiles" ) )
{
- if ( modeComboBox->currentText() == tr( "Equal Interval" ) ||
- modeComboBox->currentText() == tr( "Quantiles" ) )
- {
- minimum = provider->minimumValue( field ).toDouble();
- maximum = provider->maximumValue( field ).toDouble();
- }
- else //don't waste performance if mMode is QgsGraduatedSymbolDialog::EMPTY
- {
- minimum = 0;
- maximum = 0;
- }
+ minimum = mVectorLayer->minimumValue( field ).toDouble();
+ maximum = mVectorLayer->maximumValue( field ).toDouble();
}
+ else //don't waste performance if mMode is QgsGraduatedSymbolDialog::EMPTY
+ {
+ minimum = 0;
+ maximum = 0;
+ }
//todo: setup a data structure which holds the symbols
std::list<QgsSymbol*> symbolList;
@@ -500,30 +495,25 @@
{
if ( mVectorLayer )
{
- QgsVectorDataProvider* provider = mVectorLayer->dataProvider();
+ std::vector<double> attributeValues( mVectorLayer->featureCount() );
+ QgsAttributeList attList;
+ attList.push_back( attributeIndex );
+ QgsFeature currentFeature;
+ QgsAttributeMap currentAttributeMap;
+ double currentValue;
+ int index = 0;
- if ( provider )
+ mVectorLayer->select( attList, QgsRectangle(), false );
+ while ( mVectorLayer->nextFeature( currentFeature ) )
{
- std::vector<double> attributeValues( provider->featureCount() );
- QgsAttributeList attList;
- attList.push_back( attributeIndex );
- QgsFeature currentFeature;
- QgsAttributeMap currentAttributeMap;
- double currentValue;
- int index = 0;
-
- provider->select( attList, QgsRectangle(), false );
- while ( provider->nextFeature( currentFeature ) )
- {
- currentAttributeMap = currentFeature.attributeMap();
- currentValue = currentAttributeMap[attributeIndex].toDouble();
- attributeValues[index] = currentValue;
- ++index;
- }
-
- sort( attributeValues.begin(), attributeValues.end() );
- return calculateQuantiles( result, attributeValues, numQuantiles );
+ currentAttributeMap = currentFeature.attributeMap();
+ currentValue = currentAttributeMap[attributeIndex].toDouble();
+ attributeValues[index] = currentValue;
+ ++index;
}
+
+ sort( attributeValues.begin(), attributeValues.end() );
+ return calculateQuantiles( result, attributeValues, numQuantiles );
}
return 1;
}
Modified: trunk/qgis/src/core/qgsvectorlayer.cpp
===================================================================
--- trunk/qgis/src/core/qgsvectorlayer.cpp 2011-03-08 08:10:37 UTC (rev 15388)
+++ trunk/qgis/src/core/qgsvectorlayer.cpp 2011-03-08 16:32:01 UTC (rev 15389)
@@ -5003,6 +5003,114 @@
uniqueValues = val.values();
}
+QVariant QgsVectorLayer::minimumValue( int index )
+{
+ if ( !mDataProvider )
+ {
+ return QVariant();
+ }
+
+ int maxProviderIndex;
+ QgsVectorLayerJoinBuffer::maximumIndex( mDataProvider->fields(), maxProviderIndex );
+
+ if ( index <= maxProviderIndex && !mEditable ) //a provider field
+ {
+ return mDataProvider->minimumValue( index );
+ }
+ else // a joined field?
+ {
+ 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 )
+ {
+ return vl->minimumValue( index );
+ }
+ }
+ }
+
+ //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->minimumValue( index );
+ }
+
+ //we need to go through each feature
+ QgsAttributeList attList;
+ attList << index;
+
+ select( attList, QgsRectangle(), false, false );
+
+ QgsFeature f;
+ double minimumValue = std::numeric_limits<double>::max();
+ double currentValue = 0;
+ while ( nextFeature( f ) )
+ {
+ currentValue = f.attributeMap()[index].toDouble();
+ if ( currentValue < minimumValue )
+ {
+ minimumValue = currentValue;
+ }
+ }
+ return QVariant( minimumValue );
+}
+
+QVariant QgsVectorLayer::maximumValue( int index )
+{
+ if ( !mDataProvider )
+ {
+ return QVariant();
+ }
+
+ int maxProviderIndex;
+ QgsVectorLayerJoinBuffer::maximumIndex( mDataProvider->fields(), maxProviderIndex );
+
+ if ( index <= maxProviderIndex && !mEditable ) //a provider field
+ {
+ return mDataProvider->maximumValue( index );
+ }
+ else // a joined field?
+ {
+ 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 )
+ {
+ return vl->maximumValue( index );
+ }
+ }
+ }
+
+ //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->maximumValue( index );
+ }
+
+ //we need to go through each feature
+ QgsAttributeList attList;
+ attList << index;
+
+ select( attList, QgsRectangle(), false, false );
+
+ QgsFeature f;
+ double maximumValue = -std::numeric_limits<double>::max();
+ double currentValue = 0;
+ while ( nextFeature( f ) )
+ {
+ currentValue = f.attributeMap()[index].toDouble();
+ if ( currentValue > maximumValue )
+ {
+ maximumValue = currentValue;
+ }
+ }
+ return QVariant( maximumValue );
+}
+
void QgsVectorLayer::stopRendererV2( QgsRenderContext& rendererContext, QgsSingleSymbolRendererV2* selRenderer )
{
mRendererV2->stopRender( rendererContext );
Modified: trunk/qgis/src/core/qgsvectorlayer.h
===================================================================
--- trunk/qgis/src/core/qgsvectorlayer.h 2011-03-08 08:10:37 UTC (rev 15388)
+++ trunk/qgis/src/core/qgsvectorlayer.h 2011-03-08 16:32:01 UTC (rev 15389)
@@ -651,7 +651,14 @@
@note this method was added in version 1.7*/
void uniqueValues( int index, QList<QVariant> &uniqueValues, int limit = -1 );
+ /**Returns minimum value for an attribute column or invalid variant in case of error
+ @note added in 1.7*/
+ QVariant minimumValue( int index );
+ /**Returns maximum value for an attribute column or invalid variant in case of error
+ @note added in 1.7*/
+ QVariant maximumValue( int index );
+
public slots:
/** Select feature by its ID, optionally emit signal selectionChanged() */
void select( int featureId, bool emitSignal = true );
Modified: trunk/qgis/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp
===================================================================
--- trunk/qgis/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp 2011-03-08 08:10:37 UTC (rev 15388)
+++ trunk/qgis/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp 2011-03-08 16:32:01 UTC (rev 15389)
@@ -684,12 +684,11 @@
QgsSymbolV2* symbol,
QgsVectorColorRampV2* ramp )
{
- QgsVectorDataProvider* provider = vlayer->dataProvider();
int attrNum = vlayer->fieldNameIndex( attrName );
- double minimum = provider->minimumValue( attrNum ).toDouble();
- double maximum = provider->maximumValue( attrNum ).toDouble();
+ double minimum = vlayer->minimumValue( attrNum ).toDouble();
+ double maximum = vlayer->maximumValue( attrNum ).toDouble();
QgsDebugMsg( QString( "min %1 // max %2" ).arg( minimum ).arg( maximum ) );
QList<double> breaks;
@@ -709,8 +708,8 @@
QgsFeature f;
QgsAttributeList lst;
lst.append( attrNum );
- provider->select( lst, QgsRectangle(), false );
- while ( provider->nextFeature( f ) )
+ vlayer->select( lst, QgsRectangle(), false );
+ while ( vlayer->nextFeature( f ) )
values.append( f.attributeMap()[attrNum].toDouble() );
// calculate the breaks
if ( mode == Quantile )
More information about the QGIS-commit
mailing list