void QgsMeshVectorRenderer::drawVectorArrow( const QgsPointXY &lineStart, double xVal, double yVal, double magnitude ) { QgsPointXY lineEnd; double vectorLength; double cosAlpha, sinAlpha; if ( calcVectorLineEnd( lineEnd, vectorLength, cosAlpha, sinAlpha, lineStart, xVal, yVal, magnitude ) ) return; // Make a set of vector head coordinates that we will place at the end of each vector, // scale, translate and rotate. QgsPointXY vectorHeadPoints[3]; QVector<QPointF> finalVectorHeadPoints( 3 ); double vectorHeadWidthRatio = mCfg.arrowHeadWidthRatio(); double vectorHeadLengthRatio = mCfg.arrowHeadLengthRatio(); // First head point: top of -> vectorHeadPoints[0].setX( -1.0 * vectorHeadLengthRatio ); vectorHeadPoints[0].setY( vectorHeadWidthRatio * 0.5 ); // Second head point: right of -> vectorHeadPoints[1].setX( 0.0 ); vectorHeadPoints[1].setY( 0.0 ); // Third head point: bottom of -> vectorHeadPoints[2].setX( -1.0 * vectorHeadLengthRatio ); vectorHeadPoints[2].setY( -1.0 * vectorHeadWidthRatio * 0.5 ); // Determine the arrow head coords for ( int j = 0; j < 3; j++ ) { finalVectorHeadPoints[j].setX( lineEnd.x() + ( vectorHeadPoints[j].x() * cosAlpha * vectorLength ) - ( vectorHeadPoints[j].y() * sinAlpha * vectorLength ) ); finalVectorHeadPoints[j].setY( lineEnd.y() - ( vectorHeadPoints[j].x() * sinAlpha * vectorLength ) - ( vectorHeadPoints[j].y() * cosAlpha * vectorLength ) ); } // Now actually draw the vector mContext.painter()->drawLine( lineStart.toQPointF(), lineEnd.toQPointF() ); mContext.painter()->drawPolygon( finalVectorHeadPoints ); }
void QgsVectorLayerDiagramProvider::drawLabel( QgsRenderContext &context, pal::LabelPosition *label ) const { #if 1 // XXX strk // features are pre-rotated but not scaled/translated, // so we only disable rotation here. Ideally, they'd be // also pre-scaled/translated, as suggested here: // https://issues.qgis.org/issues/11856 QgsMapToPixel xform = context.mapToPixel(); xform.setMapRotation( 0, 0, 0 ); #else const QgsMapToPixel &xform = context.mapToPixel(); #endif QgsDiagramLabelFeature *dlf = dynamic_cast<QgsDiagramLabelFeature *>( label->getFeaturePart()->feature() ); QgsFeature feature; feature.setFields( mFields ); feature.setValid( true ); feature.setId( label->getFeaturePart()->featureId() ); feature.setAttributes( dlf->attributes() ); context.expressionContext().setFeature( feature ); //calculate top-left point for diagram //first, calculate the centroid of the label (accounts for PAL creating //rotated labels when we do not want to draw the diagrams rotated) double centerX = 0; double centerY = 0; for ( int i = 0; i < 4; ++i ) { centerX += label->getX( i ); centerY += label->getY( i ); } QgsPointXY outPt( centerX / 4.0, centerY / 4.0 ); //then, calculate the top left point for the diagram with this center position QgsPointXY centerPt = xform.transform( outPt.x() - label->getWidth() / 2, outPt.y() - label->getHeight() / 2 ); mSettings.renderer()->renderDiagram( feature, context, centerPt.toQPointF(), mSettings.dataDefinedProperties() ); //insert into label search tree to manipulate position interactively mEngine->results()->mLabelSearchTree->insertLabel( label, label->getFeaturePart()->featureId(), mLayerId, QString(), QFont(), true, false ); }