diff --git a/src/app/composer/qgscomposer.cpp b/src/app/composer/qgscomposer.cpp index b69f4ce4a875..e8875a635a33 100644 --- a/src/app/composer/qgscomposer.cpp +++ b/src/app/composer/qgscomposer.cpp @@ -1315,6 +1315,7 @@ void QgsComposer::addComposerMap( QgsComposerMap* map ) return; } + map->setMapCanvas( mapCanvas() ); //set canvas to composer map to have the possibility to draw canvas items QgsComposerMapWidget* mapWidget = new QgsComposerMapWidget( map ); connect( this, SIGNAL( zoomLevelChanged() ), map, SLOT( renderModeUpdateCachedImage() ) ); mItemWidgetMap.insert( map, mapWidget ); diff --git a/src/core/composer/qgscomposermap.cpp b/src/core/composer/qgscomposermap.cpp index e2799ab507db..54038703bdc8 100644 --- a/src/core/composer/qgscomposermap.cpp +++ b/src/core/composer/qgscomposermap.cpp @@ -34,6 +34,7 @@ #include "qgslabelattributes.h" #include +#include #include #include #include @@ -42,7 +43,7 @@ QgsComposerMap::QgsComposerMap( QgsComposition *composition, int x, int y, int width, int height ) : QgsComposerItem( x, y, width, height, composition ), mKeepLayerSet( false ), mGridEnabled( false ), mGridStyle( Solid ), \ mGridIntervalX( 0.0 ), mGridIntervalY( 0.0 ), mGridOffsetX( 0.0 ), mGridOffsetY( 0.0 ), mGridAnnotationPrecision( 3 ), mShowGridAnnotation( false ), \ - mGridAnnotationPosition( OutsideMapFrame ), mAnnotationFrameDistance( 1.0 ), mGridAnnotationDirection( Horizontal ), mCrossLength( 3 ) + mGridAnnotationPosition( OutsideMapFrame ), mAnnotationFrameDistance( 1.0 ), mGridAnnotationDirection( Horizontal ), mCrossLength( 3 ), mMapCanvas( 0 ) { mComposition = composition; mId = mComposition->composerMapItems().size(); @@ -73,7 +74,7 @@ QgsComposerMap::QgsComposerMap( QgsComposition *composition, int x, int y, int w QgsComposerMap::QgsComposerMap( QgsComposition *composition ) : QgsComposerItem( 0, 0, 10, 10, composition ), mKeepLayerSet( false ), mGridEnabled( false ), mGridStyle( Solid ), \ mGridIntervalX( 0.0 ), mGridIntervalY( 0.0 ), mGridOffsetX( 0.0 ), mGridOffsetY( 0.0 ), mGridAnnotationPrecision( 3 ), mShowGridAnnotation( false ), \ - mGridAnnotationPosition( OutsideMapFrame ), mAnnotationFrameDistance( 1.0 ), mGridAnnotationDirection( Horizontal ), mCrossLength( 3 ) + mGridAnnotationPosition( OutsideMapFrame ), mAnnotationFrameDistance( 1.0 ), mGridAnnotationDirection( Horizontal ), mCrossLength( 3 ), mMapCanvas( 0 ) { //Offset mXOffset = 0.0; @@ -257,14 +258,19 @@ void QgsComposerMap::paint( QPainter* painter, const QStyleOptionGraphicsItem* i double yTopLeftShift = ( mExtent.yMaximum() - rotationPoint.y() ) * mapUnitsToMM(); painter->save(); - //painter->scale( scale, scale ); + painter->translate( mXOffset, mYOffset ); painter->translate( xTopLeftShift, yTopLeftShift ); painter->rotate( mRotation ); painter->translate( xShiftMM, -yShiftMM ); painter->scale( scale, scale ); painter->drawImage( 0, 0, mCacheImage ); + + //restore rotation painter->restore(); + + //draw canvas items + //drawCanvasItems( painter, itemStyle ); } else if ( mComposition->plotStyle() == QgsComposition::Print || mComposition->plotStyle() == QgsComposition::Postscript ) @@ -300,8 +306,13 @@ void QgsComposerMap::paint( QPainter* painter, const QStyleOptionGraphicsItem* i painter->rotate( mRotation ); painter->translate( xShiftMM, -yShiftMM ); draw( painter, requestRectangle, theSize, 25.4 ); //scene coordinates seem to be in mm + + //restore rotation painter->restore(); + //draw canvas items + //drawCanvasItems( painter, itemStyle ); + mDrawing = false; } @@ -1388,3 +1399,93 @@ QgsComposerMap::Border QgsComposerMap::borderForLineCoord( const QPointF& p ) co return Bottom; } } + +void QgsComposerMap::drawCanvasItems( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle ) +{ + if ( !mMapCanvas ) + { + return; + } + + QList itemList = mMapCanvas->items(); + + int nItems = itemList.size(); + + QList::iterator itemIt = itemList.begin(); + for ( ; itemIt != itemList.end(); ++itemIt ) + { + //don't draw mapcanvasmap (has z value -10) + if ( !( *itemIt ) || ( *itemIt )->zValue() == -10 ) + { + continue; + } + drawCanvasItem( *itemIt, painter, itemStyle ); + } +} + +void QgsComposerMap::drawCanvasItem( QGraphicsItem* item, QPainter* painter, const QStyleOptionGraphicsItem* itemStyle ) +{ + if ( !item || !mMapCanvas || !mMapRenderer ) + { + return; + } + + painter->save(); + + //only for debugging + double itemPosX = item->scenePos().x(); + double itemPosY = item->scenePos().y(); + double cWidth = mMapCanvas->width(); + double cHeight = mMapCanvas->height(); + QgsRectangle rendererExtent = mMapRenderer->extent(); + QgsRectangle composerMapExtent = mExtent; + + //determine scale factor according to graphics view dpi + double scaleFactor = 1.0 / mMapCanvas->logicalDpiX() * 25.4; + + double itemX, itemY; + QGraphicsItem* parent = item->parentItem(); + if ( !parent ) + { + QPointF mapPos = composerMapPosForItem( item ); + itemX = mapPos.x(); + itemY = mapPos.y(); + } + else //place item relative to the parent item + { + QPointF itemScenePos = item->scenePos(); + QPointF parentScenePos = parent->scenePos(); + + QPointF mapPos = composerMapPosForItem( parent ); + + itemX = mapPos.x() + ( itemScenePos.x() - parentScenePos.x() ) * scaleFactor; + itemY = mapPos.y() + ( itemScenePos.y() - parentScenePos.y() ) * scaleFactor; + } + painter->translate( itemX, itemY ); + + + painter->scale( scaleFactor, scaleFactor ); + + item->paint( painter, itemStyle, 0 ); + painter->restore(); +} + +QPointF QgsComposerMap::composerMapPosForItem( const QGraphicsItem* item ) const +{ + if ( !item || !mMapCanvas || !mMapRenderer ) + { + return QPointF( 0, 0 ); + } + + if ( mExtent.height() <= 0 || mExtent.width() <= 0 || mMapCanvas->width() <= 0 || mMapCanvas->height() <= 0 ) + { + return QPointF( 0, 0 ); + } + + double mapX = item->scenePos().x() / mMapCanvas->width() * mMapRenderer->extent().width() + mMapRenderer->extent().xMinimum(); + double mapY = mMapRenderer->extent().yMaximum() - item->scenePos().y() / mMapCanvas->height() * mMapRenderer->extent().height(); + + double itemX = rect().width() * ( mapX - mExtent.xMinimum() ) / mExtent.width(); + double itemY = rect().height() * ( mExtent.yMaximum() - mapY ) / mExtent.height(); + return QPointF( itemX, itemY ); +} diff --git a/src/core/composer/qgscomposermap.h b/src/core/composer/qgscomposermap.h index 85c8b6cccfb3..2a70cf00f7e7 100644 --- a/src/core/composer/qgscomposermap.h +++ b/src/core/composer/qgscomposermap.h @@ -27,6 +27,7 @@ class QgsMapRenderer; class QgsMapToPixel; class QDomNode; class QDomDocument; +class QGraphicsView; class QPainter; /** \ingroup MapComposer @@ -245,6 +246,9 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem void setMapRotation( double r ); + /**Sets canvas pointer (necessary to query and draw map canvas items)*/ + void setMapCanvas( QGraphicsView* canvas ) { mMapCanvas = canvas; } + public slots: /**Called if map canvas has changed*/ @@ -341,6 +345,7 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem QRectF mCurrentRectangle; /**The length of the cross sides for mGridStyle Cross*/ double mCrossLength; + QGraphicsView* mMapCanvas; /**Draws the map grid*/ void drawGrid( QPainter* p ); @@ -381,6 +386,10 @@ class CORE_EXPORT QgsComposerMap : public QgsComposerItem QPointF mapToItemCoords( const QPointF& mapCoords ) const; /**Returns the item border of a point (in item coordinates)*/ Border borderForLineCoord( const QPointF& p ) const; + + void drawCanvasItems( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle ); + void drawCanvasItem( QGraphicsItem* item, QPainter* painter, const QStyleOptionGraphicsItem* itemStyle ); + QPointF composerMapPosForItem( const QGraphicsItem* item ) const; }; #endif