@@ -43,6 +43,7 @@ QgsPointDisplacementRenderer *QgsPointDisplacementRenderer::clone() const
4343 r->setLabelColor ( mLabelColor );
4444 r->setPlacement ( mPlacement );
4545 r->setCircleRadiusAddition ( mCircleRadiusAddition );
46+ r->setLabelDistanceFactor ( mLabelDistanceFactor );
4647 r->setMinimumLabelScale ( mMinLabelScale );
4748 r->setTolerance ( mTolerance );
4849 r->setToleranceUnit ( mToleranceUnit );
@@ -60,12 +61,21 @@ void QgsPointDisplacementRenderer::drawGroup( QPointF centerPoint, QgsRenderCont
6061
6162 // calculate max diagonal size from all symbols in group
6263 double diagonal = 0 ;
64+ QList<double > diagonals;
65+ double currentDiagonal;
6366
6467 for ( const GroupedFeature &feature : group )
6568 {
6669 if ( QgsMarkerSymbol *symbol = feature.symbol () )
6770 {
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 );
6979 }
7080 }
7181
@@ -77,7 +87,7 @@ void QgsPointDisplacementRenderer::drawGroup( QPointF centerPoint, QgsRenderCont
7787 double gridRadius = -1.0 ;
7888 int gridSize = -1 ;
7989
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 );
8191
8292 // only draw circle/grid if there's a pen present - otherwise skip drawing transparent grids
8393 if ( mCircleColor .isValid () && mCircleColor .alpha () > 0 )
@@ -149,6 +159,7 @@ QgsFeatureRenderer *QgsPointDisplacementRenderer::create( QDomElement &symbology
149159 r->setCircleColor ( QgsSymbolLayerUtils::decodeColor ( symbologyElem.attribute ( QStringLiteral ( " circleColor" ), QString () ) ) );
150160 r->setLabelColor ( QgsSymbolLayerUtils::decodeColor ( symbologyElem.attribute ( QStringLiteral ( " labelColor" ), QString () ) ) );
151161 r->setCircleRadiusAddition ( symbologyElem.attribute ( QStringLiteral ( " circleRadiusAddition" ), QStringLiteral ( " 0.0" ) ).toDouble () );
162+ r->setLabelDistanceFactor ( symbologyElem.attribute ( QStringLiteral ( " labelDistanceFactor" ), QStringLiteral ( " 0.5" ) ).toDouble () );
152163 r->setMinimumLabelScale ( symbologyElem.attribute ( QStringLiteral ( " maxLabelScaleDenominator" ), QStringLiteral ( " -1" ) ).toDouble () );
153164 r->setTolerance ( symbologyElem.attribute ( QStringLiteral ( " tolerance" ), QStringLiteral ( " 0.00001" ) ).toDouble () );
154165 r->setToleranceUnit ( QgsUnitTypes::decodeRenderUnit ( symbologyElem.attribute ( QStringLiteral ( " toleranceUnit" ), QStringLiteral ( " MapUnit" ) ) ) );
@@ -186,6 +197,7 @@ QDomElement QgsPointDisplacementRenderer::save( QDomDocument &doc, const QgsRead
186197 rendererElement.setAttribute ( QStringLiteral ( " circleColor" ), QgsSymbolLayerUtils::encodeColor ( mCircleColor ) );
187198 rendererElement.setAttribute ( QStringLiteral ( " labelColor" ), QgsSymbolLayerUtils::encodeColor ( mLabelColor ) );
188199 rendererElement.setAttribute ( QStringLiteral ( " circleRadiusAddition" ), QString::number ( mCircleRadiusAddition ) );
200+ rendererElement.setAttribute ( QStringLiteral ( " labelDistanceFactor" ), QString::number ( mLabelDistanceFactor ) );
189201 rendererElement.setAttribute ( QStringLiteral ( " placement" ), static_cast < int >( mPlacement ) );
190202 rendererElement.setAttribute ( QStringLiteral ( " maxLabelScaleDenominator" ), QString::number ( mMinLabelScale ) );
191203 rendererElement.setAttribute ( QStringLiteral ( " tolerance" ), QString::number ( mTolerance ) );
@@ -232,7 +244,7 @@ void QgsPointDisplacementRenderer::setCenterSymbol( QgsMarkerSymbol *symbol )
232244
233245void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions ( QgsSymbolRenderContext &symbolContext, QPointF centerPoint, int nPosition,
234246 double symbolDiagonal, QList<QPointF> &symbolPositions, QList<QPointF> &labelShifts, double &circleRadius, double &gridRadius,
235- int &gridSize ) const
247+ int &gridSize, QList< double > &diagonals ) const
236248{
237249 symbolPositions.clear ();
238250 labelShifts.clear ();
@@ -243,8 +255,9 @@ void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( QgsSymbolRe
243255 }
244256 else if ( nPosition == 1 ) // If there is only one feature, draw it exactly at the center position
245257 {
258+ double side = sqrt ( pow ( symbolDiagonal, 2 ) / 2.0 );
246259 symbolPositions.append ( centerPoint );
247- labelShifts.append ( QPointF ( symbolDiagonal / 2.0 , -symbolDiagonal / 2.0 ) );
260+ labelShifts.append ( QPointF ( side * mLabelDistanceFactor , -side * mLabelDistanceFactor ) );
248261 return ;
249262 }
250263
@@ -259,16 +272,19 @@ void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( QgsSymbolRe
259272
260273 double fullPerimeter = 2 * M_PI;
261274 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++ )
263279 {
264280 double sinusCurrentAngle = std::sin ( currentAngle );
265281 double cosinusCurrentAngle = std::cos ( currentAngle );
266282 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 );
268285 symbolPositions.append ( centerPoint + positionShift );
269286 labelShifts.append ( labelShift );
270287 }
271-
272288 circleRadius = radius;
273289 break ;
274290 }
@@ -279,6 +295,7 @@ void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( QgsSymbolRe
279295 int pointsRemaining = nPosition;
280296 int ringNumber = 1 ;
281297 double firstRingRadius = centerDiagonal / 2.0 + symbolDiagonal / 2.0 ;
298+ int featureIndex = 0 ;
282299 while ( pointsRemaining > 0 )
283300 {
284301 double radiusCurrentRing = std::max ( firstRingRadius + ( ringNumber - 1 ) * symbolDiagonal + ringNumber * circleAdditionPainterUnits, 0.0 );
@@ -292,10 +309,11 @@ void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( QgsSymbolRe
292309 double sinusCurrentAngle = std::sin ( currentAngle );
293310 double cosinusCurrentAngle = std::cos ( currentAngle );
294311 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 );
296313 symbolPositions.append ( centerPoint + positionShift );
297314 labelShifts.append ( labelShift );
298315 currentAngle += angleStep;
316+ featureIndex++;
299317 }
300318
301319 pointsRemaining -= actualPointsCurrentRing;
@@ -315,15 +333,17 @@ void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( QgsSymbolRe
315333 double userPointRadius = originalPointRadius + circleAdditionPainterUnits;
316334
317335 int yIndex = 0 ;
336+ int featureIndex = 0 ;
318337 while ( pointsRemaining > 0 )
319338 {
320339 for ( int xIndex = 0 ; xIndex < gridSize && pointsRemaining > 0 ; ++xIndex )
321340 {
322341 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 );
324343 symbolPositions.append ( centerPoint + positionShift );
325344 labelShifts.append ( labelShift );
326345 pointsRemaining--;
346+ featureIndex++;
327347 }
328348 yIndex++;
329349 }
0 commit comments