void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( const QPointF& centerPoint, int nPosition, double radius, double symbolDiagonal, QList<QPointF>& symbolPositions, QList<QPointF>& labelShifts ) const { symbolPositions.clear(); labelShifts.clear(); if ( nPosition < 1 ) { return; } else if ( nPosition == 1 ) //If there is only one feature, draw it exactly at the center position { symbolPositions.append( centerPoint ); labelShifts.append( QPointF( symbolDiagonal / 2.0, -symbolDiagonal / 2.0 ) ); return; } double fullPerimeter = 2 * M_PI; double angleStep = fullPerimeter / nPosition; double currentAngle; for ( currentAngle = 0.0; currentAngle < fullPerimeter; currentAngle += angleStep ) { double sinusCurrentAngle = sin( currentAngle ); double cosinusCurrentAngle = cos( currentAngle ); QPointF positionShift( radius * sinusCurrentAngle, radius * cosinusCurrentAngle ); QPointF labelShift(( radius + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radius + symbolDiagonal / 2 ) * cosinusCurrentAngle ); symbolPositions.append( centerPoint + positionShift ); labelShifts.append( labelShift ); } }
void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( const QPointF& centerPoint, int nPosition, double radius, \ double symbolDiagonal, QList<QPointF>& symbolPositions, QList<QPointF>& labelShifts ) const { symbolPositions.clear(); labelShifts.clear(); double fullPerimeter = 2 * M_PI; double angleStep = fullPerimeter / nPosition; double currentAngle; for ( currentAngle = 0.0; currentAngle < fullPerimeter; currentAngle += angleStep ) { double sinusCurrentAngle = sin( currentAngle ); double cosinusCurrentAngle = cos( currentAngle ); QPointF positionShift( radius * sinusCurrentAngle, radius * cosinusCurrentAngle ); QPointF labelShift(( radius + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radius + symbolDiagonal / 2 ) * cosinusCurrentAngle ); symbolPositions.append( centerPoint + positionShift ); labelShifts.append( labelShift ); } }
void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( QgsSymbolV2RenderContext& symbolContext, const QPointF& centerPoint, int nPosition, double symbolDiagonal, QList<QPointF>& symbolPositions, QList<QPointF>& labelShifts, double& circleRadius ) const { symbolPositions.clear(); labelShifts.clear(); if ( nPosition < 1 ) { return; } else if ( nPosition == 1 ) //If there is only one feature, draw it exactly at the center position { symbolPositions.append( centerPoint ); labelShifts.append( QPointF( symbolDiagonal / 2.0, -symbolDiagonal / 2.0 ) ); return; } double circleAdditionPainterUnits = symbolContext.outputLineWidth( mCircleRadiusAddition ); switch ( mPlacement ) { case Ring: { double minDiameterToFitSymbols = nPosition * symbolDiagonal / ( 2.0 * M_PI ); double radius = qMax( symbolDiagonal / 2, minDiameterToFitSymbols ) + circleAdditionPainterUnits; double fullPerimeter = 2 * M_PI; double angleStep = fullPerimeter / nPosition; for ( double currentAngle = 0.0; currentAngle < fullPerimeter; currentAngle += angleStep ) { double sinusCurrentAngle = sin( currentAngle ); double cosinusCurrentAngle = cos( currentAngle ); QPointF positionShift( radius * sinusCurrentAngle, radius * cosinusCurrentAngle ); QPointF labelShift(( radius + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radius + symbolDiagonal / 2 ) * cosinusCurrentAngle ); symbolPositions.append( centerPoint + positionShift ); labelShifts.append( labelShift ); } circleRadius = radius; break; } case ConcentricRings: { double centerDiagonal = QgsSymbolLayerV2Utils::convertToPainterUnits( symbolContext.renderContext(), M_SQRT2 * mCenterSymbol->size(), mCenterSymbol->outputUnit(), mCenterSymbol->mapUnitScale() ); int pointsRemaining = nPosition; int ringNumber = 1; double firstRingRadius = centerDiagonal / 2.0 + symbolDiagonal / 2.0; while ( pointsRemaining > 0 ) { double radiusCurrentRing = qMax( firstRingRadius + ( ringNumber - 1 ) * symbolDiagonal + ringNumber * circleAdditionPainterUnits, 0.0 ); int maxPointsCurrentRing = qMax( floor( 2 * M_PI * radiusCurrentRing / symbolDiagonal ), 1.0 ); int actualPointsCurrentRing = qMin( maxPointsCurrentRing, pointsRemaining ); double angleStep = 2 * M_PI / actualPointsCurrentRing; double currentAngle = 0.0; for ( int i = 0; i < actualPointsCurrentRing; ++i ) { double sinusCurrentAngle = sin( currentAngle ); double cosinusCurrentAngle = cos( currentAngle ); QPointF positionShift( radiusCurrentRing * sinusCurrentAngle, radiusCurrentRing * cosinusCurrentAngle ); QPointF labelShift(( radiusCurrentRing + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radiusCurrentRing + symbolDiagonal / 2 ) * cosinusCurrentAngle ); symbolPositions.append( centerPoint + positionShift ); labelShifts.append( labelShift ); currentAngle += angleStep; } pointsRemaining -= actualPointsCurrentRing; ringNumber++; circleRadius = radiusCurrentRing; } break; } } }
void QgsPointDisplacementRenderer::calculateSymbolAndLabelPositions( QgsSymbolRenderContext &symbolContext, QPointF centerPoint, int nPosition, double symbolDiagonal, QList<QPointF> &symbolPositions, QList<QPointF> &labelShifts, double &circleRadius, double &gridRadius, int &gridSize ) const { symbolPositions.clear(); labelShifts.clear(); if ( nPosition < 1 ) { return; } else if ( nPosition == 1 ) //If there is only one feature, draw it exactly at the center position { symbolPositions.append( centerPoint ); labelShifts.append( QPointF( symbolDiagonal / 2.0, -symbolDiagonal / 2.0 ) ); return; } double circleAdditionPainterUnits = symbolContext.outputLineWidth( mCircleRadiusAddition ); switch ( mPlacement ) { case Ring: { double minDiameterToFitSymbols = nPosition * symbolDiagonal / ( 2.0 * M_PI ); double radius = std::max( symbolDiagonal / 2, minDiameterToFitSymbols ) + circleAdditionPainterUnits; double fullPerimeter = 2 * M_PI; double angleStep = fullPerimeter / nPosition; for ( double currentAngle = 0.0; currentAngle < fullPerimeter; currentAngle += angleStep ) { double sinusCurrentAngle = std::sin( currentAngle ); double cosinusCurrentAngle = std::cos( currentAngle ); QPointF positionShift( radius * sinusCurrentAngle, radius * cosinusCurrentAngle ); QPointF labelShift( ( radius + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radius + symbolDiagonal / 2 ) * cosinusCurrentAngle ); symbolPositions.append( centerPoint + positionShift ); labelShifts.append( labelShift ); } circleRadius = radius; break; } case ConcentricRings: { double centerDiagonal = mCenterSymbol->size( symbolContext.renderContext() ) * M_SQRT2; int pointsRemaining = nPosition; int ringNumber = 1; double firstRingRadius = centerDiagonal / 2.0 + symbolDiagonal / 2.0; while ( pointsRemaining > 0 ) { double radiusCurrentRing = std::max( firstRingRadius + ( ringNumber - 1 ) * symbolDiagonal + ringNumber * circleAdditionPainterUnits, 0.0 ); int maxPointsCurrentRing = std::max( std::floor( 2 * M_PI * radiusCurrentRing / symbolDiagonal ), 1.0 ); int actualPointsCurrentRing = std::min( maxPointsCurrentRing, pointsRemaining ); double angleStep = 2 * M_PI / actualPointsCurrentRing; double currentAngle = 0.0; for ( int i = 0; i < actualPointsCurrentRing; ++i ) { double sinusCurrentAngle = std::sin( currentAngle ); double cosinusCurrentAngle = std::cos( currentAngle ); QPointF positionShift( radiusCurrentRing * sinusCurrentAngle, radiusCurrentRing * cosinusCurrentAngle ); QPointF labelShift( ( radiusCurrentRing + symbolDiagonal / 2 ) * sinusCurrentAngle, ( radiusCurrentRing + symbolDiagonal / 2 ) * cosinusCurrentAngle ); symbolPositions.append( centerPoint + positionShift ); labelShifts.append( labelShift ); currentAngle += angleStep; } pointsRemaining -= actualPointsCurrentRing; ringNumber++; circleRadius = radiusCurrentRing; } break; } case Grid: { double centerDiagonal = mCenterSymbol->size( symbolContext.renderContext() ) * M_SQRT2; int pointsRemaining = nPosition; gridSize = std::ceil( std::sqrt( pointsRemaining ) ); if ( pointsRemaining - std::pow( gridSize - 1, 2 ) < gridSize ) gridSize -= 1; double originalPointRadius = ( ( centerDiagonal / 2.0 + symbolDiagonal / 2.0 ) + symbolDiagonal ) / 2; double userPointRadius = originalPointRadius + circleAdditionPainterUnits; int yIndex = 0; while ( pointsRemaining > 0 ) { for ( int xIndex = 0; xIndex < gridSize && pointsRemaining > 0; ++xIndex ) { QPointF positionShift( userPointRadius * xIndex, userPointRadius * yIndex ); QPointF labelShift( ( userPointRadius + symbolDiagonal / 2 ) * xIndex, ( userPointRadius + symbolDiagonal / 2 ) * yIndex ); symbolPositions.append( centerPoint + positionShift ); labelShifts.append( labelShift ); pointsRemaining--; } yIndex++; } centralizeGrid( symbolPositions, userPointRadius, gridSize ); centralizeGrid( labelShifts, userPointRadius, gridSize ); gridRadius = userPointRadius; break; } } }