Skip to content

Commit 28b5217

Browse files
committed
Merge pull request #1974 from vmora/graduated_by_size
[feature] graduated with varying size
2 parents 04324fd + 84af60a commit 28b5217

8 files changed

+564
-181
lines changed

python/core/symbology-ng/qgsgraduatedsymbolrendererv2.sip

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,29 @@ class QgsGraduatedSymbolRendererV2 : QgsFeatureRendererV2
212212
/** Update all the symbols but leave breaks and colors. */
213213
void updateSymbols( QgsSymbolV2* sym /Transfer/ );
214214

215+
//! set varying symbol size for classes
216+
//! @note the classes must already be set so that symbols exist
217+
//! @note added in 2.10
218+
void setSymbolSizes( double minSize, double maxSize );
219+
220+
//! return the min symbol size when graduated by size
221+
//! @note added in 2.10
222+
double minSymbolSize() const;
223+
224+
//! return the max symbol size when graduated by size
225+
//! @note added in 2.10
226+
double maxSymbolSize() const;
227+
228+
enum GraduatedMethod {GraduatedColor = 0, GraduatedSize = 1 };
229+
230+
//! return the method used for graduation (either size or color)
231+
//! @note added in 2.10
232+
GraduatedMethod graduatedMethod() const;
233+
234+
//! set the method used for graduation (either size or color)
235+
//! @note added in 2.10
236+
void setGraduatedMethod( GraduatedMethod method );
237+
215238
void setRotationField( QString fieldOrExpression );
216239
QString rotationField() const;
217240

python/gui/symbology-ng/qgsgraduatedsymbolrendererv2widget.sip

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class QgsGraduatedSymbolRendererV2Widget : QgsRendererV2Widget
1616
void graduatedColumnChanged( QString field );
1717
void classifyGraduated();
1818
void reapplyColorRamp();
19+
void reapplySizes();
1920
void rangesDoubleClicked( const QModelIndex & idx );
2021
void rangesClicked( const QModelIndex & idx );
2122
void changeCurrentValue( QStandardItem * item );

src/core/symbology-ng/qgsgraduatedsymbolrendererv2.cpp

Lines changed: 89 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ QgsGraduatedSymbolRendererV2::QgsGraduatedSymbolRendererV2( QString attrName, Qg
286286
, mMode( Custom )
287287
, mInvertedColorRamp( false )
288288
, mScaleMethod( DEFAULT_SCALE_METHOD )
289+
, mGraduatedMethod( GraduatedColor )
289290
, mAttrNum( -1 )
290291
, mCounting( false )
291292

@@ -519,6 +520,7 @@ QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::clone() const
519520
r->setSizeScaleField( sizeScaleField() );
520521
r->setScaleMethod( scaleMethod() );
521522
r->setLabelFormat( labelFormat() );
523+
r->setGraduatedMethod( graduatedMethod() );
522524
copyPaintEffect( r );
523525
return r;
524526
}
@@ -527,6 +529,7 @@ void QgsGraduatedSymbolRendererV2::toSld( QDomDocument& doc, QDomElement &elemen
527529
{
528530
QgsStringMap props;
529531
props[ "attribute" ] = mAttrName;
532+
props[ "method" ] = graduatedMethodStr( mGraduatedMethod );
530533
if ( mRotation.data() )
531534
props[ "angle" ] = mRotation->expression();
532535
if ( mSizeScale.data() )
@@ -962,6 +965,7 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::createRenderer(
962965
QList<double> QgsGraduatedSymbolRendererV2::getDataValues( QgsVectorLayer *vlayer )
963966
{
964967
QList<double> values;
968+
965969
QScopedPointer<QgsExpression> expression;
966970
int attrNum = vlayer->fieldNameIndex( mAttrName );
967971

@@ -1022,7 +1026,7 @@ void QgsGraduatedSymbolRendererV2::updateClasses( QgsVectorLayer *vlayer, Mode m
10221026
if ( values.isEmpty() )
10231027
return;
10241028

1025-
qSort( values );
1029+
qSort( values ); // vmora: is wondering if O( n log(n) ) is really necessary here, min and max are O( n )
10261030
minimum = values.first();
10271031
maximum = values.last();
10281032
valuesLoaded = true;
@@ -1146,6 +1150,16 @@ QgsFeatureRendererV2* QgsGraduatedSymbolRendererV2::create( QDomElement& element
11461150

11471151
QgsGraduatedSymbolRendererV2* r = new QgsGraduatedSymbolRendererV2( attrName, ranges );
11481152

1153+
QString attrMethod = element.attribute( "graduatedMethod" );
1154+
if ( attrMethod.length() )
1155+
{
1156+
if ( attrMethod == graduatedMethodStr( GraduatedColor ) )
1157+
r->setGraduatedMethod( GraduatedColor );
1158+
else if ( attrMethod == graduatedMethodStr( GraduatedSize ) )
1159+
r->setGraduatedMethod( GraduatedSize );
1160+
}
1161+
1162+
11491163
// delete symbols if there are any more
11501164
QgsSymbolLayerV2Utils::clearSymbolMap( symbolMap );
11511165

@@ -1214,6 +1228,7 @@ QDomElement QgsGraduatedSymbolRendererV2::save( QDomDocument& doc )
12141228
rendererElem.setAttribute( "type", "graduatedSymbol" );
12151229
rendererElem.setAttribute( "symbollevels", ( mUsingSymbolLevels ? "1" : "0" ) );
12161230
rendererElem.setAttribute( "attr", mAttrName );
1231+
rendererElem.setAttribute( "graduatedMethod", graduatedMethodStr( mGraduatedMethod ) );
12171232

12181233
// ranges
12191234
int i = 0;
@@ -1348,6 +1363,52 @@ void QgsGraduatedSymbolRendererV2::setSourceColorRamp( QgsVectorColorRampV2* ram
13481363
mSourceColorRamp.reset( ramp );
13491364
}
13501365

1366+
double QgsGraduatedSymbolRendererV2::minSymbolSize() const
1367+
{
1368+
double min = DBL_MAX;
1369+
for ( int i = 0; i < mRanges.count(); i++ )
1370+
{
1371+
double sz = 0;
1372+
if ( mRanges[i].symbol()->type() == QgsSymbolV2::Marker )
1373+
sz = static_cast< QgsMarkerSymbolV2 * >( mRanges[i].symbol() )->size();
1374+
else if ( mRanges[i].symbol()->type() == QgsSymbolV2::Line )
1375+
sz = static_cast< QgsLineSymbolV2 * >( mRanges[i].symbol() )->width();
1376+
min = qMin( sz, min );
1377+
}
1378+
return min;
1379+
}
1380+
1381+
double QgsGraduatedSymbolRendererV2::maxSymbolSize() const
1382+
{
1383+
double max = DBL_MIN;
1384+
for ( int i = 0; i < mRanges.count(); i++ )
1385+
{
1386+
double sz = 0;
1387+
if ( mRanges[i].symbol()->type() == QgsSymbolV2::Marker )
1388+
sz = static_cast< QgsMarkerSymbolV2 * >( mRanges[i].symbol() )->size();
1389+
else if ( mRanges[i].symbol()->type() == QgsSymbolV2::Line )
1390+
sz = static_cast< QgsLineSymbolV2 * >( mRanges[i].symbol() )->width();
1391+
max = qMax( sz, max );
1392+
}
1393+
return max;
1394+
}
1395+
1396+
void QgsGraduatedSymbolRendererV2::setSymbolSizes( double minSize, double maxSize )
1397+
{
1398+
for ( int i = 0; i < mRanges.count(); i++ )
1399+
{
1400+
QScopedPointer<QgsSymbolV2> symbol( mRanges[i].symbol() ? mRanges[i].symbol()->clone() : 0 );
1401+
const double size = mRanges.count() > 1
1402+
? minSize + i * ( maxSize - minSize ) / ( mRanges.count() - 1 )
1403+
: .5 * ( maxSize + minSize );
1404+
if ( symbol->type() == QgsSymbolV2::Marker )
1405+
static_cast< QgsMarkerSymbolV2 * >( symbol.data() )->setSize( size );
1406+
if ( symbol->type() == QgsSymbolV2::Line )
1407+
static_cast< QgsLineSymbolV2 * >( symbol.data() )->setWidth( size );
1408+
updateRangeSymbol( i, symbol.take() );
1409+
}
1410+
}
1411+
13511412
void QgsGraduatedSymbolRendererV2::updateColorRamp( QgsVectorColorRampV2 *ramp, bool inverted )
13521413
{
13531414
int i = 0;
@@ -1386,9 +1447,21 @@ void QgsGraduatedSymbolRendererV2::updateSymbols( QgsSymbolV2 *sym )
13861447
int i = 0;
13871448
foreach ( QgsRendererRangeV2 range, mRanges )
13881449
{
1389-
QgsSymbolV2 *symbol = sym->clone();
1390-
symbol->setColor( range.symbol()->color() );
1391-
updateRangeSymbol( i, symbol );
1450+
QScopedPointer<QgsSymbolV2> symbol( sym->clone() );
1451+
if ( mGraduatedMethod == GraduatedColor )
1452+
{
1453+
symbol->setColor( range.symbol()->color() );
1454+
}
1455+
else if ( mGraduatedMethod == GraduatedSize )
1456+
{
1457+
if ( symbol->type() == QgsSymbolV2::Marker )
1458+
static_cast<QgsMarkerSymbolV2 *>( symbol.data() )->setSize(
1459+
static_cast<QgsMarkerSymbolV2 *>( range.symbol() )->size() );
1460+
else if ( symbol->type() == QgsSymbolV2::Line )
1461+
static_cast<QgsLineSymbolV2 *>( symbol.data() )->setWidth(
1462+
static_cast<QgsLineSymbolV2 *>( range.symbol() )->width() );
1463+
}
1464+
updateRangeSymbol( i, symbol.take() );
13921465
++i;
13931466
}
13941467
setSourceSymbol( sym->clone() );
@@ -1602,3 +1675,15 @@ QgsGraduatedSymbolRendererV2* QgsGraduatedSymbolRendererV2::convertFromRenderer(
16021675

16031676
return r;
16041677
}
1678+
1679+
const char * QgsGraduatedSymbolRendererV2::graduatedMethodStr( GraduatedMethod method )
1680+
{
1681+
switch ( method )
1682+
{
1683+
case GraduatedColor: return "GraduatedColor";
1684+
case GraduatedSize: return "GraduatedSize";
1685+
}
1686+
return "";
1687+
}
1688+
1689+

src/core/symbology-ng/qgsgraduatedsymbolrendererv2.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ class QgsVectorColorRampV2;
113113
class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
114114
{
115115
public:
116+
116117
QgsGraduatedSymbolRendererV2( QString attrName = QString(), QgsRangeList ranges = QgsRangeList() );
117118
QgsGraduatedSymbolRendererV2( const QgsGraduatedSymbolRendererV2 & other );
118119

@@ -243,6 +244,30 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
243244
/** Update all the symbols but leave breaks and colors. */
244245
void updateSymbols( QgsSymbolV2* sym );
245246

247+
//! set varying symbol size for classes
248+
//! @note the classes must already be set so that symbols exist
249+
//! @note added in 2.10
250+
void setSymbolSizes( double minSize, double maxSize );
251+
252+
//! return the min symbol size when graduated by size
253+
//! @note added in 2.10
254+
double minSymbolSize() const;
255+
256+
//! return the max symbol size when graduated by size
257+
//! @note added in 2.10
258+
double maxSymbolSize() const;
259+
260+
enum GraduatedMethod {GraduatedColor = 0, GraduatedSize = 1 };
261+
262+
//! return the method used for graduation (either size or color)
263+
//! @note added in 2.10
264+
GraduatedMethod graduatedMethod() const { return mGraduatedMethod; }
265+
266+
//! set the method used for graduation (either size or color)
267+
//! @note added in 2.10
268+
void setGraduatedMethod( GraduatedMethod method ) { mGraduatedMethod = method; }
269+
270+
246271
void setRotationField( QString fieldOrExpression ) override;
247272
QString rotationField() const override;
248273

@@ -281,10 +306,12 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
281306
QScopedPointer<QgsVectorColorRampV2> mSourceColorRamp;
282307
bool mInvertedColorRamp;
283308
QgsRendererRangeV2LabelFormat mLabelFormat;
309+
284310
QScopedPointer<QgsExpression> mRotation;
285311
QScopedPointer<QgsExpression> mSizeScale;
286312
QgsSymbolV2::ScaleMethod mScaleMethod;
287313
QScopedPointer<QgsExpression> mExpression;
314+
GraduatedMethod mGraduatedMethod;
288315
//! attribute index (derived from attribute name in startRender)
289316
int mAttrNum;
290317
bool mCounting;
@@ -294,6 +321,8 @@ class CORE_EXPORT QgsGraduatedSymbolRendererV2 : public QgsFeatureRendererV2
294321

295322
QgsSymbolV2* symbolForValue( double value );
296323

324+
static const char * graduatedMethodStr( GraduatedMethod method );
325+
297326
};
298327

299328
#endif // QGSGRADUATEDSYMBOLRENDERERV2_H

0 commit comments

Comments
 (0)