void QgsDecorationNorthArrowDialog::rotatePixmap( int theRotationInt ) { QPixmap myQPixmap; QString myFileNameQString = ":/images/north_arrows/default.png"; // QgsDebugMsg(QString("Trying to load %1").arg(myFileNameQString)); if ( myQPixmap.load( myFileNameQString ) ) { QPixmap myPainterPixmap( myQPixmap.height(), myQPixmap.width() ); myPainterPixmap.fill(); QPainter myQPainter; myQPainter.begin( &myPainterPixmap ); myQPainter.setRenderHint( QPainter::SmoothPixmapTransform ); double centerXDouble = myQPixmap.width() / 2.0; double centerYDouble = myQPixmap.height() / 2.0; //save the current canvas rotation myQPainter.save(); //myQPainter.translate( (int)centerXDouble, (int)centerYDouble ); //rotate the canvas myQPainter.rotate( theRotationInt ); //work out how to shift the image so that it appears in the center of the canvas //(x cos a + y sin a - x, -x sin a + y cos a - y) const double PI = 3.14159265358979323846; double myRadiansDouble = ( PI / 180 ) * theRotationInt; int xShift = static_cast<int>(( ( centerXDouble * cos( myRadiansDouble ) ) + ( centerYDouble * sin( myRadiansDouble ) ) ) - centerXDouble ); int yShift = static_cast<int>(( ( -centerXDouble * sin( myRadiansDouble ) ) + ( centerYDouble * cos( myRadiansDouble ) ) ) - centerYDouble ); //draw the pixmap in the proper position myQPainter.drawPixmap( xShift, yShift, myQPixmap ); //unrotate the canvas again myQPainter.restore(); myQPainter.end(); pixmapLabel->setPixmap( myPainterPixmap ); } else { QPixmap myPainterPixmap( 200, 200 ); myPainterPixmap.fill(); QPainter myQPainter; myQPainter.begin( &myPainterPixmap ); QFont myQFont( "time", 12, QFont::Bold ); myQPainter.setFont( myQFont ); myQPainter.setPen( Qt::red ); myQPainter.drawText( 10, 20, tr( "Pixmap not found" ) ); myQPainter.end(); pixmapLabel->setPixmap( myPainterPixmap ); } }
void QgsNorthArrowPlugin::renderNorthArrow( QPainter * theQPainter ) { //Large IF statement controlled by enable check box if ( mEnable ) { if ( theQPainter->isActive() ) { //QgsDebugMsg("Rendering north arrow on active painter"); } else { //QgsDebugMsg("Rendering north arrow on INactive painter!!!"); } QPixmap myQPixmap; //to store the north arrow image in QString myFileNameQString = QDir::cleanPath( QgsApplication::pkgDataPath() + "/images/north_arrows/default.png" ); //QgsDebugMsg("Trying to load " + myFileNameQString); if ( myQPixmap.load( myFileNameQString ) ) { double centerXDouble = myQPixmap.width() / 2; double centerYDouble = myQPixmap.height() / 2; //save the current canvas rotation theQPainter->save(); // //work out how to shift the image so that it rotates // properly about its center //(x cos a + y sin a - x, -x sin a + y cos a - y) // // could move this call to somewhere else so that it is only // called when the projection or map extent changes if ( mAutomatic ) calculateNorthDirection(); double myRadiansDouble = mRotationInt * PI / 180.0; int xShift = static_cast<int>(( ( centerXDouble * cos( myRadiansDouble ) ) + ( centerYDouble * sin( myRadiansDouble ) ) ) - centerXDouble ); int yShift = static_cast<int>(( ( -centerXDouble * sin( myRadiansDouble ) ) + ( centerYDouble * cos( myRadiansDouble ) ) ) - centerYDouble ); // need width/height of paint device int myHeight = theQPainter->device()->height(); int myWidth = theQPainter->device()->width(); //QgsDebugMsg("Rendering north arrow at " + mPlacementLabels.at(mPlacementIndex)); //Determine placement of label from form combo box switch ( mPlacementIndex ) { case 0: // Bottom Left theQPainter->translate( 0, myHeight - myQPixmap.height() ); break; case 1: // Top Left //no need to translate for TL corner because we're already at the origin theQPainter->translate( 0, 0 ); break; case 2: // Top Right theQPainter->translate( myWidth - myQPixmap.width(), 0 ); break; case 3: // Bottom Right theQPainter->translate( myWidth - myQPixmap.width(), myHeight - myQPixmap.height() ); break; default: { //QgsDebugMsg("Unable to determine where to put north arrow so defaulting to top left"); } } //rotate the canvas by the north arrow rotation amount theQPainter->rotate( mRotationInt ); //Now we can actually do the drawing, and draw a smooth north arrow even when rotated theQPainter->setRenderHint( QPainter::SmoothPixmapTransform ); theQPainter->drawPixmap( xShift, yShift, myQPixmap ); //unrotate the canvas again theQPainter->restore(); } else { QFont myQFont( "time", 12, QFont::Bold ); theQPainter->setFont( myQFont ); theQPainter->setPen( Qt::black ); theQPainter->drawText( 10, 20, tr( "North arrow pixmap not found" ) ); } } }
void QgsDecorationNorthArrow::render( const QgsMapSettings &mapSettings, QgsRenderContext &context ) { //Large IF statement controlled by enable checkbox if ( enabled() ) { QSize size( 64, 64 ); QSvgRenderer svg; const QByteArray &svgContent = QgsApplication::svgCache()->svgContent( QStringLiteral( ":/images/north_arrows/default.svg" ), size.width(), mColor, mOutlineColor, 1.0, 1.0 ); svg.load( svgContent ); if ( svg.isValid() ) { double centerXDouble = size.width() / 2.0; double centerYDouble = size.width() / 2.0; //save the current canvas rotation context.painter()->save(); // //work out how to shift the image so that it rotates // properly about its center //(x cos a + y sin a - x, -x sin a + y cos a - y) // // could move this call to somewhere else so that it is only // called when the projection or map extent changes if ( mAutomatic ) { mRotationInt = QgsBearingUtils:: bearingTrueNorth( mapSettings.destinationCrs(), context.extent().center() ); mRotationInt += mapSettings.rotation(); } double myRadiansDouble = mRotationInt * M_PI / 180.0; int xShift = static_cast<int>( ( ( centerXDouble * cos( myRadiansDouble ) ) + ( centerYDouble * sin( myRadiansDouble ) ) ) - centerXDouble ); int yShift = static_cast<int>( ( ( -centerXDouble * sin( myRadiansDouble ) ) + ( centerYDouble * cos( myRadiansDouble ) ) ) - centerYDouble ); // need width/height of paint device int myHeight = context.painter()->device()->height(); int myWidth = context.painter()->device()->width(); //QgsDebugMsg("Rendering north arrow at " + mPlacementLabels.at(mPlacementIndex)); // Set margin according to selected units int myXOffset = 0; int myYOffset = 0; switch ( mMarginUnit ) { case QgsUnitTypes::RenderMillimeters: { int myPixelsInchX = context.painter()->device()->logicalDpiX(); int myPixelsInchY = context.painter()->device()->logicalDpiY(); myXOffset = myPixelsInchX * INCHES_TO_MM * mMarginHorizontal; myYOffset = myPixelsInchY * INCHES_TO_MM * mMarginVertical; break; } case QgsUnitTypes::RenderPixels: myXOffset = mMarginHorizontal - 5; // Minus 5 to shift tight into corner myYOffset = mMarginVertical - 5; break; case QgsUnitTypes::RenderPercentage: myXOffset = ( ( myWidth - size.width() ) / 100. ) * mMarginHorizontal; myYOffset = ( ( myHeight - size.width() ) / 100. ) * mMarginVertical; break; default: // Use default of top left break; } //Determine placement of label from form combo box switch ( mPlacement ) { case BottomLeft: context.painter()->translate( myXOffset, myHeight - myYOffset - size.width() ); break; case TopLeft: context.painter()->translate( myXOffset, myYOffset ); break; case TopRight: context.painter()->translate( myWidth - myXOffset - size.width(), myYOffset ); break; case BottomRight: context.painter()->translate( myWidth - myXOffset - size.width(), myHeight - myYOffset - size.width() ); break; default: { //QgsDebugMsg("Unable to determine where to put north arrow so defaulting to top left"); } } //rotate the canvas by the north arrow rotation amount context.painter()->rotate( mRotationInt ); //Now we can actually do the drawing, and draw a smooth north arrow even when rotated context.painter()->translate( xShift, yShift ); svg.render( context.painter(), QRectF( 0, 0, size.width(), size.height() ) ); //unrotate the canvas again context.painter()->restore(); } else { QFont myQFont( QStringLiteral( "time" ), 12, QFont::Bold ); context.painter()->setFont( myQFont ); context.painter()->setPen( Qt::black ); context.painter()->drawText( 10, 20, tr( "North arrow pixmap not found" ) ); } } }
void QgsDecorationNorthArrowDialog::drawNorthArrow() { int rotation = spinAngle->value(); double maxLength = 64; QSvgRenderer svg; const QByteArray &svgContent = QgsApplication::svgCache()->svgContent( mDeco.svgPath(), maxLength, pbnChangeColor->color(), pbnChangeOutlineColor->color(), 1.0, 1.0 ); svg.load( svgContent ); if ( svg.isValid() ) { QSize size( maxLength, maxLength ); QRectF viewBox = svg.viewBoxF(); if ( viewBox.height() > viewBox.width() ) { size.setWidth( maxLength * viewBox.width() / viewBox.height() ); } else { size.setHeight( maxLength * viewBox.height() / viewBox.width() ); } QPixmap myPainterPixmap( maxLength, maxLength ); myPainterPixmap.fill(); QPainter myQPainter; myQPainter.begin( &myPainterPixmap ); myQPainter.setRenderHint( QPainter::SmoothPixmapTransform ); double centerXDouble = size.width() / 2.0; double centerYDouble = size.height() / 2.0; //save the current canvas rotation myQPainter.save(); myQPainter.translate( ( maxLength - size.width() ) / 2, ( maxLength - size.height() ) / 2 ); //rotate the canvas myQPainter.rotate( rotation ); //work out how to shift the image so that it appears in the center of the canvas //(x cos a + y sin a - x, -x sin a + y cos a - y) double myRadiansDouble = ( M_PI / 180 ) * rotation; int xShift = static_cast<int>( ( ( centerXDouble * std::cos( myRadiansDouble ) ) + ( centerYDouble * std::sin( myRadiansDouble ) ) ) - centerXDouble ); int yShift = static_cast<int>( ( ( -centerXDouble * std::sin( myRadiansDouble ) ) + ( centerYDouble * std::cos( myRadiansDouble ) ) ) - centerYDouble ); //draw the pixmap in the proper position myQPainter.translate( xShift, yShift ); svg.render( &myQPainter, QRectF( 0, 0, size.width(), size.height() ) ); //unrotate the canvas again myQPainter.restore(); myQPainter.end(); pixmapLabel->setPixmap( myPainterPixmap ); } else { QPixmap myPainterPixmap( 200, 200 ); myPainterPixmap.fill(); QPainter myQPainter; myQPainter.begin( &myPainterPixmap ); QFont myQFont( QStringLiteral( "time" ), 12, QFont::Bold ); myQPainter.setFont( myQFont ); myQPainter.setPen( Qt::red ); myQPainter.drawText( 10, 20, tr( "Pixmap not found" ) ); myQPainter.end(); pixmapLabel->setPixmap( myPainterPixmap ); } }
void QgsDecorationNorthArrow::render( QPainter * theQPainter ) { //Large IF statement controlled by enable check box if ( enabled() ) { QPixmap myQPixmap; //to store the north arrow image in QString myFileNameQString = ":/images/north_arrows/default.png"; if ( myQPixmap.load( myFileNameQString ) ) { double centerXDouble = myQPixmap.width() / 2.0; double centerYDouble = myQPixmap.height() / 2.0; //save the current canvas rotation theQPainter->save(); // //work out how to shift the image so that it rotates // properly about its center //(x cos a + y sin a - x, -x sin a + y cos a - y) // // could move this call to somewhere else so that it is only // called when the projection or map extent changes if ( mAutomatic ) calculateNorthDirection(); double myRadiansDouble = mRotationInt * PI / 180.0; int xShift = static_cast<int>(( ( centerXDouble * cos( myRadiansDouble ) ) + ( centerYDouble * sin( myRadiansDouble ) ) ) - centerXDouble ); int yShift = static_cast<int>(( ( -centerXDouble * sin( myRadiansDouble ) ) + ( centerYDouble * cos( myRadiansDouble ) ) ) - centerYDouble ); // need width/height of paint device int myHeight = theQPainter->device()->height(); int myWidth = theQPainter->device()->width(); //QgsDebugMsg("Rendering north arrow at " + mPlacementLabels.at(mPlacementIndex)); // Set margin according to selected units int myXOffset = 0; int myYOffset = 0; switch ( mMarginUnit ) { case QgsSymbolV2::MM: { int myPixelsInchX = theQPainter->device()->logicalDpiX(); int myPixelsInchY = theQPainter->device()->logicalDpiY(); myXOffset = myPixelsInchX * INCHES_TO_MM * mMarginHorizontal; myYOffset = myPixelsInchY * INCHES_TO_MM * mMarginVertical; break; } case QgsSymbolV2::Pixel: myXOffset = mMarginHorizontal - 5; // Minus 5 to shift tight into corner myYOffset = mMarginVertical - 5; break; case QgsSymbolV2::Percentage: myXOffset = (( myWidth - myQPixmap.width() ) / 100. ) * mMarginHorizontal; myYOffset = (( myHeight - myQPixmap.height() ) / 100. ) * mMarginVertical; break; default: // Use default of top left break; } //Determine placement of label from form combo box switch ( mPlacement ) { case BottomLeft: theQPainter->translate( myXOffset, myHeight - myYOffset - myQPixmap.height() ); break; case TopLeft: theQPainter->translate( myXOffset, myYOffset ); break; case TopRight: theQPainter->translate( myWidth - myXOffset - myQPixmap.width(), myYOffset ); break; case BottomRight: theQPainter->translate( myWidth - myXOffset - myQPixmap.width(), myHeight - myYOffset - myQPixmap.height() ); break; default: { //QgsDebugMsg("Unable to determine where to put north arrow so defaulting to top left"); } } //rotate the canvas by the north arrow rotation amount theQPainter->rotate( mRotationInt ); //Now we can actually do the drawing, and draw a smooth north arrow even when rotated theQPainter->setRenderHint( QPainter::SmoothPixmapTransform ); theQPainter->drawPixmap( xShift, yShift, myQPixmap ); //unrotate the canvas again theQPainter->restore(); } else { QFont myQFont( "time", 12, QFont::Bold ); theQPainter->setFont( myQFont ); theQPainter->setPen( Qt::black ); theQPainter->drawText( 10, 20, tr( "North arrow pixmap not found" ) ); } } }