2828#include " qgsnetworkcontentfetcher.h"
2929#include " qgssymbollayerv2utils.h"
3030#include " qgssvgcache.h"
31+ #include " qgslogger.h"
32+ #include " qgsbearingutils.h"
33+ #include " qgsmapsettings.h"
34+
3135#include < QDomDocument>
3236#include < QDomElement>
3337#include < QFileInfo>
@@ -44,6 +48,8 @@ QgsComposerPicture::QgsComposerPicture( QgsComposition *composition )
4448 , mMode( Unknown )
4549 , mPictureRotation( 0 )
4650 , mRotationMap( nullptr )
51+ , mNorthMode( GridNorth )
52+ , mNorthOffset( 0.0 )
4753 , mResizeMode( QgsComposerPicture::Zoom )
4854 , mPictureAnchor( UpperLeft )
4955 , mSvgFillColor( QColor( 255 , 255 , 255 ) )
@@ -61,6 +67,8 @@ QgsComposerPicture::QgsComposerPicture()
6167 , mMode( Unknown )
6268 , mPictureRotation( 0 )
6369 , mRotationMap( nullptr )
70+ , mNorthMode( GridNorth )
71+ , mNorthOffset( 0.0 )
6472 , mResizeMode( QgsComposerPicture::Zoom )
6573 , mPictureAnchor( UpperLeft )
6674 , mSvgFillColor( QColor( 255 , 255 , 255 ) )
@@ -419,6 +427,43 @@ void QgsComposerPicture::remotePictureLoaded()
419427 mLoaded = true ;
420428}
421429
430+ void QgsComposerPicture::updateMapRotation ()
431+ {
432+ if ( !mRotationMap )
433+ return ;
434+
435+ // take map rotation
436+ double rotation = mRotationMap ->mapRotation ();
437+
438+ // handle true north
439+ switch ( mNorthMode )
440+ {
441+ case GridNorth:
442+ break ; // nothing to do
443+
444+ case TrueNorth:
445+ {
446+ QgsPoint center = mRotationMap ->currentMapExtent ()->center ();
447+ QgsCoordinateReferenceSystem crs = mComposition ->mapSettings ().destinationCrs ();
448+
449+ try
450+ {
451+ double bearing = QgsBearingUtils::bearingTrueNorth ( crs, center );
452+ rotation += bearing;
453+ }
454+ catch ( QgsException& e )
455+ {
456+ Q_UNUSED ( e );
457+ QgsDebugMsg ( QString ( " Caught exception %1" ).arg ( e.what () ) );
458+ }
459+ break ;
460+ }
461+ }
462+
463+ rotation += mNorthOffset ;
464+ setPictureRotation ( rotation );
465+ }
466+
422467void QgsComposerPicture::loadPicture ( const QString &path )
423468{
424469 if ( path.startsWith ( " http" ) )
@@ -650,7 +695,8 @@ void QgsComposerPicture::setRotationMap( int composerMapId )
650695
651696 if ( composerMapId == -1 ) // disable rotation from map
652697 {
653- QObject::disconnect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( setPictureRotation ( double ) ) );
698+ disconnect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( updateMapRotation () ) );
699+ disconnect ( mRotationMap , SIGNAL ( extentChanged () ), this , SLOT ( updateMapRotation () ) );
654700 mRotationMap = nullptr ;
655701 }
656702
@@ -661,12 +707,14 @@ void QgsComposerPicture::setRotationMap( int composerMapId )
661707 }
662708 if ( mRotationMap )
663709 {
664- QObject::disconnect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( setPictureRotation ( double ) ) );
710+ disconnect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( updateMapRotation () ) );
711+ disconnect ( mRotationMap , SIGNAL ( extentChanged () ), this , SLOT ( updateMapRotation () ) );
665712 }
666713 mPictureRotation = map->mapRotation ();
667- QObject::connect ( map, SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( setPictureRotation ( double ) ) );
714+ connect ( map, SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( updateMapRotation () ) );
715+ connect ( map, SIGNAL ( extentChanged () ), this , SLOT ( updateMapRotation () ) );
668716 mRotationMap = map;
669- update ();
717+ updateMapRotation ();
670718 emit pictureRotationChanged ( mPictureRotation );
671719}
672720
@@ -761,6 +809,8 @@ bool QgsComposerPicture::writeXML( QDomElement& elem, QDomDocument & doc ) const
761809 {
762810 composerPictureElem.setAttribute ( " mapId" , mRotationMap ->id () );
763811 }
812+ composerPictureElem.setAttribute ( " northMode" , mNorthMode );
813+ composerPictureElem.setAttribute ( " northOffset" , mNorthOffset );
764814
765815 _writeXML ( composerPictureElem, doc );
766816 elem.appendChild ( composerPictureElem );
@@ -827,6 +877,9 @@ bool QgsComposerPicture::readXML( const QDomElement& itemElem, const QDomDocumen
827877 }
828878
829879 // rotation map
880+ mNorthMode = static_cast < NorthMode >( itemElem.attribute ( " northMode" , " 0" ).toInt () );
881+ mNorthOffset = itemElem.attribute ( " northOffset" , " 0" ).toDouble ();
882+
830883 int rotationMapId = itemElem.attribute ( " mapId" , " -1" ).toInt ();
831884 if ( rotationMapId == -1 )
832885 {
@@ -837,10 +890,12 @@ bool QgsComposerPicture::readXML( const QDomElement& itemElem, const QDomDocumen
837890
838891 if ( mRotationMap )
839892 {
840- QObject::disconnect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( setRotation ( double ) ) );
893+ disconnect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( updateMapRotation () ) );
894+ disconnect ( mRotationMap , SIGNAL ( extentChanged () ), this , SLOT ( updateMapRotation () ) );
841895 }
842896 mRotationMap = mComposition ->getComposerMapById ( rotationMapId );
843- QObject::connect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( setRotation ( double ) ) );
897+ connect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( updateMapRotation () ) );
898+ connect ( mRotationMap , SIGNAL ( extentChanged () ), this , SLOT ( updateMapRotation () ) );
844899 }
845900
846901 refreshPicture ();
@@ -861,6 +916,18 @@ int QgsComposerPicture::rotationMap() const
861916 }
862917}
863918
919+ void QgsComposerPicture::setNorthMode ( QgsComposerPicture::NorthMode mode )
920+ {
921+ mNorthMode = mode;
922+ updateMapRotation ();
923+ }
924+
925+ void QgsComposerPicture::setNorthOffset ( double offset )
926+ {
927+ mNorthOffset = offset;
928+ updateMapRotation ();
929+ }
930+
864931void QgsComposerPicture::setPictureAnchor ( QgsComposerItem::ItemPositionMode anchor )
865932{
866933 mPictureAnchor = anchor;
0 commit comments