2929#include " qgssymbollayerutils.h"
3030#include " qgssvgcache.h"
3131#include " qgslogger.h"
32+ #include " qgsbearingutils.h"
33+ #include " qgsmapsettings.h"
3234
3335#include < QDomDocument>
3436#include < QDomElement>
@@ -46,6 +48,8 @@ QgsComposerPicture::QgsComposerPicture( QgsComposition *composition )
4648 , mMode( Unknown )
4749 , mPictureRotation( 0 )
4850 , mRotationMap( nullptr )
51+ , mNorthMode( GridNorth )
52+ , mNorthOffset( 0.0 )
4953 , mResizeMode( QgsComposerPicture::Zoom )
5054 , mPictureAnchor( UpperLeft )
5155 , mSvgFillColor( QColor( 255 , 255 , 255 ) )
@@ -63,6 +67,8 @@ QgsComposerPicture::QgsComposerPicture()
6367 , mMode( Unknown )
6468 , mPictureRotation( 0 )
6569 , mRotationMap( nullptr )
70+ , mNorthMode( GridNorth )
71+ , mNorthOffset( 0.0 )
6672 , mResizeMode( QgsComposerPicture::Zoom )
6773 , mPictureAnchor( UpperLeft )
6874 , mSvgFillColor( QColor( 255 , 255 , 255 ) )
@@ -408,6 +414,43 @@ void QgsComposerPicture::remotePictureLoaded()
408414 mLoaded = true ;
409415}
410416
417+ void QgsComposerPicture::updateMapRotation ()
418+ {
419+ if ( !mRotationMap )
420+ return ;
421+
422+ // take map rotation
423+ double rotation = mRotationMap ->mapRotation ();
424+
425+ // handle true north
426+ switch ( mNorthMode )
427+ {
428+ case GridNorth:
429+ break ; // nothing to do
430+
431+ case TrueNorth:
432+ {
433+ QgsPoint center = mRotationMap ->currentMapExtent ()->center ();
434+ QgsCoordinateReferenceSystem crs = mComposition ->mapSettings ().destinationCrs ();
435+
436+ try
437+ {
438+ double bearing = QgsBearingUtils::bearingTrueNorth ( crs, center );
439+ rotation += bearing;
440+ }
441+ catch ( QgsException& e )
442+ {
443+ Q_UNUSED ( e );
444+ QgsDebugMsg ( QString ( " Caught exception %1" ).arg ( e.what () ) );
445+ }
446+ break ;
447+ }
448+ }
449+
450+ rotation += mNorthOffset ;
451+ setPictureRotation ( rotation );
452+ }
453+
411454void QgsComposerPicture::loadPicture ( const QString &path )
412455{
413456 if ( path.startsWith ( " http" ) )
@@ -633,7 +676,8 @@ void QgsComposerPicture::setRotationMap( int composerMapId )
633676
634677 if ( composerMapId == -1 ) // disable rotation from map
635678 {
636- QObject::disconnect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( setPictureRotation ( double ) ) );
679+ disconnect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( updateMapRotation () ) );
680+ disconnect ( mRotationMap , SIGNAL ( extentChanged () ), this , SLOT ( updateMapRotation () ) );
637681 mRotationMap = nullptr ;
638682 }
639683
@@ -644,10 +688,12 @@ void QgsComposerPicture::setRotationMap( int composerMapId )
644688 }
645689 if ( mRotationMap )
646690 {
647- QObject::disconnect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( setPictureRotation ( double ) ) );
691+ disconnect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( updateMapRotation () ) );
692+ disconnect ( mRotationMap , SIGNAL ( extentChanged () ), this , SLOT ( updateMapRotation () ) );
648693 }
649694 mPictureRotation = map->mapRotation ();
650- QObject::connect ( map, SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( setPictureRotation ( double ) ) );
695+ connect ( map, SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( updateMapRotation () ) );
696+ connect ( map, SIGNAL ( extentChanged () ), this , SLOT ( updateMapRotation () ) );
651697 mRotationMap = map;
652698 update ();
653699 emit pictureRotationChanged ( mPictureRotation );
@@ -722,6 +768,8 @@ bool QgsComposerPicture::writeXml( QDomElement& elem, QDomDocument & doc ) const
722768 {
723769 composerPictureElem.setAttribute ( " mapId" , mRotationMap ->id () );
724770 }
771+ composerPictureElem.setAttribute ( " northMode" , mNorthMode );
772+ composerPictureElem.setAttribute ( " northOffset" , mNorthOffset );
725773
726774 _writeXml ( composerPictureElem, doc );
727775 elem.appendChild ( composerPictureElem );
@@ -788,6 +836,9 @@ bool QgsComposerPicture::readXml( const QDomElement& itemElem, const QDomDocumen
788836 }
789837
790838 // rotation map
839+ mNorthMode = static_cast < NorthMode >( itemElem.attribute ( " northMode" , " 0" ).toInt () );
840+ mNorthOffset = itemElem.attribute ( " northOffset" , " 0" ).toDouble ();
841+
791842 int rotationMapId = itemElem.attribute ( " mapId" , " -1" ).toInt ();
792843 if ( rotationMapId == -1 )
793844 {
@@ -798,10 +849,12 @@ bool QgsComposerPicture::readXml( const QDomElement& itemElem, const QDomDocumen
798849
799850 if ( mRotationMap )
800851 {
801- QObject::disconnect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( setRotation ( double ) ) );
852+ disconnect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( updateMapRotation () ) );
853+ disconnect ( mRotationMap , SIGNAL ( extentChanged () ), this , SLOT ( updateMapRotation () ) );
802854 }
803855 mRotationMap = mComposition ->getComposerMapById ( rotationMapId );
804- QObject::connect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( setRotation ( double ) ) );
856+ connect ( mRotationMap , SIGNAL ( mapRotationChanged ( double ) ), this , SLOT ( updateMapRotation () ) );
857+ connect ( mRotationMap , SIGNAL ( extentChanged () ), this , SLOT ( updateMapRotation () ) );
805858 }
806859
807860 refreshPicture ();
@@ -822,6 +875,18 @@ int QgsComposerPicture::rotationMap() const
822875 }
823876}
824877
878+ void QgsComposerPicture::setNorthMode ( QgsComposerPicture::NorthMode mode )
879+ {
880+ mNorthMode = mode;
881+ updateMapRotation ();
882+ }
883+
884+ void QgsComposerPicture::setNorthOffset ( double offset )
885+ {
886+ mNorthOffset = offset;
887+ updateMapRotation ();
888+ }
889+
825890void QgsComposerPicture::setPictureAnchor ( QgsComposerItem::ItemPositionMode anchor )
826891{
827892 mPictureAnchor = anchor;
0 commit comments