@@ -43,6 +43,7 @@ QgsPointDisplacementRenderer *QgsPointDisplacementRenderer::clone() const
43
43
r->setLabelColor ( mLabelColor );
44
44
r->setPlacement ( mPlacement );
45
45
r->setCircleRadiusAddition ( mCircleRadiusAddition );
46
+ r->setLabelDistanceFactor ( mLabelDistanceFactor );
46
47
r->setMinimumLabelScale ( mMinLabelScale );
47
48
r->setTolerance ( mTolerance );
48
49
r->setToleranceUnit ( mToleranceUnit );
@@ -60,12 +61,21 @@ void QgsPointDisplacementRenderer::drawGroup( QPointF centerPoint, QgsRenderCont
60
61
61
62
// calculate max diagonal size from all symbols in group
62
63
double diagonal = 0 ;
64
+ QList<double > diagonals;
65
+ double currentDiagonal;
63
66
64
67
for ( const GroupedFeature &feature : group )
65
68
{
66
69
if ( QgsMarkerSymbol *symbol = feature.symbol () )
67
70
{
68
- diagonal = std::max ( diagonal, M_SQRT2 * symbol->size ( context ) );
71
+ currentDiagonal = M_SQRT2 * symbol->size ( context );
72
+ diagonals.append ( currentDiagonal );
73
+ diagonal = std::max ( diagonal, currentDiagonal );
74
+
75
+ }
76
+ else
77
+ {
78
+ diagonals.append ( 0.0 );
69
79
}
70
80
}
71
81
@@ -77,7 +87,7 @@ void QgsPointDisplacementRenderer::drawGroup( QPointF centerPoint, QgsRenderCont
77
87
double gridRadius = -1.0 ;
78
88
int gridSize = -1 ;
79
89
80
- calculateSymbolAndLabelPositions ( symbolContext, centerPoint, group.size (), diagonal, symbolPositions, labelPositions, circleRadius, gridRadius, gridSize );
90
+ calculateSymbolAndLabelPositions ( symbolContext, centerPoint, group.size (), diagonal, symbolPositions, labelPositions, circleRadius, gridRadius, gridSize, diagonals );
81
91
82
92
// only draw circle/grid if there's a pen present - otherwise skip drawing transparent grids
83
93
if ( mCircleColor .isValid () && mCircleColor .alpha () > 0 )
@@ -149,6 +159,7 @@ QgsFeatureRenderer *QgsPointDisplacementRenderer::create( QDomElement &symbology
149
159
r->setCircleColor ( QgsSymbolLayerUtils::decodeColor ( symbologyElem.attribute ( QStringLiteral ( " circleColor" ), QString () ) ) );
150
160
r->setLabelColor ( QgsSymbolLayerUtils::decodeColor ( symbologyElem.attribute ( QStringLiteral ( " labelColor" ), QString () ) ) );
151
161
r->setCircleRadiusAddition ( symbologyElem.attribute ( QStringLiteral ( " circleRadiusAddition" ), QStringLiteral ( " 0.0" ) ).toDouble () );
162
+ r->setLabelDistanceFactor ( symbologyElem.attribute ( QStringLiteral ( " labelDistanceFactor" ), QStringLiteral ( " 0.5" ) ).toDouble () );
152
163
r->setMinimumLabelScale ( symbologyElem.attribute ( QStringLiteral ( " maxLabelScaleDenominator" ), QStringLiteral ( " -1" ) ).toDouble () );
153
164
r->setTolerance ( symbologyElem.attribute ( QStringLiteral ( " tolerance" ), QStringLiteral ( " 0.00001" ) ).toDouble () );
154
165
r->setToleranceUnit ( QgsUnitTypes::decodeRenderUnit ( symbologyElem.attribute ( QStringLiteral ( " toleranceUnit" ), QStringLiteral ( " MapUnit" ) ) ) );
@@ -186,6 +197,7 @@ QDomElement QgsPointDisplacementRenderer::save( QDomDocument &doc, const QgsRead
186
197
rendererElement.setAttribute ( QStringLiteral ( " circleColor" ), QgsSymbolLayerUtils::encodeColor ( mCircleColor ) );
187
198
rendererElement.setAttribute ( QStringLiteral ( " labelColor" ), QgsSymbolLayerUtils::encodeColor ( mLabelColor ) );
188
199
rendererElement.setAttribute ( QStringLiteral ( " circleRadiusAddition" ), QString::number ( mCircleRadiusAddition ) );
200
+ rendererElement.setAttribute ( QStringLiteral ( " labelDistanceFactor" ), QString::number ( mLabelDistanceFactor ) );
189
201
rendererElement.setAttribute ( QStringLiteral ( " placement" ), static_cast < int >( mPlacement ) );
190
202
rendererElement.setAttribute ( QStringLiteral ( " maxLabelScaleDenominator" ), QString::number ( mMinLabelScale ) );
191
203
rendererElement.setAttribute ( QStringLiteral ( " tolerance" ), QString::number ( mTolerance ) );
@@ -232,7 +244,7 @@ void QgsPointDisplacementRenderer::setCenterSymbol( QgsMarkerSymbol *symbol )
232
244
233
245
void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions ( QgsSymbolRenderContext &symbolContext, QPointF centerPoint, int nPosition,
234
246
double symbolDiagonal, QList<QPointF> &symbolPositions, QList<QPointF> &labelShifts, double &circleRadius, double &gridRadius,
235
- int &gridSize ) const
247
+ int &gridSize, QList< double > &diagonals ) const
236
248
{
237
249
symbolPositions.clear ();
238
250
labelShifts.clear ();
@@ -243,8 +255,9 @@ void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( QgsSymbolRe
243
255
}
244
256
else if ( nPosition == 1 ) // If there is only one feature, draw it exactly at the center position
245
257
{
258
+ double side = sqrt ( pow ( symbolDiagonal, 2 ) / 2.0 );
246
259
symbolPositions.append ( centerPoint );
247
- labelShifts.append ( QPointF ( symbolDiagonal / 2.0 , -symbolDiagonal / 2.0 ) );
260
+ labelShifts.append ( QPointF ( side * mLabelDistanceFactor , -side * mLabelDistanceFactor ) );
248
261
return ;
249
262
}
250
263
@@ -259,16 +272,19 @@ void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( QgsSymbolRe
259
272
260
273
double fullPerimeter = 2 * M_PI;
261
274
double angleStep = fullPerimeter / nPosition;
262
- for ( double currentAngle = 0.0 ; currentAngle < fullPerimeter; currentAngle += angleStep )
275
+
276
+ int featureIndex;
277
+ double currentAngle;
278
+ for ( currentAngle = 0.0 , featureIndex = 0 ; currentAngle < fullPerimeter; currentAngle += angleStep, featureIndex++ )
263
279
{
264
280
double sinusCurrentAngle = std::sin ( currentAngle );
265
281
double cosinusCurrentAngle = std::cos ( currentAngle );
266
282
QPointF positionShift ( radius * sinusCurrentAngle, radius * cosinusCurrentAngle );
267
- QPointF labelShift ( ( radius + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radius + symbolDiagonal / 2 ) * cosinusCurrentAngle );
283
+
284
+ QPointF labelShift ( ( radius + diagonals[featureIndex] * mLabelDistanceFactor ) * sinusCurrentAngle, ( radius + diagonals[featureIndex] * mLabelDistanceFactor ) * cosinusCurrentAngle );
268
285
symbolPositions.append ( centerPoint + positionShift );
269
286
labelShifts.append ( labelShift );
270
287
}
271
-
272
288
circleRadius = radius;
273
289
break ;
274
290
}
@@ -279,6 +295,7 @@ void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( QgsSymbolRe
279
295
int pointsRemaining = nPosition;
280
296
int ringNumber = 1 ;
281
297
double firstRingRadius = centerDiagonal / 2.0 + symbolDiagonal / 2.0 ;
298
+ int featureIndex = 0 ;
282
299
while ( pointsRemaining > 0 )
283
300
{
284
301
double radiusCurrentRing = std::max ( firstRingRadius + ( ringNumber - 1 ) * symbolDiagonal + ringNumber * circleAdditionPainterUnits, 0.0 );
@@ -292,10 +309,11 @@ void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( QgsSymbolRe
292
309
double sinusCurrentAngle = std::sin ( currentAngle );
293
310
double cosinusCurrentAngle = std::cos ( currentAngle );
294
311
QPointF positionShift ( radiusCurrentRing * sinusCurrentAngle, radiusCurrentRing * cosinusCurrentAngle );
295
- QPointF labelShift ( ( radiusCurrentRing + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radiusCurrentRing + symbolDiagonal / 2 ) * cosinusCurrentAngle );
312
+ QPointF labelShift ( ( radiusCurrentRing + diagonals[featureIndex] * mLabelDistanceFactor ) * sinusCurrentAngle, ( radiusCurrentRing + diagonals[featureIndex] * mLabelDistanceFactor ) * cosinusCurrentAngle );
296
313
symbolPositions.append ( centerPoint + positionShift );
297
314
labelShifts.append ( labelShift );
298
315
currentAngle += angleStep;
316
+ featureIndex++;
299
317
}
300
318
301
319
pointsRemaining -= actualPointsCurrentRing;
@@ -315,15 +333,17 @@ void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( QgsSymbolRe
315
333
double userPointRadius = originalPointRadius + circleAdditionPainterUnits;
316
334
317
335
int yIndex = 0 ;
336
+ int featureIndex = 0 ;
318
337
while ( pointsRemaining > 0 )
319
338
{
320
339
for ( int xIndex = 0 ; xIndex < gridSize && pointsRemaining > 0 ; ++xIndex )
321
340
{
322
341
QPointF positionShift ( userPointRadius * xIndex, userPointRadius * yIndex );
323
- QPointF labelShift ( ( userPointRadius + symbolDiagonal / 2 ) * xIndex, ( userPointRadius + symbolDiagonal / 2 ) * yIndex );
342
+ QPointF labelShift ( ( userPointRadius + diagonals[featureIndex] * mLabelDistanceFactor ) * xIndex, ( userPointRadius + diagonals[featureIndex] * mLabelDistanceFactor ) * yIndex );
324
343
symbolPositions.append ( centerPoint + positionShift );
325
344
labelShifts.append ( labelShift );
326
345
pointsRemaining--;
346
+ featureIndex++;
327
347
}
328
348
yIndex++;
329
349
}
0 commit comments