[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