Skip to content

Commit

Permalink
[feature] graduated with varying size
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
vmora committed Apr 10, 2015
1 parent c3321e5 commit 84af60a
Show file tree
Hide file tree
Showing 8 changed files with 564 additions and 181 deletions.
23 changes: 23 additions & 0 deletions python/core/symbology-ng/qgsgraduatedsymbolrendererv2.sip
Expand Up @@ -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;

Expand Down
Expand Up @@ -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 );
Expand Down
93 changes: 89 additions & 4 deletions src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp
Expand Up @@ -286,6 +286,7 @@ QgsGraduatedSymbolRendererV2::QgsGraduatedSymbolRendererV2( QString attrName, Qg
, mMode( Custom )
, mInvertedColorRamp( false )
, mScaleMethod( DEFAULT_SCALE_METHOD )
, mGraduatedMethod( GraduatedColor )
, mAttrNum( -1 )
, mCounting( false )

Expand Down Expand Up @@ -519,6 +520,7 @@ QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::clone() const
r->setSizeScaleField( sizeScaleField() );
r->setScaleMethod( scaleMethod() );
r->setLabelFormat( labelFormat() );
r->setGraduatedMethod( graduatedMethod() );
copyPaintEffect( r );
return r;
}
Expand All @@ -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() )
Expand Down Expand Up @@ -962,6 +965,7 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
QList<double> QgsGraduatedSymbolRendererV2::getDataValues( QgsVectorLayer *vlayer )
{
QList<double> values;

QScopedPointer<QgsExpression> expression;
int attrNum = vlayer->fieldNameIndex( mAttrName );

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 );

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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<QgsSymbolV2> 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;
Expand Down Expand Up @@ -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<QgsSymbolV2> symbol( sym->clone() );
if ( mGraduatedMethod == GraduatedColor )
{
symbol->setColor( range.symbol()->color() );
}
else if ( mGraduatedMethod == GraduatedSize )
{
if ( symbol->type() == QgsSymbolV2::Marker )
static_cast<QgsMarkerSymbolV2 *>( symbol.data() )->setSize(
static_cast<QgsMarkerSymbolV2 *>( range.symbol() )->size() );
else if ( symbol->type() == QgsSymbolV2::Line )
static_cast<QgsLineSymbolV2 *>( symbol.data() )->setWidth(
static_cast<QgsLineSymbolV2 *>( range.symbol() )->width() );
}
updateRangeSymbol( i, symbol.take() );
++i;
}
setSourceSymbol( sym->clone() );
Expand Down Expand Up @@ -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 "";
}


29 changes: 29 additions & 0 deletions src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h
Expand Up @@ -113,6 +113,7 @@ class QgsVectorColorRampV2;
class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
{
public:

QgsGraduatedSymbolRendererV2( QString attrName = QString(), QgsRangeList ranges = QgsRangeList() );
QgsGraduatedSymbolRendererV2( const QgsGraduatedSymbolRendererV2 & other );

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -281,10 +306,12 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
QScopedPointer<QgsVectorColorRampV2> mSourceColorRamp;
bool mInvertedColorRamp;
QgsRendererRangeV2LabelFormat mLabelFormat;

QScopedPointer<QgsExpression> mRotation;
QScopedPointer<QgsExpression> mSizeScale;
QgsSymbolV2::ScaleMethod mScaleMethod;
QScopedPointer<QgsExpression> mExpression;
GraduatedMethod mGraduatedMethod;
//! attribute index (derived from attribute name in startRender)
int mAttrNum;
bool mCounting;
Expand All @@ -294,6 +321,8 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2

QgsSymbolV2* symbolForValue( double value );

static const char * graduatedMethodStr( GraduatedMethod method );

};

#endif // QGSGRADUATEDSYMBOLRENDERERV2_H

0 comments on commit 84af60a

Please sign in to comment.