Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Merge pull request #1974 from vmora/graduated_by_size
[feature] graduated with varying size
  • Loading branch information
nyalldawson committed Apr 11, 2015
2 parents 04324fd + 84af60a commit 28b5217
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 28b5217

Please sign in to comment.