From 84af60ad5600c1552fb4ae9b9e92ba552c9001a9 Mon Sep 17 00:00:00 2001 From: vmora Date: Mon, 30 Mar 2015 17:48:00 +0200 Subject: [PATCH] [feature] graduated with varying size The graduated symbol renderer now allows to use varying size instead of varying color. The classification remains the same an tabbed size/color in the gui allows the use to choose one type or the other. --- .../qgsgraduatedsymbolrendererv2.sip | 23 + .../qgsgraduatedsymbolrendererv2widget.sip | 1 + .../qgsgraduatedsymbolrendererv2.cpp | 93 +++- .../qgsgraduatedsymbolrendererv2.h | 29 ++ .../qgsgraduatedsymbolrendererv2widget.cpp | 137 +++++- .../qgsgraduatedsymbolrendererv2widget.h | 3 + src/ui/qgsgraduatedsymbolrendererv2widget.ui | 463 +++++++++++------- .../test_qgsgraduatedsymbolrendererv2.py | 12 + 8 files changed, 572 insertions(+), 189 deletions(-) diff --git a/python/core/symbology-ng/qgsgraduatedsymbolrendererv2.sip b/python/core/symbology-ng/qgsgraduatedsymbolrendererv2.sip index 233f835e641..767cf2520d2 100644 --- a/python/core/symbology-ng/qgsgraduatedsymbolrendererv2.sip +++ b/python/core/symbology-ng/qgsgraduatedsymbolrendererv2.sip @@ -212,6 +212,29 @@ class QgsGraduatedSymbolRendererV2 : QgsFeatureRendererV2 /** Update all the symbols but leave breaks and colors. */ void updateSymbols( QgsSymbolV2* sym /Transfer/ ); + //! set varying symbol size for classes + //! @note the classes must already be set so that symbols exist + //! @note added in 2.10 + void setSymbolSizes( double minSize, double maxSize ); + + //! return the min symbol size when graduated by size + //! @note added in 2.10 + double minSymbolSize() const; + + //! return the max symbol size when graduated by size + //! @note added in 2.10 + double maxSymbolSize() const; + + enum GraduatedMethod {GraduatedColor = 0, GraduatedSize = 1 }; + + //! return the method used for graduation (either size or color) + //! @note added in 2.10 + GraduatedMethod graduatedMethod() const; + + //! set the method used for graduation (either size or color) + //! @note added in 2.10 + void setGraduatedMethod( GraduatedMethod method ); + void setRotationField( QString fieldOrExpression ); QString rotationField() const; diff --git a/python/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.sip b/python/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.sip index bd4073b6095..86577ebfa5f 100644 --- a/python/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.sip +++ b/python/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.sip @@ -16,6 +16,7 @@ class QgsGraduatedSymbolRendererV2Widget : QgsRendererV2Widget void graduatedColumnChanged( QString field ); void classifyGraduated(); void reapplyColorRamp(); + void reapplySizes(); void rangesDoubleClicked( const QModelIndex & idx ); void rangesClicked( const QModelIndex & idx ); void changeCurrentValue( QStandardItem * item ); diff --git a/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp b/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp index ff013ae2be7..f1aeb2e144c 100644 --- a/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp +++ b/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp @@ -286,6 +286,7 @@ QgsGraduatedSymbolRendererV2::QgsGraduatedSymbolRendererV2( QString attrName, Qg , mMode( Custom ) , mInvertedColorRamp( false ) , mScaleMethod( DEFAULT_SCALE_METHOD ) + , mGraduatedMethod( GraduatedColor ) , mAttrNum( -1 ) , mCounting( false ) @@ -519,6 +520,7 @@ QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::clone() const r->setSizeScaleField( sizeScaleField() ); r->setScaleMethod( scaleMethod() ); r->setLabelFormat( labelFormat() ); + r->setGraduatedMethod( graduatedMethod() ); copyPaintEffect( r ); return r; } @@ -527,6 +529,7 @@ void QgsGraduatedSymbolRendererV2::toSld( QDomDocument& doc, QDomElement &elemen { QgsStringMap props; props[ "attribute" ] = mAttrName; + props[ "method" ] = graduatedMethodStr( mGraduatedMethod ); if ( mRotation.data() ) props[ "angle" ] = mRotation->expression(); if ( mSizeScale.data() ) @@ -962,6 +965,7 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer( QList QgsGraduatedSymbolRendererV2::getDataValues( QgsVectorLayer *vlayer ) { QList values; + QScopedPointer expression; int attrNum = vlayer->fieldNameIndex( mAttrName ); @@ -1022,7 +1026,7 @@ void QgsGraduatedSymbolRendererV2::updateClasses( QgsVectorLayer *vlayer, Mode m if ( values.isEmpty() ) return; - qSort( values ); + qSort( values ); // vmora: is wondering if O( n log(n) ) is really necessary here, min and max are O( n ) minimum = values.first(); maximum = values.last(); valuesLoaded = true; @@ -1146,6 +1150,16 @@ QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::create( QDomElement& element QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( attrName, ranges ); + QString attrMethod = element.attribute( "graduatedMethod" ); + if ( attrMethod.length() ) + { + if ( attrMethod == graduatedMethodStr( GraduatedColor ) ) + r->setGraduatedMethod( GraduatedColor ); + else if ( attrMethod == graduatedMethodStr( GraduatedSize ) ) + r->setGraduatedMethod( GraduatedSize ); + } + + // delete symbols if there are any more QgsSymbolLayerV2Utils::clearSymbolMap( symbolMap ); @@ -1214,6 +1228,7 @@ QDomElement QgsGraduatedSymbolRendererV2::save( QDomDocument& doc ) rendererElem.setAttribute( "type", "graduatedSymbol" ); rendererElem.setAttribute( "symbollevels", ( mUsingSymbolLevels ? "1" : "0" ) ); rendererElem.setAttribute( "attr", mAttrName ); + rendererElem.setAttribute( "graduatedMethod", graduatedMethodStr( mGraduatedMethod ) ); // ranges int i = 0; @@ -1348,6 +1363,52 @@ void QgsGraduatedSymbolRendererV2::setSourceColorRamp( QgsVectorColorRampV2* ram mSourceColorRamp.reset( ramp ); } +double QgsGraduatedSymbolRendererV2::minSymbolSize() const +{ + double min = DBL_MAX; + for ( int i = 0; i < mRanges.count(); i++ ) + { + double sz = 0; + if ( mRanges[i].symbol()->type() == QgsSymbolV2::Marker ) + sz = static_cast< QgsMarkerSymbolV2 * >( mRanges[i].symbol() )->size(); + else if ( mRanges[i].symbol()->type() == QgsSymbolV2::Line ) + sz = static_cast< QgsLineSymbolV2 * >( mRanges[i].symbol() )->width(); + min = qMin( sz, min ); + } + return min; +} + +double QgsGraduatedSymbolRendererV2::maxSymbolSize() const +{ + double max = DBL_MIN; + for ( int i = 0; i < mRanges.count(); i++ ) + { + double sz = 0; + if ( mRanges[i].symbol()->type() == QgsSymbolV2::Marker ) + sz = static_cast< QgsMarkerSymbolV2 * >( mRanges[i].symbol() )->size(); + else if ( mRanges[i].symbol()->type() == QgsSymbolV2::Line ) + sz = static_cast< QgsLineSymbolV2 * >( mRanges[i].symbol() )->width(); + max = qMax( sz, max ); + } + return max; +} + +void QgsGraduatedSymbolRendererV2::setSymbolSizes( double minSize, double maxSize ) +{ + for ( int i = 0; i < mRanges.count(); i++ ) + { + QScopedPointer symbol( mRanges[i].symbol() ? mRanges[i].symbol()->clone() : 0 ); + const double size = mRanges.count() > 1 + ? minSize + i * ( maxSize - minSize ) / ( mRanges.count() - 1 ) + : .5 * ( maxSize + minSize ); + if ( symbol->type() == QgsSymbolV2::Marker ) + static_cast< QgsMarkerSymbolV2 * >( symbol.data() )->setSize( size ); + if ( symbol->type() == QgsSymbolV2::Line ) + static_cast< QgsLineSymbolV2 * >( symbol.data() )->setWidth( size ); + updateRangeSymbol( i, symbol.take() ); + } +} + void QgsGraduatedSymbolRendererV2::updateColorRamp( QgsVectorColorRampV2 *ramp, bool inverted ) { int i = 0; @@ -1386,9 +1447,21 @@ void QgsGraduatedSymbolRendererV2::updateSymbols( QgsSymbolV2 *sym ) int i = 0; foreach ( QgsRendererRangeV2 range, mRanges ) { - QgsSymbolV2 *symbol = sym->clone(); - symbol->setColor( range.symbol()->color() ); - updateRangeSymbol( i, symbol ); + QScopedPointer symbol( sym->clone() ); + if ( mGraduatedMethod == GraduatedColor ) + { + symbol->setColor( range.symbol()->color() ); + } + else if ( mGraduatedMethod == GraduatedSize ) + { + if ( symbol->type() == QgsSymbolV2::Marker ) + static_cast( symbol.data() )->setSize( + static_cast( range.symbol() )->size() ); + else if ( symbol->type() == QgsSymbolV2::Line ) + static_cast( symbol.data() )->setWidth( + static_cast( range.symbol() )->width() ); + } + updateRangeSymbol( i, symbol.take() ); ++i; } setSourceSymbol( sym->clone() ); @@ -1602,3 +1675,15 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::convertFromRenderer( return r; } + +const char * QgsGraduatedSymbolRendererV2::graduatedMethodStr( GraduatedMethod method ) +{ + switch ( method ) + { + case GraduatedColor: return "GraduatedColor"; + case GraduatedSize: return "GraduatedSize"; + } + return ""; +} + + diff --git a/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h b/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h index e5f7ece20c2..d4971c53dfa 100644 --- a/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h +++ b/src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h @@ -113,6 +113,7 @@ class QgsVectorColorRampV2; class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2 { public: + QgsGraduatedSymbolRendererV2( QString attrName = QString(), QgsRangeList ranges = QgsRangeList() ); QgsGraduatedSymbolRendererV2( const QgsGraduatedSymbolRendererV2 & other ); @@ -243,6 +244,30 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2 /** Update all the symbols but leave breaks and colors. */ void updateSymbols( QgsSymbolV2* sym ); + //! set varying symbol size for classes + //! @note the classes must already be set so that symbols exist + //! @note added in 2.10 + void setSymbolSizes( double minSize, double maxSize ); + + //! return the min symbol size when graduated by size + //! @note added in 2.10 + double minSymbolSize() const; + + //! return the max symbol size when graduated by size + //! @note added in 2.10 + double maxSymbolSize() const; + + enum GraduatedMethod {GraduatedColor = 0, GraduatedSize = 1 }; + + //! return the method used for graduation (either size or color) + //! @note added in 2.10 + GraduatedMethod graduatedMethod() const { return mGraduatedMethod; } + + //! set the method used for graduation (either size or color) + //! @note added in 2.10 + void setGraduatedMethod( GraduatedMethod method ) { mGraduatedMethod = method; } + + void setRotationField( QString fieldOrExpression ) override; QString rotationField() const override; @@ -281,10 +306,12 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2 QScopedPointer mSourceColorRamp; bool mInvertedColorRamp; QgsRendererRangeV2LabelFormat mLabelFormat; + QScopedPointer mRotation; QScopedPointer mSizeScale; QgsSymbolV2::ScaleMethod mScaleMethod; QScopedPointer mExpression; + GraduatedMethod mGraduatedMethod; //! attribute index (derived from attribute name in startRender) int mAttrNum; bool mCounting; @@ -294,6 +321,8 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2 QgsSymbolV2* symbolForValue( double value ); + static const char * graduatedMethodStr( GraduatedMethod method ); + }; #endif // QGSGRADUATEDSYMBOLRENDERERV2_H diff --git a/src/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.cpp b/src/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.cpp index e0daef630fa..8e24542e44d 100644 --- a/src/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.cpp +++ b/src/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.cpp @@ -397,6 +397,9 @@ QgsGraduatedSymbolRendererV2Widget::QgsGraduatedSymbolRendererV2Widget( QgsVecto mExpressionWidget->setFilters( QgsFieldProxyModel::Numeric | QgsFieldProxyModel::Date ); mExpressionWidget->setLayer( mLayer ); + mSizeUnitWidget->setUnits( QgsSymbolV2::OutputUnitList() << QgsSymbolV2::MM << QgsSymbolV2::MapUnit ); + + cboGraduatedColorRamp->populate( mStyle ); spinPrecision->setMinimum( QgsRendererRangeV2LabelFormat::MinPrecision ); @@ -416,6 +419,20 @@ QgsGraduatedSymbolRendererV2Widget::QgsGraduatedSymbolRendererV2Widget( QgsVecto mGraduatedSymbol = QgsSymbolV2::defaultSymbol( mLayer->geometryType() ); + methodComboBox->addItem( "Color" ); + if ( mGraduatedSymbol->type() == QgsSymbolV2::Marker ) + { + methodComboBox->addItem( "Size" ); + minSizeSpinBox->setValue( 1 ); + maxSizeSpinBox->setValue( 8 ); + } + else if ( mGraduatedSymbol->type() == QgsSymbolV2::Line ) + { + methodComboBox->addItem( "Size" ); + minSizeSpinBox->setValue( .1 ); + maxSizeSpinBox->setValue( 2 ); + } + connect( mExpressionWidget, SIGNAL( fieldChanged( QString ) ), this, SLOT( graduatedColumnChanged( QString ) ) ); connect( viewGraduated, SIGNAL( doubleClicked( const QModelIndex & ) ), this, SLOT( rangesDoubleClicked( const QModelIndex & ) ) ); connect( viewGraduated, SIGNAL( clicked( const QModelIndex & ) ), this, SLOT( rangesClicked( const QModelIndex & ) ) ); @@ -428,6 +445,10 @@ QgsGraduatedSymbolRendererV2Widget::QgsGraduatedSymbolRendererV2Widget( QgsVecto connect( btnGraduatedAdd, SIGNAL( clicked() ), this, SLOT( addClass() ) ); connect( cbxLinkBoundaries, SIGNAL( toggled( bool ) ), this, SLOT( toggleBoundariesLink( bool ) ) ); + connect( mSizeUnitWidget, SIGNAL( changed() ), this, SLOT( on_mSizeUnitWidget_changed() ) ); + + connect( methodComboBox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( on_methodComboBox_currentChanged( int ) ) ); + connectUpdateHandlers(); // initialize from previously set renderer @@ -446,6 +467,16 @@ QgsGraduatedSymbolRendererV2Widget::QgsGraduatedSymbolRendererV2Widget( QgsVecto btnAdvanced->setMenu( advMenu ); } +void QgsGraduatedSymbolRendererV2Widget::on_mSizeUnitWidget_changed() +{ + if ( !mGraduatedSymbol ) return; + mGraduatedSymbol->setOutputUnit( mSizeUnitWidget->unit() ); + mGraduatedSymbol->setMapUnitScale( mSizeUnitWidget->getMapUnitScale() ); + updateGraduatedSymbolIcon(); + mRenderer->updateSymbols( mGraduatedSymbol ); + refreshSymbolView(); +} + QgsGraduatedSymbolRendererV2Widget::~QgsGraduatedSymbolRendererV2Widget() { delete mRenderer; @@ -467,7 +498,10 @@ void QgsGraduatedSymbolRendererV2Widget::connectUpdateHandlers() connect( cbxInvertedColorRamp, SIGNAL( toggled( bool ) ), this, SLOT( reapplyColorRamp() ) ); connect( spinPrecision, SIGNAL( valueChanged( int ) ), this, SLOT( labelFormatChanged() ) ); connect( cbxTrimTrailingZeroes, SIGNAL( toggled( bool ) ), this, SLOT( labelFormatChanged() ) ); - connect( txtFormat, SIGNAL( textChanged( QString ) ), this, SLOT( labelFormatChanged() ) ); + connect( txtLegendFormat, SIGNAL( textChanged( QString ) ), this, SLOT( labelFormatChanged() ) ); + connect( minSizeSpinBox, SIGNAL( valueChanged( double ) ), this, SLOT( reapplySizes() ) ); + connect( maxSizeSpinBox, SIGNAL( valueChanged( double ) ), this, SLOT( reapplySizes() ) ); + connect( mModel, SIGNAL( rowsMoved() ), this, SLOT( rowsMoved() ) ); connect( mModel, SIGNAL( dataChanged( QModelIndex, QModelIndex ) ), this, SLOT( modelDataChanged() ) ); @@ -483,7 +517,9 @@ void QgsGraduatedSymbolRendererV2Widget::disconnectUpdateHandlers() disconnect( cbxInvertedColorRamp, SIGNAL( toggled( bool ) ), this, SLOT( reapplyColorRamp() ) ); disconnect( spinPrecision, SIGNAL( valueChanged( int ) ), this, SLOT( labelFormatChanged() ) ); disconnect( cbxTrimTrailingZeroes, SIGNAL( toggled( bool ) ), this, SLOT( labelFormatChanged() ) ); - disconnect( txtFormat, SIGNAL( textChanged( QString ) ), this, SLOT( labelFormatChanged() ) ); + disconnect( txtLegendFormat, SIGNAL( textChanged( QString ) ), this, SLOT( labelFormatChanged() ) ); + disconnect( minSizeSpinBox, SIGNAL( valueChanged( double ) ), this, SLOT( reapplySizes() ) ); + disconnect( maxSizeSpinBox, SIGNAL( valueChanged( double ) ), this, SLOT( reapplySizes() ) ); disconnect( mModel, SIGNAL( rowsMoved() ), this, SLOT( rowsMoved() ) ); disconnect( mModel, SIGNAL( dataChanged( QModelIndex, QModelIndex ) ), this, SLOT( modelDataChanged() ) ); @@ -516,20 +552,40 @@ void QgsGraduatedSymbolRendererV2Widget::updateUiFromRenderer( bool updateCount updateGraduatedSymbolIcon(); } - // set source color ramp - if ( mRenderer->sourceColorRamp() ) + mModel->setRenderer( mRenderer ); + viewGraduated->setModel( mModel ); + + if ( mGraduatedSymbol ) { - cboGraduatedColorRamp->setSourceColorRamp( mRenderer->sourceColorRamp() ); + mSizeUnitWidget->blockSignals( true ); + mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() ); + mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() ); + mSizeUnitWidget->blockSignals( false ); + } + + // set source color ramp + if ( mRenderer->graduatedMethod() == QgsGraduatedSymbolRendererV2::GraduatedColor ) + { + methodComboBox->setCurrentIndex( 0 ); + if ( mRenderer->sourceColorRamp() ) + cboGraduatedColorRamp->setSourceColorRamp( mRenderer->sourceColorRamp() ); cbxInvertedColorRamp->setChecked( mRenderer->invertedColorRamp() ); } + else + { + methodComboBox->setCurrentIndex( 1 ); + if ( mRenderer->ranges().count() ) // avoid overiding default size with zeros + { + minSizeSpinBox->setValue( mRenderer->minSymbolSize() ); + maxSizeSpinBox->setValue( mRenderer->maxSymbolSize() ); + } + } QgsRendererRangeV2LabelFormat labelFormat = mRenderer->labelFormat(); - txtFormat->setText( labelFormat.format() ); + txtLegendFormat->setText( labelFormat.format() ); spinPrecision->setValue( labelFormat.precision() ); cbxTrimTrailingZeroes->setChecked( labelFormat.trimTrailingZeroes() ); - mModel->setRenderer( mRenderer ); - viewGraduated->setModel( mModel ); viewGraduated->resizeColumnToContents( 0 ); viewGraduated->resizeColumnToContents( 1 ); viewGraduated->resizeColumnToContents( 2 ); @@ -542,6 +598,32 @@ void QgsGraduatedSymbolRendererV2Widget::graduatedColumnChanged( QString field ) mRenderer->setClassAttribute( field ); } +void QgsGraduatedSymbolRendererV2Widget::on_methodComboBox_currentChanged( int idx ) +{ + stackedWidget->setCurrentIndex( idx ); + if ( idx == 0 ) + { + mRenderer->setGraduatedMethod( QgsGraduatedSymbolRendererV2::GraduatedColor ); + QgsVectorColorRampV2* ramp = cboGraduatedColorRamp->currentColorRamp(); + + if ( ramp == NULL ) + { + if ( cboGraduatedColorRamp->count() == 0 ) + QMessageBox::critical( this, tr( "Error" ), tr( "There are no available color ramps. You can add them in Style Manager." ) ); + else + QMessageBox::critical( this, tr( "Error" ), tr( "The selected color ramp is not available." ) ); + return; + } + mRenderer->setSourceColorRamp( ramp->clone() ); + reapplyColorRamp(); + } + else + { + mRenderer->setGraduatedMethod( QgsGraduatedSymbolRendererV2::GraduatedSize ); + reapplySizes(); + } +} + void QgsGraduatedSymbolRendererV2Widget::classifyGraduated() { QString attrName = mExpressionWidget->currentField(); @@ -582,10 +664,32 @@ void QgsGraduatedSymbolRendererV2Widget::classifyGraduated() mRenderer->setClassAttribute( attrName ); mRenderer->setMode( mode ); - mRenderer->setSourceColorRamp( ramp->clone() ); + + if ( methodComboBox->currentIndex() == 0 ) + { + QgsVectorColorRampV2* ramp = cboGraduatedColorRamp->currentColorRamp(); + + if ( ramp == NULL ) + { + if ( cboGraduatedColorRamp->count() == 0 ) + QMessageBox::critical( this, tr( "Error" ), tr( "There are no available color ramps. You can add them in Style Manager." ) ); + else + QMessageBox::critical( this, tr( "Error" ), tr( "The selected color ramp is not available." ) ); + return; + } + mRenderer->setSourceColorRamp( ramp->clone() ); + } + else + { + mRenderer->setSourceColorRamp( NULL ); + } QApplication::setOverrideCursor( Qt::WaitCursor ); mRenderer->updateClasses( mLayer, mode, nclasses ); + + if ( methodComboBox->currentIndex() == 1 ) + mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() ); + mRenderer->calculateLabelPrecision(); QApplication::restoreOverrideCursor(); // PrettyBreaks and StdDev calculation don't generate exact @@ -600,6 +704,14 @@ void QgsGraduatedSymbolRendererV2Widget::reapplyColorRamp() return; mRenderer->updateColorRamp( ramp, cbxInvertedColorRamp->isChecked() ); + mRenderer->updateSymbols( mGraduatedSymbol ); + refreshSymbolView(); +} + +void QgsGraduatedSymbolRendererV2Widget::reapplySizes() +{ + mRenderer->setSymbolSizes( minSizeSpinBox->value(), maxSizeSpinBox->value() ); + mRenderer->updateSymbols( mGraduatedSymbol ); refreshSymbolView(); } @@ -626,6 +738,11 @@ void QgsGraduatedSymbolRendererV2Widget::changeGraduatedSymbol() mGraduatedSymbol = newSymbol; + mSizeUnitWidget->blockSignals( true ); + mSizeUnitWidget->setUnit( mGraduatedSymbol->outputUnit() ); + mSizeUnitWidget->setMapUnitScale( mGraduatedSymbol->mapUnitScale() ); + mSizeUnitWidget->blockSignals( false ); + updateGraduatedSymbolIcon(); mRenderer->updateSymbols( mGraduatedSymbol ); refreshSymbolView(); @@ -857,7 +974,7 @@ void QgsGraduatedSymbolRendererV2Widget::scaleMethodChanged( QgsSymbolV2::ScaleM void QgsGraduatedSymbolRendererV2Widget::labelFormatChanged() { QgsRendererRangeV2LabelFormat labelFormat = QgsRendererRangeV2LabelFormat( - txtFormat->text(), + txtLegendFormat->text(), spinPrecision->value(), cbxTrimTrailingZeroes->isChecked() ); mRenderer->setLabelFormat( labelFormat, true ); diff --git a/src/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.h b/src/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.h index 9a0ba30e3ea..4d58dab19ef 100644 --- a/src/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.h +++ b/src/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.h @@ -86,6 +86,7 @@ class GUI_EXPORT QgsGraduatedSymbolRendererV2Widget : public QgsRendererV2Widget void graduatedColumnChanged( QString field ); void classifyGraduated(); void reapplyColorRamp(); + void reapplySizes(); void rangesDoubleClicked( const QModelIndex & idx ); void rangesClicked( const QModelIndex & idx ); void changeCurrentValue( QStandardItem * item ); @@ -108,6 +109,8 @@ class GUI_EXPORT QgsGraduatedSymbolRendererV2Widget : public QgsRendererV2Widget void rowsMoved(); void modelDataChanged(); + void on_mSizeUnitWidget_changed(); + void on_methodComboBox_currentChanged( int ); protected: void updateUiFromRenderer( bool updateCount = true ); diff --git a/src/ui/qgsgraduatedsymbolrendererv2widget.ui b/src/ui/qgsgraduatedsymbolrendererv2widget.ui index a9bc24a61f9..7b94e1bbcc5 100644 --- a/src/ui/qgsgraduatedsymbolrendererv2widget.ui +++ b/src/ui/qgsgraduatedsymbolrendererv2widget.ui @@ -6,20 +6,130 @@ 0 0 - 647 - 339 + 759 + 638 - - - 0 - - + + + + + Qt::CustomContextMenu + + + true + + + QAbstractItemView::InternalMove + + + QAbstractItemView::ExtendedSelection + + + false + + + false + + + true + + + + 6 + + + + Column + + + + + + + Precision + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + spinPrecision + + + + + + + 0 + 0 + + + + 1 + + + 999 + + + 5 + + + + + + + Mode + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + cboGraduatedMode + + + + + + + 0 + + + + + + 10 + 0 + + + + + 500 + 16777215 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + @@ -57,41 +167,17 @@ Negative rounds to powers of 10 - - - - Template for the legend text associated with each classification. -Use "%1" for the lower bound of the classification, and "%2" for the upper bound. - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Mode - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - cboGraduatedMode - - - - + - Color ramp + Symbol - cboGraduatedColorRamp + btnChangeGraduatedSymbol - + @@ -120,118 +206,21 @@ Use "%1" for the lower bound of the classification, and "%2" - - - - Symbol - - - btnChangeGraduatedSymbol - - - - - - - - 1 - 0 - - - - Change... - - - - - - - - 0 - 0 - - - - 1 - - - 999 - - - 5 - - - - - - - Classes - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - spinGraduatedClasses - - - - - + + - - - - - - Invert + + + Template for the legend text associated with each classification. +Use "%1" for the lower bound of the classification, and "%2" for the upper bound. + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - Column - - - - - - - 0 - - - - - - 0 - 0 - - - - - 500 - 16777215 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - @@ -241,51 +230,49 @@ Use "%1" for the lower bound of the classification, and "%2" Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - txtFormat + txtLegendFormat + + + + + + + + 1 + 0 + + + + Change... - + - Precision + Classes Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - spinPrecision + spinGraduatedClasses + + + + Method + + + + + + - - - - Qt::CustomContextMenu - - - true - - - QAbstractItemView::InternalMove - - - QAbstractItemView::ExtendedSelection - - - false - - - false - - - true - - - - + @@ -347,6 +334,123 @@ Use "%1" for the lower bound of the classification, and "%2" + + + + + 0 + 0 + + + + + 16777215 + 50 + + + + 0 + + + + + + + Invert + + + + + + + Color ramp + + + cboGraduatedColorRamp + + + + + + + + + + Qt::Horizontal + + + + 208 + 20 + + + + + + + + + + + + 1.000000000000000 + + + + + + + 10.000000000000000 + + + + + + + + 14 + 0 + + + + Qt::StrongFocus + + + + + + + to + + + + + + + Size from + + + cboGraduatedColorRamp + + + + + + + Qt::Horizontal + + + + 190 + 20 + + + + + + + + @@ -361,16 +465,22 @@ Use "%1" for the lower bound of the classification, and "%2"
qgsfieldexpressionwidget.h
1 + + QgsUnitSelectionWidget + QWidget +
qgsunitselectionwidget.h
+ 1 +
+ cboGraduatedMode btnChangeGraduatedSymbol + spinPrecision + cbxTrimTrailingZeroes + txtLegendFormat spinGraduatedClasses cboGraduatedColorRamp cbxInvertedColorRamp - cboGraduatedMode - txtFormat - spinPrecision - cbxTrimTrailingZeroes viewGraduated btnGraduatedClassify btnGraduatedAdd @@ -378,6 +488,9 @@ Use "%1" for the lower bound of the classification, and "%2" btnDeleteAllClasses cbxLinkBoundaries btnAdvanced + mSizeUnitWidget + minSizeSpinBox + maxSizeSpinBox diff --git a/tests/src/python/test_qgsgraduatedsymbolrendererv2.py b/tests/src/python/test_qgsgraduatedsymbolrendererv2.py index 2828f6d9015..42b7fa90c76 100644 --- a/tests/src/python/test_qgsgraduatedsymbolrendererv2.py +++ b/tests/src/python/test_qgsgraduatedsymbolrendererv2.py @@ -334,6 +334,18 @@ class TestQgsGraduatedSymbolRendererV2(TestCase): renderer.setScaleMethod(sm) self.assertEqual(str(sm),str(renderer.scaleMethod()), "Get/set renderer scale method") + # test for classificatio with varying size + renderer.setGraduatedMethod(QgsGraduatedSymbolRendererV2.GraduatedSize) + renderer.setSourceColorRamp(None) + renderer.addClassLowerUpper(0, 2) + renderer.addClassLowerUpper(2, 4) + renderer.addClassLowerUpper(4, 6) + renderer.setSymbolSizes(2,13) + self.assertEqual(renderer.maxSymbolSize(), 13) + self.assertEqual(renderer.minSymbolSize(), 2) + refSizes = [2, (13+2)*.5, 13] + for idx, symbol in enumerate(renderer.symbols()): + self.assertEqual(symbol.size(), refSizes[idx])