void QgsPointDisplacementRenderer::drawGroup( QPointF centerPoint, QgsRenderContext &context, const ClusteredGroup &group ) { //calculate max diagonal size from all symbols in group double diagonal = 0; for ( const GroupedFeature &feature : group ) { if ( QgsMarkerSymbol *symbol = feature.symbol() ) { diagonal = std::max( diagonal, M_SQRT2 * symbol->size( context ) ); } } QgsSymbolRenderContext symbolContext( context, QgsUnitTypes::RenderMillimeters, 1.0, false ); QList<QPointF> symbolPositions; QList<QPointF> labelPositions; double circleRadius = -1.0; double gridRadius = -1.0; int gridSize = -1; calculateSymbolAndLabelPositions( symbolContext, centerPoint, group.size(), diagonal, symbolPositions, labelPositions, circleRadius, gridRadius, gridSize ); //only draw circle/grid if there's a pen present - otherwise skip drawing transparent grids if ( mCircleColor.isValid() && mCircleColor.alpha() > 0 ) { //draw circle if ( circleRadius > 0 ) drawCircle( circleRadius, symbolContext, centerPoint, group.size() ); //draw grid else drawGrid( gridSize, symbolContext, symbolPositions, group.size() ); } if ( group.size() > 1 ) { //draw mid point QgsFeature firstFeature = group.at( 0 ).feature; if ( mCenterSymbol ) { mCenterSymbol->renderPoint( centerPoint, &firstFeature, context, -1, false ); } else { context.painter()->drawRect( QRectF( centerPoint.x() - symbolContext.outputLineWidth( 1 ), centerPoint.y() - symbolContext.outputLineWidth( 1 ), symbolContext.outputLineWidth( 2 ), symbolContext.outputLineWidth( 2 ) ) ); } } //draw symbols on the circle drawSymbols( group, context, symbolPositions ); //and also the labels if ( mLabelIndex >= 0 ) { drawLabels( centerPoint, symbolContext, labelPositions, group ); } }
void QgsPointDisplacementRenderer::drawGroup( QPointF centerPoint, QgsRenderContext& context, const ClusteredGroup& group ) { //calculate max diagonal size from all symbols in group double diagonal = 0; Q_FOREACH ( const GroupedFeature& feature, group ) { if ( QgsMarkerSymbol* symbol = feature.symbol ) { diagonal = qMax( diagonal, context.convertToPainterUnits( M_SQRT2 * symbol->size(), symbol->sizeUnit(), symbol->sizeMapUnitScale() ) ); } } QgsSymbolRenderContext symbolContext( context, QgsUnitTypes::RenderMillimeters, 1.0, false ); QList<QPointF> symbolPositions; QList<QPointF> labelPositions; double circleRadius = -1.0; calculateSymbolAndLabelPositions( symbolContext, centerPoint, group.size(), diagonal, symbolPositions, labelPositions, circleRadius ); //draw circle if ( circleRadius > 0 ) drawCircle( circleRadius, symbolContext, centerPoint, group.size() ); if ( group.size() > 1 ) { //draw mid point QgsFeature firstFeature = group.at( 0 ).feature; if ( mCenterSymbol ) { mCenterSymbol->renderPoint( centerPoint, &firstFeature, context, -1, false ); } else { context.painter()->drawRect( QRectF( centerPoint.x() - symbolContext.outputLineWidth( 1 ), centerPoint.y() - symbolContext.outputLineWidth( 1 ), symbolContext.outputLineWidth( 2 ), symbolContext.outputLineWidth( 2 ) ) ); } } //draw symbols on the circle drawSymbols( group, context, symbolPositions ); //and also the labels if ( mLabelIndex >= 0 ) { drawLabels( centerPoint, symbolContext, labelPositions, group ); } }
bool QgsPointDisplacementRenderer::renderFeature( QgsFeature& feature, QgsRenderContext& context, int layer, bool selected, bool drawVertexMarker ) { Q_UNUSED( drawVertexMarker ); //point position in screen coords QgsGeometry* geom = feature.geometry(); QGis::WkbType geomType = geom->wkbType(); if ( geomType != QGis::WKBPoint && geomType != QGis::WKBPoint25D ) { //can only render point type return false; } QPointF pt; _getPoint( pt, context, geom->asWkb() ); //get list of labels and symbols QStringList labelAttributeList; QList<QgsMarkerSymbolV2*> symbolList; if ( mDisplacementIds.contains( feature.id() ) ) { //create the symbol for the whole display group if the id is the first entry in a display group QList<QMap<QgsFeatureId, QgsFeature> >::iterator it = mDisplacementGroups.begin(); for ( ; it != mDisplacementGroups.end(); ++it ) { //create the symbol for the whole display group if the id is the first entry in a display group if ( feature.id() == it->begin().key() ) { QMap<QgsFeatureId, QgsFeature>::iterator attIt = it->begin(); for ( ; attIt != it->end(); ++attIt ) { if ( mDrawLabels ) { labelAttributeList << getLabel( attIt.value() ); } else { labelAttributeList << QString(); } symbolList << dynamic_cast<QgsMarkerSymbolV2*>( firstSymbolForFeature( mRenderer, attIt.value() ) ); } } } } else //only one feature { symbolList << dynamic_cast<QgsMarkerSymbolV2*>( firstSymbolForFeature( mRenderer, feature ) ); if ( mDrawLabels ) { labelAttributeList << getLabel( feature ); } else { labelAttributeList << QString(); } } if ( symbolList.isEmpty() && labelAttributeList.isEmpty() ) { return true; //display all point symbols for one posi } //draw symbol double diagonal = 0; double currentWidthFactor; //scale symbol size to map unit and output resolution QList<QgsMarkerSymbolV2*>::const_iterator it = symbolList.constBegin(); for ( ; it != symbolList.constEnd(); ++it ) { if ( *it ) { currentWidthFactor = QgsSymbolLayerV2Utils::lineWidthScaleFactor( context, ( *it )->outputUnit() ); double currentDiagonal = sqrt( 2 * (( *it )->size() * ( *it )->size() ) ) * currentWidthFactor; if ( currentDiagonal > diagonal ) { diagonal = currentDiagonal; } } } QgsSymbolV2RenderContext symbolContext( context, QgsSymbolV2::MM, 1.0, selected ); double circleAdditionPainterUnits = symbolContext.outputLineWidth( mCircleRadiusAddition ); double radius = qMax(( diagonal / 2 ), labelAttributeList.size() * diagonal / 2 / M_PI ) + circleAdditionPainterUnits; //draw Circle drawCircle( radius, symbolContext, pt, symbolList.size() ); QList<QPointF> symbolPositions; QList<QPointF> labelPositions; calculateSymbolAndLabelPositions( pt, labelAttributeList.size(), radius, diagonal, symbolPositions, labelPositions ); //draw mid point if ( labelAttributeList.size() > 1 ) { if ( mCenterSymbol ) { mCenterSymbol->renderPoint( pt, &feature, context, layer, selected ); } else { context.painter()->drawRect( QRectF( pt.x() - symbolContext.outputLineWidth( 1 ), pt.y() - symbolContext.outputLineWidth( 1 ), symbolContext.outputLineWidth( 2 ), symbolContext.outputLineWidth( 2 ) ) ); } } //draw symbols on the circle drawSymbols( feature, context, symbolList, symbolPositions, selected ); //and also the labels drawLabels( pt, symbolContext, labelPositions, labelAttributeList ); return true; }
void QgsPointDisplacementRenderer::drawGroup( const DisplacementGroup& group, QgsRenderContext& context ) { const QgsFeature& feature = group.begin().value().first; bool selected = mSelectedFeatures.contains( feature.id() ); // maybe we should highlight individual features instead of the whole group? //get list of labels and symbols QStringList labelAttributeList; QList<QgsMarkerSymbolV2*> symbolList; QgsMultiPointV2* groupMultiPoint = new QgsMultiPointV2(); for ( DisplacementGroup::const_iterator attIt = group.constBegin(); attIt != group.constEnd(); ++attIt ) { labelAttributeList << ( mDrawLabels ? getLabel( attIt.value().first ) : QString() ); symbolList << dynamic_cast<QgsMarkerSymbolV2*>( attIt.value().second ); groupMultiPoint->addGeometry( attIt.value().first.constGeometry()->geometry()->clone() ); } //calculate centroid of all points, this will be center of group QgsGeometry groupGeom( groupMultiPoint ); QgsGeometry* centroid = groupGeom.centroid(); QPointF pt; _getPoint( pt, context, centroid->asWkb() ); delete centroid; //calculate max diagonal size from all symbols in group double diagonal = 0; Q_FOREACH ( QgsMarkerSymbolV2* symbol, symbolList ) { if ( symbol ) { diagonal = qMax( diagonal, QgsSymbolLayerV2Utils::convertToPainterUnits( context, M_SQRT2 * symbol->size(), symbol->outputUnit(), symbol->mapUnitScale() ) ); } } QgsSymbolV2RenderContext symbolContext( context, QgsSymbolV2::MM, 1.0, selected ); QList<QPointF> symbolPositions; QList<QPointF> labelPositions; double circleRadius = -1.0; calculateSymbolAndLabelPositions( symbolContext, pt, symbolList.size(), diagonal, symbolPositions, labelPositions, circleRadius ); //draw Circle if ( circleRadius > 0 ) drawCircle( circleRadius, symbolContext, pt, symbolList.size() ); //draw mid point if ( labelAttributeList.size() > 1 ) { if ( mCenterSymbol ) { mCenterSymbol->renderPoint( pt, &feature, context, -1, selected ); } else { context.painter()->drawRect( QRectF( pt.x() - symbolContext.outputLineWidth( 1 ), pt.y() - symbolContext.outputLineWidth( 1 ), symbolContext.outputLineWidth( 2 ), symbolContext.outputLineWidth( 2 ) ) ); } } //draw symbols on the circle drawSymbols( feature, context, symbolList, symbolPositions, selected ); //and also the labels drawLabels( pt, symbolContext, labelPositions, labelAttributeList ); }
void QgsPointDisplacementRenderer::drawGroup( const DisplacementGroup& group, QgsRenderContext& context ) { const QgsFeature& feature = group.begin().value().first; bool selected = mSelectedFeatures.contains( feature.id() ); // maybe we should highlight individual features instead of the whole group? QPointF pt; _getPoint( pt, context, feature.constGeometry()->asWkb() ); //get list of labels and symbols QStringList labelAttributeList; QList<QgsMarkerSymbolV2*> symbolList; for ( DisplacementGroup::const_iterator attIt = group.constBegin(); attIt != group.constEnd(); ++attIt ) { labelAttributeList << ( mDrawLabels ? getLabel( attIt.value().first ) : QString() ); symbolList << dynamic_cast<QgsMarkerSymbolV2*>( attIt.value().second ); } //draw symbol double diagonal = 0; double currentWidthFactor; //scale symbol size to map unit and output resolution QList<QgsMarkerSymbolV2*>::const_iterator it = symbolList.constBegin(); for ( ; it != symbolList.constEnd(); ++it ) { if ( *it ) { currentWidthFactor = QgsSymbolLayerV2Utils::lineWidthScaleFactor( context, ( *it )->outputUnit(), ( *it )->mapUnitScale() ); double currentDiagonal = sqrt( 2 * (( *it )->size() * ( *it )->size() ) ) * currentWidthFactor; if ( currentDiagonal > diagonal ) { diagonal = currentDiagonal; } } } QgsSymbolV2RenderContext symbolContext( context, QgsSymbolV2::MM, 1.0, selected ); double circleAdditionPainterUnits = symbolContext.outputLineWidth( mCircleRadiusAddition ); double radius = qMax(( diagonal / 2 ), labelAttributeList.size() * diagonal / 2 / M_PI ) + circleAdditionPainterUnits; //draw Circle drawCircle( radius, symbolContext, pt, symbolList.size() ); QList<QPointF> symbolPositions; QList<QPointF> labelPositions; calculateSymbolAndLabelPositions( pt, labelAttributeList.size(), radius, diagonal, symbolPositions, labelPositions ); //draw mid point if ( labelAttributeList.size() > 1 ) { if ( mCenterSymbol ) { mCenterSymbol->renderPoint( pt, &feature, context, -1, selected ); } else { context.painter()->drawRect( QRectF( pt.x() - symbolContext.outputLineWidth( 1 ), pt.y() - symbolContext.outputLineWidth( 1 ), symbolContext.outputLineWidth( 2 ), symbolContext.outputLineWidth( 2 ) ) ); } } //draw symbols on the circle drawSymbols( feature, context, symbolList, symbolPositions, selected ); //and also the labels drawLabels( pt, symbolContext, labelPositions, labelAttributeList ); }