QGIS API Documentation  2.9.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
qgscomposermap.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgscomposermap.cpp
3  -------------------
4  begin : January 2005
5  copyright : (C) 2005 by Radim Blazek
6  email : blazek@itc.it
7  ***************************************************************************/
8 
9 /***************************************************************************
10  * *
11  * This program is free software; you can redistribute it and/or modify *
12  * it under the terms of the GNU General Public License as published by *
13  * the Free Software Foundation; either version 2 of the License, or *
14  * (at your option) any later version. *
15  * *
16  ***************************************************************************/
17 
18 #include "qgscomposermap.h"
19 #include "qgscomposermapgrid.h"
20 #include "qgscomposermapoverview.h"
21 #include "qgscomposition.h"
22 #include "qgscomposerutils.h"
23 #include "qgslogger.h"
24 #include "qgsmaprenderer.h"
26 #include "qgsmaplayerregistry.h"
28 #include "qgsmaptopixel.h"
29 #include "qgsproject.h"
30 #include "qgsrasterlayer.h"
31 #include "qgsrendercontext.h"
32 #include "qgsscalecalculator.h"
33 #include "qgsvectorlayer.h"
34 #include "qgspallabeling.h"
35 #include "qgsexpression.h"
36 
37 #include "qgslabel.h"
38 #include "qgslabelattributes.h"
39 #include "qgssymbollayerv2utils.h" //for pointOnLineWithDistance
40 
41 #include <QGraphicsScene>
42 #include <QGraphicsView>
43 #include <QPainter>
44 #include <QSettings>
45 #include <cmath>
46 
47 QgsComposerMap::QgsComposerMap( QgsComposition *composition, int x, int y, int width, int height )
48  : QgsComposerItem( x, y, width, height, composition )
49  , mGridStack( 0 )
50  , mOverviewStack( 0 )
51  , mMapRotation( 0 )
52  , mEvaluatedMapRotation( 0 )
53  , mKeepLayerSet( false )
54  , mKeepLayerStyles( false )
55  , mUpdatesEnabled( true )
56  , mMapCanvas( 0 )
57  , mDrawCanvasItems( true )
58  , mAtlasDriven( false )
59  , mAtlasScalingMode( Auto )
60  , mAtlasMargin( 0.10 )
61 {
63 
64  mId = 0;
65  assignFreeId();
66 
67  mPreviewMode = QgsComposerMap::Rectangle;
68  mCurrentRectangle = rect();
69 
70  // Cache
71  mCacheUpdated = false;
72  mDrawing = false;
73 
74  //Offset
75  mXOffset = 0.0;
76  mYOffset = 0.0;
77 
78  //get the color for map canvas background and set map background color accordingly
79  int bgRedInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorRedPart", 255 );
80  int bgGreenInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorGreenPart", 255 );
81  int bgBlueInt = QgsProject::instance()->readNumEntry( "Gui", "/CanvasColorBluePart", 255 );
82  setBackgroundColor( QColor( bgRedInt, bgGreenInt, bgBlueInt ) );
83 
84  //calculate mExtent based on width/height ratio and map canvas extent
85  mExtent = mComposition->mapSettings().visibleExtent();
86 
87  init();
88 
89  setSceneRect( QRectF( x, y, width, height ) );
90 }
91 
93  : QgsComposerItem( 0, 0, 10, 10, composition )
94  , mGridStack( 0 )
95  , mOverviewStack( 0 )
96  , mMapRotation( 0 )
97  , mEvaluatedMapRotation( 0 )
98  , mKeepLayerSet( false )
99  , mKeepLayerStyles( false )
100  , mUpdatesEnabled( true )
101  , mMapCanvas( 0 )
102  , mDrawCanvasItems( true )
103  , mAtlasDriven( false )
104  , mAtlasScalingMode( Auto )
105  , mAtlasMargin( 0.10 )
106 {
107  //Offset
108  mXOffset = 0.0;
109  mYOffset = 0.0;
110 
112  mId = mComposition->composerMapItems().size();
113  mPreviewMode = QgsComposerMap::Rectangle;
114  mCurrentRectangle = rect();
115 
116  init();
117  updateToolTip();
118 }
119 
120 void QgsComposerMap::init()
121 {
122  mGridStack = new QgsComposerMapGridStack( this );
123  mOverviewStack = new QgsComposerMapOverviewStack( this );
124  connectUpdateSlot();
125 
126  // data defined strings
127  mDataDefinedNames.insert( QgsComposerObject::MapRotation, QString( "dataDefinedMapRotation" ) );
128  mDataDefinedNames.insert( QgsComposerObject::MapScale, QString( "dataDefinedMapScale" ) );
129  mDataDefinedNames.insert( QgsComposerObject::MapXMin, QString( "dataDefinedMapXMin" ) );
130  mDataDefinedNames.insert( QgsComposerObject::MapYMin, QString( "dataDefinedMapYMin" ) );
131  mDataDefinedNames.insert( QgsComposerObject::MapXMax, QString( "dataDefinedMapXMax" ) );
132  mDataDefinedNames.insert( QgsComposerObject::MapYMax, QString( "dataDefinedMapYMax" ) );
133  mDataDefinedNames.insert( QgsComposerObject::MapAtlasMargin, QString( "dataDefinedMapAtlasMargin" ) );
134 }
135 
136 void QgsComposerMap::updateToolTip()
137 {
138  setToolTip( tr( "Map %1" ).arg( mId ) );
139 }
140 
141 void QgsComposerMap::adjustExtentToItemShape( double itemWidth, double itemHeight, QgsRectangle& extent ) const
142 {
143  double itemWidthHeightRatio = itemWidth / itemHeight;
144  double newWidthHeightRatio = extent.width() / extent.height();
145 
146  if ( itemWidthHeightRatio <= newWidthHeightRatio )
147  {
148  //enlarge height of new extent, ensuring the map center stays the same
149  double newHeight = extent.width() / itemWidthHeightRatio;
150  double deltaHeight = newHeight - extent.height();
151  extent.setYMinimum( extent.yMinimum() - deltaHeight / 2 );
152  extent.setYMaximum( extent.yMaximum() + deltaHeight / 2 );
153  }
154  else
155  {
156  //enlarge width of new extent, ensuring the map center stays the same
157  double newWidth = itemWidthHeightRatio * extent.height();
158  double deltaWidth = newWidth - extent.width();
159  extent.setXMinimum( extent.xMinimum() - deltaWidth / 2 );
160  extent.setXMaximum( extent.xMaximum() + deltaWidth / 2 );
161  }
162 }
163 
165 {
166  delete mOverviewStack;
167  delete mGridStack;
168 }
169 
170 /* This function is called by paint() and cache() to render the map. It does not override any functions
171 from QGraphicsItem. */
172 void QgsComposerMap::draw( QPainter *painter, const QgsRectangle& extent, const QSizeF& size, double dpi, double* forceWidthScale )
173 {
174  Q_UNUSED( forceWidthScale );
175 
176  if ( !painter )
177  {
178  return;
179  }
180  if ( size.width() == 0 || size.height() == 0 )
181  {
182  //don't attempt to draw if size is invalid
183  return;
184  }
185 
186  // render
187  QgsMapRendererCustomPainterJob job( mapSettings( extent, size, dpi ), painter );
188  // Render the map in this thread. This is done because of problems
189  // with printing to printer on Windows (printing to PDF is fine though).
190  // Raster images were not displayed - see #10599
191  job.renderSynchronously();
192 }
193 
194 QgsMapSettings QgsComposerMap::mapSettings( const QgsRectangle& extent, const QSizeF& size, int dpi ) const
195 {
196  const QgsMapSettings &ms = mComposition->mapSettings();
197 
198  QgsMapSettings jobMapSettings;
199  jobMapSettings.setExtent( extent );
200  jobMapSettings.setOutputSize( size.toSize() );
201  jobMapSettings.setOutputDpi( dpi );
202  jobMapSettings.setMapUnits( ms.mapUnits() );
203  jobMapSettings.setBackgroundColor( Qt::transparent );
204  jobMapSettings.setOutputImageFormat( ms.outputImageFormat() );
205  jobMapSettings.setRotation( mEvaluatedMapRotation );
206 
207  //set layers to render
208  QStringList theLayerSet = layersToRender();
209  if ( -1 != mCurrentExportLayer )
210  {
211  //exporting with separate layers (eg, to svg layers), so we only want to render a single map layer
212  const int layerIdx = mCurrentExportLayer - ( hasBackground() ? 1 : 0 );
213  theLayerSet =
214  ( layerIdx >= 0 && layerIdx < theLayerSet.length() )
215  ? QStringList( theLayerSet[ theLayerSet.length() - layerIdx - 1 ] )
216  : QStringList(); //exporting decorations such as map frame/grid/overview, so no map layers required
217  }
218  jobMapSettings.setLayers( theLayerSet );
219  jobMapSettings.setLayerStyleOverrides( mLayerStyleOverrides );
220  jobMapSettings.setDestinationCrs( ms.destinationCrs() );
221  jobMapSettings.setCrsTransformEnabled( ms.hasCrsTransformEnabled() );
222  jobMapSettings.setFlags( ms.flags() );
223  jobMapSettings.setFlag( QgsMapSettings::DrawSelection, false );
224 
227  {
228  //if outputing composer, disable optimisations like layer simplification
229  jobMapSettings.setFlag( QgsMapSettings::UseRenderingOptimization, false );
230  }
231 
232  //update $map variable. Use QgsComposerItem's id since that is user-definable
234 
235  // composer-specific overrides of flags
236  jobMapSettings.setFlag( QgsMapSettings::ForceVectorOutput ); // force vector output (no caching of marker images etc.)
237  jobMapSettings.setFlag( QgsMapSettings::DrawEditingInfo, false );
238  jobMapSettings.setFlag( QgsMapSettings::UseAdvancedEffects, mComposition->useAdvancedEffects() ); // respect the composition's useAdvancedEffects flag
239 
240  jobMapSettings.datumTransformStore() = ms.datumTransformStore();
241 
242  return jobMapSettings;
243 }
244 
246 {
247  if ( mPreviewMode == Rectangle )
248  {
249  return;
250  }
251 
252  if ( mDrawing )
253  {
254  return;
255  }
256 
257  mDrawing = true;
258 
259  double horizontalVScaleFactor = horizontalViewScaleFactor();
260  if ( horizontalVScaleFactor < 0 )
261  {
262  //make sure scale factor is positive
263  horizontalVScaleFactor = mLastValidViewScaleFactor > 0 ? mLastValidViewScaleFactor : 1;
264  }
265 
266  const QgsRectangle &ext = *currentMapExtent();
267  double widthMM = ext.width() * mapUnitsToMM();
268  double heightMM = ext.height() * mapUnitsToMM();
269 
270  int w = widthMM * horizontalVScaleFactor;
271  int h = heightMM * horizontalVScaleFactor;
272 
273  // limit size of image for better performance
274  if ( w > 5000 || h > 5000 )
275  {
276  if ( w > h )
277  {
278  w = 5000;
279  h = w * heightMM / widthMM;
280  }
281  else
282  {
283  h = 5000;
284  w = h * widthMM / heightMM;
285  }
286  }
287 
288  mCacheImage = QImage( w, h, QImage::Format_ARGB32 );
289 
290  // set DPI of the image
291  mCacheImage.setDotsPerMeterX( 1000 * w / widthMM );
292  mCacheImage.setDotsPerMeterY( 1000 * h / heightMM );
293 
294  if ( hasBackground() )
295  {
296  //Initially fill image with specified background color. This ensures that layers with blend modes will
297  //preview correctly
298  mCacheImage.fill( backgroundColor().rgba() );
299  }
300  else
301  {
302  //no background, but start with empty fill to avoid artifacts
303  mCacheImage.fill( QColor( 255, 255, 255, 0 ).rgba() );
304  }
305 
306  QPainter p( &mCacheImage );
307 
308  draw( &p, ext, QSizeF( w, h ), mCacheImage.logicalDpiX() );
309  p.end();
310  mCacheUpdated = true;
311 
312  mDrawing = false;
313 }
314 
315 void QgsComposerMap::paint( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle, QWidget* pWidget )
316 {
317  Q_UNUSED( pWidget );
318 
319  if ( !mComposition || !painter )
320  {
321  return;
322  }
323  if ( !shouldDrawItem() )
324  {
325  return;
326  }
327 
328  QRectF thisPaintRect = QRectF( 0, 0, QGraphicsRectItem::rect().width(), QGraphicsRectItem::rect().height() );
329  painter->save();
330  painter->setClipRect( thisPaintRect );
331 
332  if ( mComposition->plotStyle() == QgsComposition::Preview && mPreviewMode == Rectangle )
333  {
334  // Fill with background color
335  drawBackground( painter );
336  QFont messageFont( "", 12 );
337  painter->setFont( messageFont );
338  painter->setPen( QColor( 0, 0, 0, 125 ) );
339  painter->drawText( thisPaintRect, tr( "Map will be printed here" ) );
340  }
342  {
343  //draw cached pixmap. This function does not call cache() any more because
344  //Qt 4.4.0 and 4.4.1 have problems with recursive paintings
345  //QgsComposerMap::cache() and QgsComposerMap::update() need to be called by
346  //client functions
347 
348  //Background color is already included in cached image, so no need to draw
349 
350  double imagePixelWidth = mCacheImage.width(); //how many pixels of the image are for the map extent?
351  double scale = rect().width() / imagePixelWidth;
352 
353  painter->save();
354 
355  painter->translate( mXOffset, mYOffset );
356  painter->scale( scale, scale );
357  painter->drawImage( 0, 0, mCacheImage );
358 
359  //restore rotation
360  painter->restore();
361 
362  //draw canvas items
363  drawCanvasItems( painter, itemStyle );
364  }
365  else if ( mComposition->plotStyle() == QgsComposition::Print ||
367  {
368  if ( mDrawing )
369  {
370  return;
371  }
372 
373  mDrawing = true;
374  QPaintDevice* thePaintDevice = painter->device();
375  if ( !thePaintDevice )
376  {
377  return;
378  }
379 
380  // Fill with background color
381  if ( shouldDrawPart( Background ) )
382  {
383  drawBackground( painter );
384  }
385 
386  QgsRectangle cExtent = *currentMapExtent();
387 
388  QSizeF theSize( cExtent.width() * mapUnitsToMM(), cExtent.height() * mapUnitsToMM() );
389 
390  painter->save();
391  painter->translate( mXOffset, mYOffset );
392 
393  double dotsPerMM = thePaintDevice->logicalDpiX() / 25.4;
394  theSize *= dotsPerMM; // output size will be in dots (pixels)
395  painter->scale( 1 / dotsPerMM, 1 / dotsPerMM ); // scale painter from mm to dots
396  draw( painter, cExtent, theSize, thePaintDevice->logicalDpiX() );
397 
398  //restore rotation
399  painter->restore();
400 
401  //draw canvas items
402  drawCanvasItems( painter, itemStyle );
403 
404  mDrawing = false;
405  }
406 
407  painter->setClipRect( thisPaintRect, Qt::NoClip );
408  if ( shouldDrawPart( OverviewMapExtent ) &&
409  ( mComposition->plotStyle() != QgsComposition::Preview || mPreviewMode != Rectangle ) )
410  {
411  mOverviewStack->drawItems( painter );
412  }
413  if ( shouldDrawPart( Grid ) &&
414  ( mComposition->plotStyle() != QgsComposition::Preview || mPreviewMode != Rectangle ) )
415  {
416  mGridStack->drawItems( painter );
417  }
418  if ( shouldDrawPart( Frame ) )
419  {
420  drawFrame( painter );
421  }
422  if ( isSelected() && shouldDrawPart( SelectionBoxes ) )
423  {
424  drawSelectionBoxes( painter );
425  }
426 
427  painter->restore();
428 }
429 
431 {
432  return
433  ( hasBackground() ? 1 : 0 )
434  + layersToRender().length()
435  + 1 // for grids, if they exist
436  + 1 // for overviews, if they exist
437  + ( hasFrame() ? 1 : 0 )
438  + ( isSelected() ? 1 : 0 )
439  ;
440 }
441 
442 bool QgsComposerMap::shouldDrawPart( PartType part ) const
443 {
444  if ( -1 == mCurrentExportLayer )
445  {
446  //all parts of the composer map are visible
447  return true;
448  }
449 
450  int idx = numberExportLayers();
451  if ( isSelected() )
452  {
453  --idx;
454  if ( SelectionBoxes == part )
455  {
456  return mCurrentExportLayer == idx;
457  }
458  }
459 
460  if ( hasFrame() )
461  {
462  --idx;
463  if ( Frame == part )
464  {
465  return mCurrentExportLayer == idx;
466  }
467  }
468  --idx;
469  if ( OverviewMapExtent == part )
470  {
471  return mCurrentExportLayer == idx;
472  }
473  --idx;
474  if ( Grid == part )
475  {
476  return mCurrentExportLayer == idx;
477  }
478  if ( hasBackground() )
479  {
480  if ( Background == part )
481  {
482  return mCurrentExportLayer == 0;
483  }
484  }
485 
486  return true; // for Layer
487 }
488 
490 {
491  syncLayerSet(); //layer list may have changed
492  mCacheUpdated = false;
493  cache();
494  QGraphicsRectItem::update();
495 }
496 
498 {
499  if ( mPreviewMode == Render )
500  {
502  }
503 }
504 
506 {
507  mCacheUpdated = u;
508 }
509 
511 {
513  return mComposition->mapRenderer();
515 }
516 
517 QStringList QgsComposerMap::layersToRender() const
518 {
519  //use stored layer set or read current set from main canvas
520  QStringList renderLayerSet;
521  if ( mKeepLayerSet )
522  {
523  renderLayerSet = mLayerSet;
524  }
525  else
526  {
527  renderLayerSet = mComposition->mapSettings().layers();
528  }
529 
530  //remove atlas coverage layer if required
531  //TODO - move setting for hiding coverage layer to map item properties
533  {
535  {
536  //hiding coverage layer
537  int removeAt = renderLayerSet.indexOf( mComposition->atlasComposition().coverageLayer()->id() );
538  if ( removeAt != -1 )
539  {
540  renderLayerSet.removeAt( removeAt );
541  }
542  }
543  }
544 
545  return renderLayerSet;
546 }
547 
548 double QgsComposerMap::scale() const
549 {
550  QgsScaleCalculator calculator;
551  calculator.setMapUnits( mComposition->mapSettings().mapUnits() );
552  calculator.setDpi( 25.4 ); //QGraphicsView units are mm
553  return calculator.calculate( *currentMapExtent(), rect().width() );
554 }
555 
556 void QgsComposerMap::resize( double dx, double dy )
557 {
558  //setRect
559  QRectF currentRect = rect();
560  QRectF newSceneRect = QRectF( pos().x(), pos().y(), currentRect.width() + dx, currentRect.height() + dy );
561  setSceneRect( newSceneRect );
562  updateItem();
563 }
564 
565 void QgsComposerMap::moveContent( double dx, double dy )
566 {
567  if ( !mDrawing )
568  {
569  transformShift( dx, dy );
570  currentMapExtent()->setXMinimum( currentMapExtent()->xMinimum() + dx );
571  currentMapExtent()->setXMaximum( currentMapExtent()->xMaximum() + dx );
572  currentMapExtent()->setYMinimum( currentMapExtent()->yMinimum() + dy );
573  currentMapExtent()->setYMaximum( currentMapExtent()->yMaximum() + dy );
574 
575  //in case data defined extents are set, these override the calculated values
576  refreshMapExtents();
577 
578  cache();
579  update();
580  emit itemChanged();
581  emit extentChanged();
582  }
583 }
584 
585 void QgsComposerMap::zoomContent( int delta, double x, double y )
586 {
587  QSettings settings;
588 
589  //read zoom mode
590  QgsComposerItem::ZoomMode zoomMode = ( QgsComposerItem::ZoomMode )settings.value( "/qgis/wheel_action", 2 ).toInt();
591  if ( zoomMode == QgsComposerItem::NoZoom )
592  {
593  //do nothing
594  return;
595  }
596 
597  double zoomFactor = settings.value( "/qgis/zoom_factor", 2.0 ).toDouble();
598  zoomFactor = delta > 0 ? zoomFactor : 1 / zoomFactor;
599 
600  zoomContent( zoomFactor, QPointF( x, y ), zoomMode );
601 }
602 
603 void QgsComposerMap::zoomContent( const double factor, const QPointF point, const ZoomMode mode )
604 {
605  if ( mDrawing )
606  {
607  return;
608  }
609 
610  if ( mode == QgsComposerItem::NoZoom )
611  {
612  //do nothing
613  return;
614  }
615 
616  //find out map coordinates of position
617  double mapX = currentMapExtent()->xMinimum() + ( point.x() / rect().width() ) * ( currentMapExtent()->xMaximum() - currentMapExtent()->xMinimum() );
618  double mapY = currentMapExtent()->yMinimum() + ( 1 - ( point.y() / rect().height() ) ) * ( currentMapExtent()->yMaximum() - currentMapExtent()->yMinimum() );
619 
620  //find out new center point
621  double centerX = ( currentMapExtent()->xMaximum() + currentMapExtent()->xMinimum() ) / 2;
622  double centerY = ( currentMapExtent()->yMaximum() + currentMapExtent()->yMinimum() ) / 2;
623 
624  if ( mode != QgsComposerItem::Zoom )
625  {
626  if ( mode == QgsComposerItem::ZoomRecenter )
627  {
628  centerX = mapX;
629  centerY = mapY;
630  }
631  else if ( mode == QgsComposerItem::ZoomToPoint )
632  {
633  centerX = mapX + ( centerX - mapX ) * ( 1.0 / factor );
634  centerY = mapY + ( centerY - mapY ) * ( 1.0 / factor );
635  }
636  }
637 
638  double newIntervalX, newIntervalY;
639 
640  if ( factor > 0 )
641  {
642  newIntervalX = ( currentMapExtent()->xMaximum() - currentMapExtent()->xMinimum() ) / factor;
643  newIntervalY = ( currentMapExtent()->yMaximum() - currentMapExtent()->yMinimum() ) / factor;
644  }
645  else //no need to zoom
646  {
647  return;
648  }
649 
650  currentMapExtent()->setXMaximum( centerX + newIntervalX / 2 );
651  currentMapExtent()->setXMinimum( centerX - newIntervalX / 2 );
652  currentMapExtent()->setYMaximum( centerY + newIntervalY / 2 );
653  currentMapExtent()->setYMinimum( centerY - newIntervalY / 2 );
654 
655  if ( mAtlasDriven && mAtlasScalingMode == Fixed && mComposition->atlasMode() != QgsComposition::AtlasOff )
656  {
657  //if map is atlas controlled and set to fixed scaling mode, then scale changes should be treated as permanant
658  //and also apply to the map's original extent (see #9602)
659  //we can't use the scaleRatio calculated earlier, as the scale can vary depending on extent for geographic coordinate systems
660  QgsScaleCalculator calculator;
661  calculator.setMapUnits( mComposition->mapSettings().mapUnits() );
662  calculator.setDpi( 25.4 ); //QGraphicsView units are mm
663  double scaleRatio = scale() / calculator.calculate( mExtent, rect().width() );
664  mExtent.scale( scaleRatio );
665  }
666 
667  //recalculate data defined scale and extents, since that may override zoom
668  refreshMapExtents();
669 
670  cache();
671  update();
672  emit itemChanged();
673  emit extentChanged();
674 }
675 
676 void QgsComposerMap::setSceneRect( const QRectF& rectangle )
677 {
678  double w = rectangle.width();
679  double h = rectangle.height();
680  //prepareGeometryChange();
681 
682  QgsComposerItem::setSceneRect( rectangle );
683 
684  //QGraphicsRectItem::update();
685  double newHeight = mExtent.width() * h / w;
686  mExtent = QgsRectangle( mExtent.xMinimum(), mExtent.yMinimum(), mExtent.xMaximum(), mExtent.yMinimum() + newHeight );
687 
688  //recalculate data defined scale and extents
689  refreshMapExtents();
690  mCacheUpdated = false;
691 
693  update();
694  emit itemChanged();
695  emit extentChanged();
696 }
697 
699 {
700  if ( *currentMapExtent() == extent )
701  {
702  return;
703  }
705 
706  //recalculate data defined scale and extents, since that may override extent
707  refreshMapExtents();
708 
709  //adjust height
710  QRectF currentRect = rect();
711 
712  double newHeight = currentRect.width() * currentMapExtent()->height() / currentMapExtent()->width();
713 
714  setSceneRect( QRectF( pos().x(), pos().y(), currentRect.width(), newHeight ) );
715  updateItem();
716 }
717 
719 {
720  QgsRectangle newExtent = extent;
721  //Make sure the width/height ratio is the same as the current composer map extent.
722  //This is to keep the map item frame size fixed
723  double currentWidthHeightRatio = currentMapExtent()->width() / currentMapExtent()->height();
724  double newWidthHeightRatio = newExtent.width() / newExtent.height();
725 
726  if ( currentWidthHeightRatio < newWidthHeightRatio )
727  {
728  //enlarge height of new extent, ensuring the map center stays the same
729  double newHeight = newExtent.width() / currentWidthHeightRatio;
730  double deltaHeight = newHeight - newExtent.height();
731  newExtent.setYMinimum( newExtent.yMinimum() - deltaHeight / 2 );
732  newExtent.setYMaximum( newExtent.yMaximum() + deltaHeight / 2 );
733  }
734  else
735  {
736  //enlarge width of new extent, ensuring the map center stays the same
737  double newWidth = currentWidthHeightRatio * newExtent.height();
738  double deltaWidth = newWidth - newExtent.width();
739  newExtent.setXMinimum( newExtent.xMinimum() - deltaWidth / 2 );
740  newExtent.setXMaximum( newExtent.xMaximum() + deltaWidth / 2 );
741  }
742 
743  if ( *currentMapExtent() == newExtent )
744  {
745  return;
746  }
747  *currentMapExtent() = newExtent;
748 
749  //recalculate data defined scale and extents, since that may override extent
750  refreshMapExtents();
751 
752  mCacheUpdated = false;
753  updateItem();
754  emit itemChanged();
755  emit extentChanged();
756 }
757 
759 {
760  if ( mAtlasFeatureExtent != extent )
761  {
762  //don't adjust size of item, instead adjust size of bounds to fit
763  QgsRectangle newExtent = extent;
764 
765  //Make sure the width/height ratio is the same as the map item size
766  double currentWidthHeightRatio = rect().width() / rect().height();
767  double newWidthHeightRatio = newExtent.width() / newExtent.height();
768 
769  if ( currentWidthHeightRatio < newWidthHeightRatio )
770  {
771  //enlarge height of new extent, ensuring the map center stays the same
772  double newHeight = newExtent.width() / currentWidthHeightRatio;
773  double deltaHeight = newHeight - newExtent.height();
774  newExtent.setYMinimum( extent.yMinimum() - deltaHeight / 2 );
775  newExtent.setYMaximum( extent.yMaximum() + deltaHeight / 2 );
776  }
777  else if ( currentWidthHeightRatio >= newWidthHeightRatio )
778  {
779  //enlarge width of new extent, ensuring the map center stays the same
780  double newWidth = currentWidthHeightRatio * newExtent.height();
781  double deltaWidth = newWidth - newExtent.width();
782  newExtent.setXMinimum( extent.xMinimum() - deltaWidth / 2 );
783  newExtent.setXMaximum( extent.xMaximum() + deltaWidth / 2 );
784  }
785 
786  mAtlasFeatureExtent = newExtent;
787  }
788 
789  //recalculate data defined scale and extents, since that may override extents
790  refreshMapExtents();
791 
792  mCacheUpdated = false;
793  emit preparedForAtlas();
794  updateItem();
795  emit itemChanged();
796  emit extentChanged();
797 }
798 
800 {
801  //non-const version
802  if ( mAtlasDriven && mComposition->atlasMode() != QgsComposition::AtlasOff )
803  {
804  //if atlas is enabled, and we are either exporting the composition or previewing the atlas, then
805  //return the current temporary atlas feature extent
806  return &mAtlasFeatureExtent;
807  }
808  else
809  {
810  //otherwise return permenant user set extent
811  return &mExtent;
812  }
813 }
814 
816 {
817  //const version
818  if ( mAtlasDriven && mComposition->atlasMode() != QgsComposition::AtlasOff )
819  {
820  //if atlas is enabled, and we are either exporting the composition or previewing the atlas, then
821  //return the current temporary atlas feature extent
822  return &mAtlasFeatureExtent;
823  }
824  else
825  {
826  //otherwise return permenant user set extent
827  return &mExtent;
828  }
829 }
830 
831 void QgsComposerMap::setNewScale( double scaleDenominator, bool forceUpdate )
832 {
833  double currentScaleDenominator = scale();
834 
835  if ( scaleDenominator == currentScaleDenominator || scaleDenominator == 0 )
836  {
837  return;
838  }
839 
840  double scaleRatio = scaleDenominator / currentScaleDenominator;
841  currentMapExtent()->scale( scaleRatio );
842 
843  if ( mAtlasDriven && mAtlasScalingMode == Fixed && mComposition->atlasMode() != QgsComposition::AtlasOff )
844  {
845  //if map is atlas controlled and set to fixed scaling mode, then scale changes should be treated as permanant
846  //and also apply to the map's original extent (see #9602)
847  //we can't use the scaleRatio calculated earlier, as the scale can vary depending on extent for geographic coordinate systems
848  QgsScaleCalculator calculator;
849  calculator.setMapUnits( mComposition->mapSettings().mapUnits() );
850  calculator.setDpi( 25.4 ); //QGraphicsView units are mm
851  scaleRatio = scaleDenominator / calculator.calculate( mExtent, rect().width() );
852  mExtent.scale( scaleRatio );
853  }
854 
855  mCacheUpdated = false;
856  if ( forceUpdate )
857  {
858  cache();
859  update();
860  emit itemChanged();
861  }
862  emit extentChanged();
863 }
864 
866 {
867  mPreviewMode = m;
868  emit itemChanged();
869 }
870 
871 void QgsComposerMap::setOffset( double xOffset, double yOffset )
872 {
873  mXOffset = xOffset;
874  mYOffset = yOffset;
875 }
876 
878 {
879  //kept for api compatibility with QGIS 2.0
880  setMapRotation( r );
881 }
882 
884 {
885  mMapRotation = r;
886  mEvaluatedMapRotation = mMapRotation;
887  emit mapRotationChanged( r );
888  emit itemChanged();
889  update();
890 }
891 
893 {
894  return valueType == QgsComposerObject::EvaluatedValue ? mEvaluatedMapRotation : mMapRotation;
895 }
896 
897 void QgsComposerMap::refreshMapExtents()
898 {
899  //data defined map extents set?
900  QVariant exprVal;
901 
902  QgsRectangle newExtent = *currentMapExtent();
903  bool useDdXMin = false;
904  bool useDdXMax = false;
905  bool useDdYMin = false;
906  bool useDdYMax = false;
907  double minXD = 0;
908  double minYD = 0;
909  double maxXD = 0;
910  double maxYD = 0;
911 
913  {
914  bool ok;
915  minXD = exprVal.toDouble( &ok );
916  QgsDebugMsg( QString( "exprVal Map XMin:%1" ).arg( minXD ) );
917  if ( ok && !exprVal.isNull() )
918  {
919  useDdXMin = true;
920  newExtent.setXMinimum( minXD );
921  }
922  }
924  {
925  bool ok;
926  minYD = exprVal.toDouble( &ok );
927  QgsDebugMsg( QString( "exprVal Map YMin:%1" ).arg( minYD ) );
928  if ( ok && !exprVal.isNull() )
929  {
930  useDdYMin = true;
931  newExtent.setYMinimum( minYD );
932  }
933  }
935  {
936  bool ok;
937  maxXD = exprVal.toDouble( &ok );
938  QgsDebugMsg( QString( "exprVal Map XMax:%1" ).arg( maxXD ) );
939  if ( ok && !exprVal.isNull() )
940  {
941  useDdXMax = true;
942  newExtent.setXMaximum( maxXD );
943  }
944  }
946  {
947  bool ok;
948  maxYD = exprVal.toDouble( &ok );
949  QgsDebugMsg( QString( "exprVal Map YMax:%1" ).arg( maxYD ) );
950  if ( ok && !exprVal.isNull() )
951  {
952  useDdYMax = true;
953  newExtent.setYMaximum( maxYD );
954  }
955  }
956 
957  if ( newExtent != *currentMapExtent() )
958  {
959  //calculate new extents to fit data defined extents
960 
961  //Make sure the width/height ratio is the same as in current map extent.
962  //This is to keep the map item frame and the page layout fixed
963  double currentWidthHeightRatio = currentMapExtent()->width() / currentMapExtent()->height();
964  double newWidthHeightRatio = newExtent.width() / newExtent.height();
965 
966  if ( currentWidthHeightRatio < newWidthHeightRatio )
967  {
968  //enlarge height of new extent, ensuring the map center stays the same
969  double newHeight = newExtent.width() / currentWidthHeightRatio;
970  double deltaHeight = newHeight - newExtent.height();
971  newExtent.setYMinimum( newExtent.yMinimum() - deltaHeight / 2 );
972  newExtent.setYMaximum( newExtent.yMaximum() + deltaHeight / 2 );
973  }
974  else
975  {
976  //enlarge width of new extent, ensuring the map center stays the same
977  double newWidth = currentWidthHeightRatio * newExtent.height();
978  double deltaWidth = newWidth - newExtent.width();
979  newExtent.setXMinimum( newExtent.xMinimum() - deltaWidth / 2 );
980  newExtent.setXMaximum( newExtent.xMaximum() + deltaWidth / 2 );
981  }
982 
983  *currentMapExtent() = newExtent;
984  }
985 
986  //now refresh scale, as this potentially overrides extents
987 
988  //data defined map scale set?
990  {
991  bool ok;
992  double scaleD = exprVal.toDouble( &ok );
993  QgsDebugMsg( QString( "exprVal Map Scale:%1" ).arg( scaleD ) );
994  if ( ok && !exprVal.isNull() )
995  {
996  setNewScale( scaleD, false );
997  newExtent = *currentMapExtent();
998  }
999  }
1000 
1001  if ( useDdXMax || useDdXMin || useDdYMax || useDdYMin )
1002  {
1003  //if only one of min/max was set for either x or y, then make sure our extent is locked on that value
1004  //as we can do this without altering the scale
1005  if ( useDdXMin && !useDdXMax )
1006  {
1007  double xMax = currentMapExtent()->xMaximum() - ( currentMapExtent()->xMinimum() - minXD );
1008  newExtent.setXMinimum( minXD );
1009  newExtent.setXMaximum( xMax );
1010  }
1011  else if ( !useDdXMin && useDdXMax )
1012  {
1013  double xMin = currentMapExtent()->xMinimum() - ( currentMapExtent()->xMaximum() - maxXD );
1014  newExtent.setXMinimum( xMin );
1015  newExtent.setXMaximum( maxXD );
1016  }
1017  if ( useDdYMin && !useDdYMax )
1018  {
1019  double yMax = currentMapExtent()->yMaximum() - ( currentMapExtent()->yMinimum() - minYD );
1020  newExtent.setYMinimum( minYD );
1021  newExtent.setYMaximum( yMax );
1022  }
1023  else if ( !useDdYMin && useDdYMax )
1024  {
1025  double yMin = currentMapExtent()->yMinimum() - ( currentMapExtent()->yMaximum() - maxYD );
1026  newExtent.setYMinimum( yMin );
1027  newExtent.setYMaximum( maxYD );
1028  }
1029 
1030  if ( newExtent != *currentMapExtent() )
1031  {
1032  *currentMapExtent() = newExtent;
1033  }
1034  }
1035 
1036  //lastly, map rotation overrides all
1037  double mapRotation = mMapRotation;
1038 
1039  //data defined map rotation set?
1041  {
1042  bool ok;
1043  double rotationD = exprVal.toDouble( &ok );
1044  QgsDebugMsg( QString( "exprVal Map Rotation:%1" ).arg( rotationD ) );
1045  if ( ok && !exprVal.isNull() )
1046  {
1047  mapRotation = rotationD;
1048  }
1049  }
1050 
1051  if ( mEvaluatedMapRotation != mapRotation )
1052  {
1053  mEvaluatedMapRotation = mapRotation;
1054  emit mapRotationChanged( mapRotation );
1055  }
1056 
1057 }
1058 
1060 {
1061  if ( !mUpdatesEnabled )
1062  {
1063  return;
1064  }
1065 
1066  if ( mPreviewMode != QgsComposerMap::Rectangle && !mCacheUpdated )
1067  {
1068  cache();
1069  }
1071 }
1072 
1074 {
1075  QStringList layers = mComposition->mapSettings().layers();
1076 
1077  QStringList::const_iterator layer_it = layers.constBegin();
1078  QgsMapLayer* currentLayer = 0;
1079 
1080  for ( ; layer_it != layers.constEnd(); ++layer_it )
1081  {
1082  currentLayer = QgsMapLayerRegistry::instance()->mapLayer( *layer_it );
1083  if ( currentLayer )
1084  {
1085  QgsRasterLayer* currentRasterLayer = qobject_cast<QgsRasterLayer *>( currentLayer );
1086  if ( currentRasterLayer )
1087  {
1088  const QgsRasterDataProvider* rasterProvider = 0;
1089  if (( rasterProvider = currentRasterLayer->dataProvider() ) )
1090  {
1091  if ( rasterProvider->name() == "wms" )
1092  {
1093  return true;
1094  }
1095  }
1096  }
1097  }
1098  }
1099  return false;
1100 }
1101 
1103 {
1104  //check easy things first
1105 
1106  //overviews
1107  if ( mOverviewStack->containsAdvancedEffects() )
1108  {
1109  return true;
1110  }
1111 
1112  //grids
1113  if ( mGridStack->containsAdvancedEffects() )
1114  {
1115  return true;
1116  }
1117 
1118  // check if map contains advanced effects like blend modes, or flattened layers for transparency
1119 
1120  QStringList layers = mComposition->mapSettings().layers();
1121 
1122  QStringList::const_iterator layer_it = layers.constBegin();
1123  QgsMapLayer* currentLayer = 0;
1124 
1125  for ( ; layer_it != layers.constEnd(); ++layer_it )
1126  {
1127  currentLayer = QgsMapLayerRegistry::instance()->mapLayer( *layer_it );
1128  if ( currentLayer )
1129  {
1130  if ( currentLayer->blendMode() != QPainter::CompositionMode_SourceOver )
1131  {
1132  return true;
1133  }
1134  // if vector layer, check labels and feature blend mode
1135  QgsVectorLayer* currentVectorLayer = qobject_cast<QgsVectorLayer *>( currentLayer );
1136  if ( currentVectorLayer )
1137  {
1138  if ( currentVectorLayer->layerTransparency() != 0 )
1139  {
1140  return true;
1141  }
1142  if ( currentVectorLayer->featureBlendMode() != QPainter::CompositionMode_SourceOver )
1143  {
1144  return true;
1145  }
1146  // check label blend modes
1147  if ( QgsPalLabeling::staticWillUseLayer( currentVectorLayer ) )
1148  {
1149  // Check all label blending properties
1150  QgsPalLayerSettings layerSettings = QgsPalLayerSettings::fromLayer( currentVectorLayer );
1151  if (( layerSettings.blendMode != QPainter::CompositionMode_SourceOver ) ||
1152  ( layerSettings.bufferSize != 0 && layerSettings.bufferBlendMode != QPainter::CompositionMode_SourceOver ) ||
1153  ( layerSettings.shadowDraw && layerSettings.shadowBlendMode != QPainter::CompositionMode_SourceOver ) ||
1154  ( layerSettings.shapeDraw && layerSettings.shapeBlendMode != QPainter::CompositionMode_SourceOver ) )
1155  {
1156  return true;
1157  }
1158  }
1159  }
1160  }
1161  }
1162 
1163  return false;
1164 }
1165 
1166 void QgsComposerMap::connectUpdateSlot()
1167 {
1168  //connect signal from layer registry to update in case of new or deleted layers
1170  if ( layerRegistry )
1171  {
1172  connect( layerRegistry, SIGNAL( layerWillBeRemoved( QString ) ), this, SLOT( updateCachedImage() ) );
1173  connect( layerRegistry, SIGNAL( layerWasAdded( QgsMapLayer* ) ), this, SLOT( updateCachedImage() ) );
1174  }
1175 }
1176 
1177 bool QgsComposerMap::writeXML( QDomElement& elem, QDomDocument & doc ) const
1178 {
1179  if ( elem.isNull() )
1180  {
1181  return false;
1182  }
1183 
1184  QDomElement composerMapElem = doc.createElement( "ComposerMap" );
1185  composerMapElem.setAttribute( "id", mId );
1186 
1187  //previewMode
1188  if ( mPreviewMode == Cache )
1189  {
1190  composerMapElem.setAttribute( "previewMode", "Cache" );
1191  }
1192  else if ( mPreviewMode == Render )
1193  {
1194  composerMapElem.setAttribute( "previewMode", "Render" );
1195  }
1196  else //rectangle
1197  {
1198  composerMapElem.setAttribute( "previewMode", "Rectangle" );
1199  }
1200 
1201  if ( mKeepLayerSet )
1202  {
1203  composerMapElem.setAttribute( "keepLayerSet", "true" );
1204  }
1205  else
1206  {
1207  composerMapElem.setAttribute( "keepLayerSet", "false" );
1208  }
1209 
1210  if ( mDrawCanvasItems )
1211  {
1212  composerMapElem.setAttribute( "drawCanvasItems", "true" );
1213  }
1214  else
1215  {
1216  composerMapElem.setAttribute( "drawCanvasItems", "false" );
1217  }
1218 
1219  //extent
1220  QDomElement extentElem = doc.createElement( "Extent" );
1221  extentElem.setAttribute( "xmin", qgsDoubleToString( mExtent.xMinimum() ) );
1222  extentElem.setAttribute( "xmax", qgsDoubleToString( mExtent.xMaximum() ) );
1223  extentElem.setAttribute( "ymin", qgsDoubleToString( mExtent.yMinimum() ) );
1224  extentElem.setAttribute( "ymax", qgsDoubleToString( mExtent.yMaximum() ) );
1225  composerMapElem.appendChild( extentElem );
1226 
1227  //map rotation
1228  composerMapElem.setAttribute( "mapRotation", QString::number( mMapRotation ) );
1229 
1230  //layer set
1231  QDomElement layerSetElem = doc.createElement( "LayerSet" );
1232  QStringList::const_iterator layerIt = mLayerSet.constBegin();
1233  for ( ; layerIt != mLayerSet.constEnd(); ++layerIt )
1234  {
1235  QDomElement layerElem = doc.createElement( "Layer" );
1236  QDomText layerIdText = doc.createTextNode( *layerIt );
1237  layerElem.appendChild( layerIdText );
1238  layerSetElem.appendChild( layerElem );
1239  }
1240  composerMapElem.appendChild( layerSetElem );
1241 
1242  // override styles
1243  if ( mKeepLayerStyles )
1244  {
1245  QDomElement stylesElem = doc.createElement( "LayerStyles" );
1246  QMap<QString, QString>::const_iterator styleIt = mLayerStyleOverrides.constBegin();
1247  for ( ; styleIt != mLayerStyleOverrides.constEnd(); ++styleIt )
1248  {
1249  QDomElement styleElem = doc.createElement( "LayerStyle" );
1250  styleElem.setAttribute( "layerid", styleIt.key() );
1251  QgsMapLayerStyle style( styleIt.value() );
1252  style.writeXml( styleElem );
1253  stylesElem.appendChild( styleElem );
1254  }
1255  composerMapElem.appendChild( stylesElem );
1256  }
1257 
1258  //write a dummy "Grid" element to prevent crashes on pre 2.5 versions (refs #10905)
1259  QDomElement gridElem = doc.createElement( "Grid" );
1260  composerMapElem.appendChild( gridElem );
1261 
1262  //grids
1263  mGridStack->writeXML( composerMapElem, doc );
1264 
1265  //overviews
1266  mOverviewStack->writeXML( composerMapElem, doc );
1267 
1268  //atlas
1269  QDomElement atlasElem = doc.createElement( "AtlasMap" );
1270  atlasElem.setAttribute( "atlasDriven", mAtlasDriven );
1271  atlasElem.setAttribute( "scalingMode", mAtlasScalingMode );
1272  atlasElem.setAttribute( "margin", qgsDoubleToString( mAtlasMargin ) );
1273  composerMapElem.appendChild( atlasElem );
1274 
1275  elem.appendChild( composerMapElem );
1276  return _writeXML( composerMapElem, doc );
1277 }
1278 
1279 bool QgsComposerMap::readXML( const QDomElement& itemElem, const QDomDocument& doc )
1280 {
1281  if ( itemElem.isNull() )
1282  {
1283  return false;
1284  }
1285 
1286  QString idRead = itemElem.attribute( "id", "not found" );
1287  if ( idRead != "not found" )
1288  {
1289  mId = idRead.toInt();
1290  updateToolTip();
1291  }
1292  mPreviewMode = Rectangle;
1293 
1294  //previewMode
1295  QString previewMode = itemElem.attribute( "previewMode" );
1296  if ( previewMode == "Cache" )
1297  {
1298  mPreviewMode = Cache;
1299  }
1300  else if ( previewMode == "Render" )
1301  {
1302  mPreviewMode = Render;
1303  }
1304  else
1305  {
1306  mPreviewMode = Rectangle;
1307  }
1308 
1309  //extent
1310  QDomNodeList extentNodeList = itemElem.elementsByTagName( "Extent" );
1311  if ( extentNodeList.size() > 0 )
1312  {
1313  QDomElement extentElem = extentNodeList.at( 0 ).toElement();
1314  double xmin, xmax, ymin, ymax;
1315  xmin = extentElem.attribute( "xmin" ).toDouble();
1316  xmax = extentElem.attribute( "xmax" ).toDouble();
1317  ymin = extentElem.attribute( "ymin" ).toDouble();
1318  ymax = extentElem.attribute( "ymax" ).toDouble();
1319  setNewExtent( QgsRectangle( xmin, ymin, xmax, ymax ) );
1320  }
1321 
1322  //map rotation
1323  if ( itemElem.attribute( "mapRotation", "0" ).toDouble() != 0 )
1324  {
1325  mMapRotation = itemElem.attribute( "mapRotation", "0" ).toDouble();
1326  }
1327 
1328  //mKeepLayerSet flag
1329  QString keepLayerSetFlag = itemElem.attribute( "keepLayerSet" );
1330  if ( keepLayerSetFlag.compare( "true", Qt::CaseInsensitive ) == 0 )
1331  {
1332  mKeepLayerSet = true;
1333  }
1334  else
1335  {
1336  mKeepLayerSet = false;
1337  }
1338 
1339  QString drawCanvasItemsFlag = itemElem.attribute( "drawCanvasItems", "true" );
1340  if ( drawCanvasItemsFlag.compare( "true", Qt::CaseInsensitive ) == 0 )
1341  {
1342  mDrawCanvasItems = true;
1343  }
1344  else
1345  {
1346  mDrawCanvasItems = false;
1347  }
1348 
1349  mLayerStyleOverrides.clear();
1350 
1351  //mLayerSet
1352  QDomNodeList layerSetNodeList = itemElem.elementsByTagName( "LayerSet" );
1353  QStringList layerSet;
1354  if ( layerSetNodeList.size() > 0 )
1355  {
1356  QDomElement layerSetElem = layerSetNodeList.at( 0 ).toElement();
1357  QDomNodeList layerIdNodeList = layerSetElem.elementsByTagName( "Layer" );
1358  for ( int i = 0; i < layerIdNodeList.size(); ++i )
1359  {
1360  const QDomElement& layerIdElement = layerIdNodeList.at( i ).toElement();
1361  layerSet << layerIdElement.text();
1362  }
1363  }
1364  mLayerSet = layerSet;
1365 
1366  // override styles
1367  QDomNodeList layerStylesNodeList = itemElem.elementsByTagName( "LayerStyles" );
1368  mKeepLayerStyles = layerStylesNodeList.size() > 0;
1369  if ( mKeepLayerStyles )
1370  {
1371  QDomElement layerStylesElem = layerStylesNodeList.at( 0 ).toElement();
1372  QDomNodeList layerStyleNodeList = layerStylesElem.elementsByTagName( "LayerStyle" );
1373  for ( int i = 0; i < layerStyleNodeList.size(); ++i )
1374  {
1375  const QDomElement& layerStyleElement = layerStyleNodeList.at( i ).toElement();
1376  QString layerId = layerStyleElement.attribute( "layerid" );
1377  QgsMapLayerStyle style;
1378  style.readXml( layerStyleElement );
1379  mLayerStyleOverrides.insert( layerId, style.xmlData() );
1380  }
1381  }
1382 
1383  mDrawing = false;
1384  mNumCachedLayers = 0;
1385  mCacheUpdated = false;
1386 
1387  //overviews
1388  mOverviewStack->readXML( itemElem, doc );
1389 
1390  //grids
1391  mGridStack->readXML( itemElem, doc );
1392 
1393  //load grid / grid annotation in old xml format
1394  //only do this if the grid stack didn't load any grids, otherwise this will
1395  //be the dummy element created by QGIS >= 2.5 (refs #10905)
1396  QDomNodeList gridNodeList = itemElem.elementsByTagName( "Grid" );
1397  if ( mGridStack->size() == 0 && gridNodeList.size() > 0 )
1398  {
1399  QDomElement gridElem = gridNodeList.at( 0 ).toElement();
1400  QgsComposerMapGrid* mapGrid = new QgsComposerMapGrid( tr( "Grid %1" ).arg( 1 ), this );
1401  mapGrid->setEnabled( gridElem.attribute( "show", "0" ) != "0" );
1402  mapGrid->setStyle( QgsComposerMapGrid::GridStyle( gridElem.attribute( "gridStyle", "0" ).toInt() ) );
1403  mapGrid->setIntervalX( gridElem.attribute( "intervalX", "0" ).toDouble() );
1404  mapGrid->setIntervalY( gridElem.attribute( "intervalY", "0" ).toDouble() );
1405  mapGrid->setOffsetX( gridElem.attribute( "offsetX", "0" ).toDouble() );
1406  mapGrid->setOffsetY( gridElem.attribute( "offsetY", "0" ).toDouble() );
1407  mapGrid->setCrossLength( gridElem.attribute( "crossLength", "3" ).toDouble() );
1408  mapGrid->setFrameStyle(( QgsComposerMapGrid::FrameStyle )gridElem.attribute( "gridFrameStyle", "0" ).toInt() );
1409  mapGrid->setFrameWidth( gridElem.attribute( "gridFrameWidth", "2.0" ).toDouble() );
1410  mapGrid->setFramePenSize( gridElem.attribute( "gridFramePenThickness", "0.5" ).toDouble() );
1411  mapGrid->setFramePenColor( QgsSymbolLayerV2Utils::decodeColor( gridElem.attribute( "framePenColor", "0,0,0" ) ) );
1412  mapGrid->setFrameFillColor1( QgsSymbolLayerV2Utils::decodeColor( gridElem.attribute( "frameFillColor1", "255,255,255,255" ) ) );
1413  mapGrid->setFrameFillColor2( QgsSymbolLayerV2Utils::decodeColor( gridElem.attribute( "frameFillColor2", "0,0,0,255" ) ) );
1414  mapGrid->setBlendMode( QgsMapRenderer::getCompositionMode(( QgsMapRenderer::BlendMode ) itemElem.attribute( "gridBlendMode", "0" ).toUInt() ) );
1415  QDomElement gridSymbolElem = gridElem.firstChildElement( "symbol" );
1416  QgsLineSymbolV2* lineSymbol = 0;
1417  if ( gridSymbolElem.isNull() )
1418  {
1419  //old project file, read penWidth /penColorRed, penColorGreen, penColorBlue
1420  lineSymbol = QgsLineSymbolV2::createSimple( QgsStringMap() );
1421  lineSymbol->setWidth( gridElem.attribute( "penWidth", "0" ).toDouble() );
1422  lineSymbol->setColor( QColor( gridElem.attribute( "penColorRed", "0" ).toInt(),
1423  gridElem.attribute( "penColorGreen", "0" ).toInt(),
1424  gridElem.attribute( "penColorBlue", "0" ).toInt() ) );
1425  }
1426  else
1427  {
1428  lineSymbol = QgsSymbolLayerV2Utils::loadSymbol<QgsLineSymbolV2>( gridSymbolElem );
1429  }
1430  mapGrid->setLineSymbol( lineSymbol );
1431 
1432  //annotation
1433  QDomNodeList annotationNodeList = gridElem.elementsByTagName( "Annotation" );
1434  if ( annotationNodeList.size() > 0 )
1435  {
1436  QDomElement annotationElem = annotationNodeList.at( 0 ).toElement();
1437  mapGrid->setAnnotationEnabled( annotationElem.attribute( "show", "0" ) != "0" );
1438  mapGrid->setAnnotationFormat( QgsComposerMapGrid::AnnotationFormat( annotationElem.attribute( "format", "0" ).toInt() ) );
1439  mapGrid->setAnnotationPosition( QgsComposerMapGrid::AnnotationPosition( annotationElem.attribute( "leftPosition", "0" ).toInt() ), QgsComposerMapGrid::Left );
1440  mapGrid->setAnnotationPosition( QgsComposerMapGrid::AnnotationPosition( annotationElem.attribute( "rightPosition", "0" ).toInt() ), QgsComposerMapGrid::Right );
1441  mapGrid->setAnnotationPosition( QgsComposerMapGrid::AnnotationPosition( annotationElem.attribute( "topPosition", "0" ).toInt() ), QgsComposerMapGrid::Top );
1442  mapGrid->setAnnotationPosition( QgsComposerMapGrid::AnnotationPosition( annotationElem.attribute( "bottomPosition", "0" ).toInt() ), QgsComposerMapGrid::Bottom );
1443  mapGrid->setAnnotationDirection( QgsComposerMapGrid::AnnotationDirection( annotationElem.attribute( "leftDirection", "0" ).toInt() ), QgsComposerMapGrid::Left );
1444  mapGrid->setAnnotationDirection( QgsComposerMapGrid::AnnotationDirection( annotationElem.attribute( "rightDirection", "0" ).toInt() ), QgsComposerMapGrid::Right );
1445  mapGrid->setAnnotationDirection( QgsComposerMapGrid::AnnotationDirection( annotationElem.attribute( "topDirection", "0" ).toInt() ), QgsComposerMapGrid::Top );
1446  mapGrid->setAnnotationDirection( QgsComposerMapGrid::AnnotationDirection( annotationElem.attribute( "bottomDirection", "0" ).toInt() ), QgsComposerMapGrid::Bottom );
1447  mapGrid->setAnnotationFrameDistance( annotationElem.attribute( "frameDistance", "0" ).toDouble() );
1448  QFont annotationFont;
1449  annotationFont.fromString( annotationElem.attribute( "font", "" ) );
1450  mapGrid->setAnnotationFont( annotationFont );
1451  mapGrid->setAnnotationFontColor( QgsSymbolLayerV2Utils::decodeColor( itemElem.attribute( "fontColor", "0,0,0,255" ) ) );
1452 
1453  mapGrid->setAnnotationPrecision( annotationElem.attribute( "precision", "3" ).toInt() );
1454  }
1455  mGridStack->addGrid( mapGrid );
1456  }
1457 
1458  //load overview in old xml format
1459  QDomElement overviewFrameElem = itemElem.firstChildElement( "overviewFrame" );
1460  if ( !overviewFrameElem.isNull() )
1461  {
1462  QgsComposerMapOverview* mapOverview = new QgsComposerMapOverview( tr( "Overview %1" ).arg( mOverviewStack->size() + 1 ), this );
1463 
1464  mapOverview->setFrameMap( overviewFrameElem.attribute( "overviewFrameMap", "-1" ).toInt() );
1465  mapOverview->setBlendMode( QgsMapRenderer::getCompositionMode(( QgsMapRenderer::BlendMode ) overviewFrameElem.attribute( "overviewBlendMode", "0" ).toUInt() ) );
1466  mapOverview->setInverted( overviewFrameElem.attribute( "overviewInverted" ).compare( "true", Qt::CaseInsensitive ) == 0 );
1467  mapOverview->setCentered( overviewFrameElem.attribute( "overviewCentered" ).compare( "true", Qt::CaseInsensitive ) == 0 );
1468 
1469  QgsFillSymbolV2* fillSymbol = 0;
1470  QDomElement overviewFrameSymbolElem = overviewFrameElem.firstChildElement( "symbol" );
1471  if ( !overviewFrameSymbolElem.isNull() )
1472  {
1473  fillSymbol = QgsSymbolLayerV2Utils::loadSymbol<QgsFillSymbolV2>( overviewFrameSymbolElem );
1474  mapOverview->setFrameSymbol( fillSymbol );
1475  }
1476  mOverviewStack->addOverview( mapOverview );
1477  }
1478 
1479  //atlas
1480  QDomNodeList atlasNodeList = itemElem.elementsByTagName( "AtlasMap" );
1481  if ( atlasNodeList.size() > 0 )
1482  {
1483  QDomElement atlasElem = atlasNodeList.at( 0 ).toElement();
1484  mAtlasDriven = ( atlasElem.attribute( "atlasDriven", "0" ) != "0" );
1485  if ( atlasElem.hasAttribute( "fixedScale" ) ) // deprecated XML
1486  {
1487  mAtlasScalingMode = ( atlasElem.attribute( "fixedScale", "0" ) != "0" ) ? Fixed : Auto;
1488  }
1489  else if ( atlasElem.hasAttribute( "scalingMode" ) )
1490  {
1491  mAtlasScalingMode = static_cast<AtlasScalingMode>( atlasElem.attribute( "scalingMode" ).toInt() );
1492  }
1493  mAtlasMargin = atlasElem.attribute( "margin", "0.1" ).toDouble();
1494  }
1495 
1496  //restore general composer item properties
1497  QDomNodeList composerItemList = itemElem.elementsByTagName( "ComposerItem" );
1498  if ( composerItemList.size() > 0 )
1499  {
1500  QDomElement composerItemElem = composerItemList.at( 0 ).toElement();
1501 
1502  if ( composerItemElem.attribute( "rotation", "0" ).toDouble() != 0 )
1503  {
1504  //in versions prior to 2.1 map rotation was stored in the rotation attribute
1505  mMapRotation = composerItemElem.attribute( "rotation", "0" ).toDouble();
1506  }
1507 
1508  _readXML( composerItemElem, doc );
1509  }
1510 
1512  emit itemChanged();
1513  return true;
1514 }
1515 
1517 {
1518  mLayerSet = mComposition->mapSettings().layers();
1519 
1520  if ( mKeepLayerStyles )
1521  {
1522  // also store styles associated with the layers
1524  }
1525 }
1526 
1528 {
1529  mLayerStyleOverrides.clear();
1530  foreach ( const QString& layerID, mLayerSet )
1531  {
1532  if ( QgsMapLayer* layer = QgsMapLayerRegistry::instance()->mapLayer( layerID ) )
1533  {
1534  QgsMapLayerStyle style;
1535  style.readFromLayer( layer );
1536  mLayerStyleOverrides.insert( layerID, style.xmlData() );
1537  }
1538  }
1539 }
1540 
1541 void QgsComposerMap::syncLayerSet()
1542 {
1543  if ( mLayerSet.size() < 1 )
1544  {
1545  return;
1546  }
1547 
1548  //if layer set is fixed, do a lookup in the layer registry to also find the non-visible layers
1549  QStringList currentLayerSet;
1550  if ( mKeepLayerSet )
1551  {
1552  currentLayerSet = QgsMapLayerRegistry::instance()->mapLayers().uniqueKeys();
1553  }
1554  else //only consider layers visible in the map
1555  {
1556  currentLayerSet = mComposition->mapSettings().layers();
1557  }
1558 
1559  for ( int i = mLayerSet.size() - 1; i >= 0; --i )
1560  {
1561  if ( !currentLayerSet.contains( mLayerSet.at( i ) ) )
1562  {
1563  mLayerStyleOverrides.remove( mLayerSet.at( i ) );
1564  mLayerSet.removeAt( i );
1565  }
1566  }
1567 }
1568 
1570 {
1571  if ( mGridStack->size() < 1 )
1572  {
1573  QgsComposerMapGrid* grid = new QgsComposerMapGrid( tr( "Grid %1" ).arg( 1 ), this );
1574  mGridStack->addGrid( grid );
1575  }
1576  return mGridStack->grid( 0 );
1577 }
1578 
1579 const QgsComposerMapGrid* QgsComposerMap::constFirstMapGrid() const
1580 {
1581  return const_cast<QgsComposerMap*>( this )->grid();
1582 }
1583 
1585 {
1586  QgsComposerMapGrid* g = grid();
1587  g->setStyle( QgsComposerMapGrid::GridStyle( style ) );
1588 }
1589 
1591 {
1592  const QgsComposerMapGrid* g = constFirstMapGrid();
1593  return ( QgsComposerMap::GridStyle )g->style();
1594 }
1595 
1596 void QgsComposerMap::setGridIntervalX( double interval )
1597 {
1598  QgsComposerMapGrid* g = grid();
1599  g->setIntervalX( interval );
1600 }
1601 
1603 {
1604  const QgsComposerMapGrid* g = constFirstMapGrid();
1605  return g->intervalX();
1606 }
1607 
1608 void QgsComposerMap::setGridIntervalY( double interval )
1609 {
1610  QgsComposerMapGrid* g = grid();
1611  g->setIntervalY( interval );
1612 }
1613 
1615 {
1616  const QgsComposerMapGrid* g = constFirstMapGrid();
1617  return g->intervalY();
1618 }
1619 
1620 void QgsComposerMap::setGridOffsetX( double offset )
1621 {
1622  QgsComposerMapGrid* g = grid();
1623  g->setOffsetX( offset );
1624 }
1625 
1627 {
1628  const QgsComposerMapGrid* g = constFirstMapGrid();
1629  return g->offsetX();
1630 }
1631 
1632 void QgsComposerMap::setGridOffsetY( double offset )
1633 {
1634  QgsComposerMapGrid* g = grid();
1635  g->setOffsetY( offset );
1636 }
1637 
1639 {
1640  const QgsComposerMapGrid* g = constFirstMapGrid();
1641  return g->offsetY();
1642 }
1643 
1645 {
1646  QgsComposerMapGrid* g = grid();
1647  g->setGridLineWidth( w );
1648 }
1649 
1650 void QgsComposerMap::setGridPenColor( const QColor& c )
1651 {
1652  QgsComposerMapGrid* g = grid();
1653  g->setGridLineColor( c );
1654 }
1655 
1656 void QgsComposerMap::setGridPen( const QPen& p )
1657 {
1658  QgsComposerMapGrid* g = grid();
1659  g->setGridLineWidth( p.widthF() );
1660  g->setGridLineColor( p.color() );
1661 }
1662 
1664 {
1665  const QgsComposerMapGrid* g = constFirstMapGrid();
1666  QPen p;
1667  if ( g->lineSymbol() )
1668  {
1669  QgsLineSymbolV2* line = dynamic_cast<QgsLineSymbolV2*>( g->lineSymbol()->clone() );
1670  if ( !line )
1671  {
1672  return p;
1673  }
1674  p.setWidthF( line->width() );
1675  p.setColor( line->color() );
1676  p.setCapStyle( Qt::FlatCap );
1677  delete line;
1678  }
1679  return p;
1680 }
1681 
1683 {
1684  QgsComposerMapGrid* g = grid();
1685  g->setAnnotationFont( f );
1686 }
1687 
1689 {
1690  const QgsComposerMapGrid* g = constFirstMapGrid();
1691  return g->annotationFont();
1692 }
1693 
1695 {
1696  QgsComposerMapGrid* g = grid();
1697  g->setAnnotationFontColor( c );
1698 }
1699 
1701 {
1702  const QgsComposerMapGrid* g = constFirstMapGrid();
1703  return g->annotationFontColor();
1704 }
1705 
1707 {
1708  QgsComposerMapGrid* g = grid();
1709  g->setAnnotationPrecision( p );
1710 }
1711 
1713 {
1714  const QgsComposerMapGrid* g = constFirstMapGrid();
1715  return g->annotationPrecision();
1716 }
1717 
1719 {
1720  QgsComposerMapGrid* g = grid();
1721  g->setAnnotationEnabled( show );
1722 }
1723 
1725 {
1726  const QgsComposerMapGrid* g = constFirstMapGrid();
1727  return g->annotationEnabled();
1728 }
1729 
1731 {
1732  QgsComposerMapGrid* g = grid();
1733  if ( p != QgsComposerMap::Disabled )
1734  {
1736  }
1737  else
1738  {
1740  }
1741 }
1742 
1744 {
1745  const QgsComposerMapGrid* g = constFirstMapGrid();
1747 }
1748 
1750 {
1751  QgsComposerMapGrid* g = grid();
1753 }
1754 
1756 {
1757  const QgsComposerMapGrid* g = constFirstMapGrid();
1758  return g->annotationFrameDistance();
1759 }
1760 
1762 {
1763  QgsComposerMapGrid* g = grid();
1764  //map grid direction to QgsComposerMapGrid direction (values are different)
1766  switch ( d )
1767  {
1769  gridDirection = QgsComposerMapGrid::Horizontal;
1770  break;
1772  gridDirection = QgsComposerMapGrid::Vertical;
1773  break;
1775  gridDirection = QgsComposerMapGrid::BoundaryDirection;
1776  break;
1777  default:
1778  gridDirection = QgsComposerMapGrid::Horizontal;
1779  }
1780  g->setAnnotationDirection( gridDirection, ( QgsComposerMapGrid::BorderSide )border );
1781 
1782 }
1783 
1785 {
1786  const QgsComposerMapGrid* g = constFirstMapGrid();
1788 }
1789 
1791 {
1792  QgsComposerMapGrid* g = grid();
1794 }
1795 
1797 {
1798  const QgsComposerMapGrid* g = constFirstMapGrid();
1800 }
1801 
1803 {
1804  QgsComposerMapGrid* g = grid();
1806 }
1807 
1809 {
1810  const QgsComposerMapGrid* g = constFirstMapGrid();
1812 }
1813 
1815 {
1816  QgsComposerMapGrid* g = grid();
1817  g->setFrameWidth( w );
1818 }
1819 
1821 {
1822  const QgsComposerMapGrid* g = constFirstMapGrid();
1823  return g->frameWidth();
1824 }
1825 
1827 {
1828  QgsComposerMapGrid* g = grid();
1829  g->setFramePenSize( w );
1830 }
1831 
1833 {
1834  const QgsComposerMapGrid* g = constFirstMapGrid();
1835  return g->framePenSize();
1836 }
1837 
1839 {
1840  QgsComposerMapGrid* g = grid();
1841  g->setFramePenColor( c );
1842 }
1843 
1845 {
1846  const QgsComposerMapGrid* g = constFirstMapGrid();
1847  return g->framePenColor();
1848 }
1849 
1851 {
1852  QgsComposerMapGrid* g = grid();
1853  g->setFrameFillColor1( c );
1854 }
1855 
1857 {
1858  const QgsComposerMapGrid* g = constFirstMapGrid();
1859  return g->frameFillColor1();
1860 }
1861 
1863 {
1864  QgsComposerMapGrid* g = grid();
1865  g->setFrameFillColor2( c );
1866 }
1867 
1869 {
1870  const QgsComposerMapGrid* g = constFirstMapGrid();
1871  return g->frameFillColor2();
1872 }
1873 
1875 {
1876  QgsComposerMapGrid* g = grid();
1877  g->setCrossLength( l );
1878 }
1879 
1881 {
1882  const QgsComposerMapGrid* g = constFirstMapGrid();
1883  return g->crossLength();
1884 }
1885 
1887 {
1888  if ( mOverviewStack->size() < 1 )
1889  {
1890  QgsComposerMapOverview* overview = new QgsComposerMapOverview( tr( "Overview %1" ).arg( 1 ), this );
1891  mOverviewStack->addOverview( overview );
1892  }
1893  return mOverviewStack->overview( 0 );
1894 }
1895 
1896 const QgsComposerMapOverview *QgsComposerMap::constFirstMapOverview() const
1897 {
1898  return const_cast<QgsComposerMap*>( this )->overview();
1899 }
1900 
1901 void QgsComposerMap::setGridBlendMode( QPainter::CompositionMode blendMode )
1902 {
1903  QgsComposerMapGrid* g = grid();
1904  g->setBlendMode( blendMode );
1905 }
1906 
1907 QPainter::CompositionMode QgsComposerMap::gridBlendMode() const
1908 {
1909  const QgsComposerMapGrid* g = constFirstMapGrid();
1910  return g->blendMode();
1911 }
1912 
1914 {
1915  return mCurrentRectangle;
1916 }
1917 
1919 {
1920  QRectF rectangle = rect();
1921  double frameExtension = mFrame ? pen().widthF() / 2.0 : 0.0;
1922  double maxGridExtension = mGridStack ? mGridStack->maxGridExtension() : 0;
1923 
1924  double maxExtension = qMax( frameExtension, maxGridExtension );
1925 
1926  rectangle.setLeft( rectangle.left() - maxExtension );
1927  rectangle.setRight( rectangle.right() + maxExtension );
1928  rectangle.setTop( rectangle.top() - maxExtension );
1929  rectangle.setBottom( rectangle.bottom() + maxExtension );
1930  if ( rectangle != mCurrentRectangle )
1931  {
1932  prepareGeometryChange();
1933  mCurrentRectangle = rectangle;
1934  }
1935 }
1936 
1938 {
1939  QgsComposerItem::setFrameOutlineWidth( outlineWidth );
1941 }
1942 
1943 QgsRectangle QgsComposerMap::transformedExtent() const
1944 {
1945  double dx = mXOffset;
1946  double dy = mYOffset;
1947  transformShift( dx, dy );
1948  return QgsRectangle( currentMapExtent()->xMinimum() - dx, currentMapExtent()->yMinimum() - dy, currentMapExtent()->xMaximum() - dx, currentMapExtent()->yMaximum() - dy );
1949 }
1950 
1952 {
1953  double dx = mXOffset;
1954  double dy = mYOffset;
1955  //qWarning("offset");
1956  //qWarning(QString::number(dx).toLocal8Bit().data());
1957  //qWarning(QString::number(dy).toLocal8Bit().data());
1958  transformShift( dx, dy );
1959  //qWarning("transformed:");
1960  //qWarning(QString::number(dx).toLocal8Bit().data());
1961  //qWarning(QString::number(dy).toLocal8Bit().data());
1962  QPolygonF poly = visibleExtentPolygon();
1963  poly.translate( -dx, -dy );
1964  return poly;
1965 }
1966 
1967 void QgsComposerMap::mapPolygon( const QgsRectangle& extent, QPolygonF& poly ) const
1968 {
1969  poly.clear();
1970  if ( mEvaluatedMapRotation == 0 )
1971  {
1972  poly << QPointF( extent.xMinimum(), extent.yMaximum() );
1973  poly << QPointF( extent.xMaximum(), extent.yMaximum() );
1974  poly << QPointF( extent.xMaximum(), extent.yMinimum() );
1975  poly << QPointF( extent.xMinimum(), extent.yMinimum() );
1976  //ensure polygon is closed by readding first point
1977  poly << QPointF( poly.at( 0 ) );
1978  return;
1979  }
1980 
1981  //there is rotation
1982  QgsPoint rotationPoint(( extent.xMaximum() + extent.xMinimum() ) / 2.0, ( extent.yMaximum() + extent.yMinimum() ) / 2.0 );
1983  double dx, dy; //x-, y- shift from rotation point to corner point
1984 
1985  //top left point
1986  dx = rotationPoint.x() - extent.xMinimum();
1987  dy = rotationPoint.y() - extent.yMaximum();
1988  QgsComposerUtils::rotate( mEvaluatedMapRotation, dx, dy );
1989  poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
1990 
1991  //top right point
1992  dx = rotationPoint.x() - extent.xMaximum();
1993  dy = rotationPoint.y() - extent.yMaximum();
1994  QgsComposerUtils::rotate( mEvaluatedMapRotation, dx, dy );
1995  poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
1996 
1997  //bottom right point
1998  dx = rotationPoint.x() - extent.xMaximum();
1999  dy = rotationPoint.y() - extent.yMinimum();
2000  QgsComposerUtils::rotate( mEvaluatedMapRotation, dx, dy );
2001  poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2002 
2003  //bottom left point
2004  dx = rotationPoint.x() - extent.xMinimum();
2005  dy = rotationPoint.y() - extent.yMinimum();
2006  QgsComposerUtils::rotate( mEvaluatedMapRotation, dx, dy );
2007  poly << QPointF( rotationPoint.x() - dx, rotationPoint.y() - dy );
2008 
2009  //ensure polygon is closed by readding first point
2010  poly << QPointF( poly.at( 0 ) );
2011 }
2012 
2014 {
2015  QPolygonF poly;
2016  mapPolygon( *currentMapExtent(), poly );
2017  return poly;
2018 }
2019 
2021 {
2022  if ( !QgsComposerItem::id().isEmpty() )
2023  {
2024  return QgsComposerItem::id();
2025  }
2026 
2027  return tr( "Map %1" ).arg( mId );
2028 }
2029 
2031 {
2032  QgsRectangle newExtent = *currentMapExtent();
2033  if ( mEvaluatedMapRotation == 0 )
2034  {
2035  extent = newExtent;
2036  }
2037  else
2038  {
2039  QPolygonF poly;
2040  mapPolygon( newExtent, poly );
2041  QRectF bRect = poly.boundingRect();
2042  extent.setXMinimum( bRect.left() );
2043  extent.setXMaximum( bRect.right() );
2044  extent.setYMinimum( bRect.top() );
2045  extent.setYMaximum( bRect.bottom() );
2046  }
2047 }
2048 
2050 {
2051  double extentWidth = currentMapExtent()->width();
2052  if ( extentWidth <= 0 )
2053  {
2054  return 1;
2055  }
2056  return rect().width() / extentWidth;
2057 }
2058 
2060 {
2062  o->setFrameMap( mapId );
2063 }
2064 
2066 {
2067  const QgsComposerMapOverview* o = constFirstMapOverview();
2068  return o->frameMapId();
2069 }
2070 
2072 {
2073  //updates data defined properties and redraws item to match
2074  if ( property == QgsComposerObject::MapRotation || property == QgsComposerObject::MapScale ||
2075  property == QgsComposerObject::MapXMin || property == QgsComposerObject::MapYMin ||
2076  property == QgsComposerObject::MapXMax || property == QgsComposerObject::MapYMax ||
2077  property == QgsComposerObject::MapAtlasMargin ||
2078  property == QgsComposerObject::AllProperties )
2079  {
2080  QgsRectangle beforeExtent = *currentMapExtent();
2081  refreshMapExtents();
2082  emit itemChanged();
2083  if ( *currentMapExtent() != beforeExtent )
2084  {
2085  emit extentChanged();
2086  }
2087  }
2088 
2089  //force redraw
2090  mCacheUpdated = false;
2091 
2093 }
2094 
2096 {
2098  o->setFrameSymbol( symbol );
2099 }
2100 
2102 {
2104  return o->frameSymbol();
2105 }
2106 
2107 QPainter::CompositionMode QgsComposerMap::overviewBlendMode() const
2108 {
2109  const QgsComposerMapOverview* o = constFirstMapOverview();
2110  return o->blendMode();
2111 }
2112 
2113 void QgsComposerMap::setOverviewBlendMode( QPainter::CompositionMode blendMode )
2114 {
2116  o->setBlendMode( blendMode );
2117 }
2118 
2120 {
2121  const QgsComposerMapOverview* o = constFirstMapOverview();
2122  return o->inverted();
2123 }
2124 
2126 {
2128  o->setInverted( inverted );
2129 }
2130 
2132 {
2133  const QgsComposerMapOverview* o = constFirstMapOverview();
2134  return o->centered();
2135 }
2136 
2138 {
2140  o->setCentered( centered );
2141  //overviewExtentChanged();
2142 }
2143 
2145 {
2146  QgsComposerMapGrid* g = grid();
2147  g->setLineSymbol( symbol );
2148 }
2149 
2151 {
2152  QgsComposerMapGrid* g = grid();
2153  return g->lineSymbol();
2154 }
2155 
2157 {
2158  QgsComposerMapGrid* g = grid();
2159  g->setEnabled( enabled );
2160 }
2161 
2163 {
2164  const QgsComposerMapGrid* g = constFirstMapGrid();
2165  return g->enabled();
2166 }
2167 
2168 void QgsComposerMap::transformShift( double& xShift, double& yShift ) const
2169 {
2170  double mmToMapUnits = 1.0 / mapUnitsToMM();
2171  double dxScaled = xShift * mmToMapUnits;
2172  double dyScaled = - yShift * mmToMapUnits;
2173 
2174  QgsComposerUtils::rotate( mEvaluatedMapRotation, dxScaled, dyScaled );
2175 
2176  xShift = dxScaled;
2177  yShift = dyScaled;
2178 }
2179 
2180 QPointF QgsComposerMap::mapToItemCoords( const QPointF& mapCoords ) const
2181 {
2182  QPolygonF mapPoly = transformedMapPolygon();
2183  if ( mapPoly.size() < 1 )
2184  {
2185  return QPointF( 0, 0 );
2186  }
2187 
2188  QgsRectangle tExtent = transformedExtent();
2189  QgsPoint rotationPoint(( tExtent.xMaximum() + tExtent.xMinimum() ) / 2.0, ( tExtent.yMaximum() + tExtent.yMinimum() ) / 2.0 );
2190  double dx = mapCoords.x() - rotationPoint.x();
2191  double dy = mapCoords.y() - rotationPoint.y();
2192  QgsComposerUtils::rotate( -mEvaluatedMapRotation, dx, dy );
2193  QgsPoint backRotatedCoords( rotationPoint.x() + dx, rotationPoint.y() + dy );
2194 
2195  QgsRectangle unrotatedExtent = transformedExtent();
2196  double xItem = rect().width() * ( backRotatedCoords.x() - unrotatedExtent.xMinimum() ) / unrotatedExtent.width();
2197  double yItem = rect().height() * ( 1 - ( backRotatedCoords.y() - unrotatedExtent.yMinimum() ) / unrotatedExtent.height() );
2198  return QPointF( xItem, yItem );
2199 }
2200 
2202 {
2203 
2204 }
2205 
2206 void QgsComposerMap::drawCanvasItems( QPainter* painter, const QStyleOptionGraphicsItem* itemStyle )
2207 {
2208  if ( !mMapCanvas || !mDrawCanvasItems )
2209  {
2210  return;
2211  }
2212 
2213  QList<QGraphicsItem*> itemList = mMapCanvas->items();
2214  if ( itemList.size() < 1 )
2215  {
2216  return;
2217  }
2218  QGraphicsItem* currentItem = 0;
2219 
2220  for ( int i = itemList.size() - 1; i >= 0; --i )
2221  {
2222  currentItem = itemList.at( i );
2223  //don't draw mapcanvasmap (has z value -10)
2224  if ( !currentItem || currentItem->data( 0 ).toString() != "AnnotationItem" )
2225  {
2226  continue;
2227  }
2228  drawCanvasItem( currentItem, painter, itemStyle );
2229  }
2230 }
2231 
2232 void QgsComposerMap::drawCanvasItem( QGraphicsItem* item, QPainter* painter, const QStyleOptionGraphicsItem* itemStyle )
2233 {
2234  if ( !item || !mMapCanvas || !item->isVisible() )
2235  {
2236  return;
2237  }
2238 
2239  painter->save();
2240  painter->setRenderHint( QPainter::Antialiasing );
2241 
2242  //determine scale factor according to graphics view dpi
2243  double scaleFactor = 1.0 / mMapCanvas->logicalDpiX() * 25.4;
2244 
2245  double itemX, itemY;
2246  QGraphicsItem* parent = item->parentItem();
2247  if ( !parent )
2248  {
2249  QPointF mapPos = composerMapPosForItem( item );
2250  itemX = mapPos.x();
2251  itemY = mapPos.y();
2252  }
2253  else //place item relative to the parent item
2254  {
2255  QPointF itemScenePos = item->scenePos();
2256  QPointF parentScenePos = parent->scenePos();
2257 
2258  QPointF mapPos = composerMapPosForItem( parent );
2259 
2260  itemX = mapPos.x() + ( itemScenePos.x() - parentScenePos.x() ) * scaleFactor;
2261  itemY = mapPos.y() + ( itemScenePos.y() - parentScenePos.y() ) * scaleFactor;
2262  }
2263  painter->translate( itemX, itemY );
2264 
2265  painter->scale( scaleFactor, scaleFactor );
2266 
2267  //a little trick to let the item know that the paint request comes from the composer
2268  item->setData( 1, "composer" );
2269  item->paint( painter, itemStyle, 0 );
2270  item->setData( 1, "" );
2271  painter->restore();
2272 }
2273 
2274 QPointF QgsComposerMap::composerMapPosForItem( const QGraphicsItem* item ) const
2275 {
2276  if ( !item || !mMapCanvas )
2277  {
2278  return QPointF( 0, 0 );
2279  }
2280 
2281  if ( currentMapExtent()->height() <= 0 || currentMapExtent()->width() <= 0 || mMapCanvas->width() <= 0 || mMapCanvas->height() <= 0 )
2282  {
2283  return QPointF( 0, 0 );
2284  }
2285 
2286  QRectF graphicsSceneRect = mMapCanvas->sceneRect();
2287  QPointF itemScenePos = item->scenePos();
2288  QgsRectangle mapRendererExtent = mComposition->mapSettings().visibleExtent();
2289 
2290  double mapX = itemScenePos.x() / graphicsSceneRect.width() * mapRendererExtent.width() + mapRendererExtent.xMinimum();
2291  double mapY = mapRendererExtent.yMaximum() - itemScenePos.y() / graphicsSceneRect.height() * mapRendererExtent.height();
2292  return mapToItemCoords( QPointF( mapX, mapY ) );
2293 }
2294 
2296 {
2297  if ( !mComposition )
2298  {
2299  return;
2300  }
2301 
2302  const QgsComposerMap* existingMap = mComposition->getComposerMapById( mId );
2303  if ( !existingMap )
2304  {
2305  return; //keep mId as it is still available
2306  }
2307 
2308  int maxId = -1;
2309  QList<const QgsComposerMap*> mapList = mComposition->composerMapItems();
2310  QList<const QgsComposerMap*>::const_iterator mapIt = mapList.constBegin();
2311  for ( ; mapIt != mapList.constEnd(); ++mapIt )
2312  {
2313  if (( *mapIt )->id() > maxId )
2314  {
2315  maxId = ( *mapIt )->id();
2316  }
2317  }
2318  mId = maxId + 1;
2319  updateToolTip();
2320 }
2321 
2322 bool QgsComposerMap::imageSizeConsideringRotation( double& width, double& height ) const
2323 {
2324  //kept for api compatibility with QGIS 2.0 - use mMapRotation
2326  return QgsComposerItem::imageSizeConsideringRotation( width, height, mEvaluatedMapRotation );
2328 }
2329 
2330 bool QgsComposerMap::cornerPointOnRotatedAndScaledRect( double& x, double& y, double width, double height ) const
2331 {
2332  //kept for api compatibility with QGIS 2.0 - use mMapRotation
2334  return QgsComposerItem::cornerPointOnRotatedAndScaledRect( x, y, width, height, mEvaluatedMapRotation );
2336 }
2337 
2338 void QgsComposerMap::sizeChangedByRotation( double& width, double& height )
2339 {
2340  //kept for api compatibility with QGIS 2.0 - use mMapRotation
2342  return QgsComposerItem::sizeChangedByRotation( width, height, mEvaluatedMapRotation );
2344 }
2345 
2347 {
2348  mAtlasDriven = enabled;
2349 
2350  if ( !enabled )
2351  {
2352  //if not enabling the atlas, we still need to refresh the map extents
2353  //so that data defined extents and scale are recalculated
2354  refreshMapExtents();
2355  }
2356 }
2357 
2359 {
2360  return mAtlasScalingMode == Fixed;
2361 }
2362 
2364 {
2365  // implicit : if set to false => auto scaling
2366  mAtlasScalingMode = fixed ? Fixed : Auto;
2367 }
2368 
2370 {
2371  if ( valueType == QgsComposerObject::EvaluatedValue )
2372  {
2373  //evaluate data defined atlas margin
2374 
2375  //start with user specified margin
2376  double margin = mAtlasMargin;
2377  QVariant exprVal;
2379  {
2380  bool ok;
2381  double ddMargin = exprVal.toDouble( &ok );
2382  QgsDebugMsg( QString( "exprVal Map Atlas Margin:%1" ).arg( ddMargin ) );
2383  if ( ok && !exprVal.isNull() )
2384  {
2385  //divide by 100 to convert to 0 -> 1.0 range
2386  margin = ddMargin / 100;
2387  }
2388  }
2389  return margin;
2390  }
2391  else
2392  {
2393  return mAtlasMargin;
2394  }
2395 }
2396 
Q_DECL_DEPRECATED void setGridFrameWidth(double w)
Set grid frame width.
void setMapUnits(QGis::UnitType mapUnits)
Set the map units.
void setStyle(const GridStyle style)
Sets the grid style, which controls how the grid is drawn over the map's contents.
void preparedForAtlas()
Is emitted when the map has been prepared for atlas rendering, just before actual rendering...
void updateItem() override
Updates item, with the possibility to do custom update for subclasses.
void addGrid(QgsComposerMapGrid *grid)
Adds a new map grid to the stack and takes ownership of the grid.
AtlasScalingMode
Scaling modes used for the serial rendering (atlas)
QgsComposition::AtlasMode atlasMode() const
Returns the current atlas mode of the composition.
const QgsDatumTransformStore & datumTransformStore() const
QColor frameFillColor1() const
Retrieves the first fill color for the grid frame.
void draw(QPainter *painter, const QgsRectangle &extent, const QSizeF &size, double dpi, double *forceWidthScale=0)
Draw to paint device.
Q_DECL_DEPRECATED bool imageSizeConsideringRotation(double &width, double &height, double rotation) const
Calculates width and hight of the picture (in mm) such that it fits into the item frame with the give...
double outlineWidth
Definition: qgssvgcache.cpp:78
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
sets destination coordinate reference system
A rectangle specified with double values.
Definition: qgsrectangle.h:35
Base class for all map layer types.
Definition: qgsmaplayer.h:49
Job implementation that renders everything sequentially using a custom painter.
void setAnnotationDirection(const AnnotationDirection direction, const BorderSide border)
Sets the direction for drawing frame annotations.
double intervalX() const
Gets the interval between grid lines in the x-direction.
void setBlendMode(const QPainter::CompositionMode mode)
Sets the blending mode used for drawing the grid.
Q_DECL_DEPRECATED GridAnnotationDirection gridAnnotationDirection(QgsComposerMap::Border border) const
Q_DECL_DEPRECATED QgsLineSymbolV2 * gridLineSymbol()
double atlasMargin(const QgsComposerObject::PropertyValueType valueType=QgsComposerObject::EvaluatedValue)
Returns the margin size (percentage) used when the map is in atlas mode.
Q_DECL_DEPRECATED void setGridIntervalY(double interval)
Sets coordinate interval in y-direction for composergrid.
Q_DECL_DEPRECATED void setOverviewCentered(bool centered)
Set the overview's centering mode.
void setLineSymbol(QgsLineSymbolV2 *symbol)
Sets the line symbol used for drawing grid lines.
GridStyle
Grid drawing style.
bool containsWMSLayer() const
True if composer map renders a WMS layer.
QgsComposerMapGrid * grid(const QString &gridId) const
Returns a reference to a grid within the stack.
Q_DECL_DEPRECATED void setGridAnnotationFormat(GridAnnotationFormat f)
Q_DECL_DEPRECATED void setGridFrameFillColor1(const QColor &c)
Sets first fill color for grid zebra frame.
bool containsAdvancedEffects() const
Returns whether any items within the stack contain advanced effects, such as blending modes...
Q_DECL_DEPRECATED double gridIntervalX() const
void setOffsetY(const double offset)
Sets the offset for grid lines in the y-direction.
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:163
double mapUnitsToMM() const
Returns the conversion factor map units -> mm.
bool hideCoverage() const
Returns true if the atlas is set to hide the coverage layer.
Q_DECL_DEPRECATED void setGridEnabled(bool enabled)
Enables a coordinate grid that is shown on top of this composermap.
const QgsLineSymbolV2 * lineSymbol() const
Gets the line symbol used for drawing grid lines.
Q_DECL_DEPRECATED double gridFramePenSize() const
void setFramePenSize(const double width)
Sets the width of the outline drawn in the grid frame.
void assignFreeId()
Sets mId to a number not yet used in the composition.
int size() const
Returns the number of items in the stack.
void setNewAtlasFeatureExtent(const QgsRectangle &extent)
Sets new Extent for the current atlas preview and changes width, height (and implicitely also scale)...
void readXml(const QDomElement &styleElement)
Read style configuration (for project file reading)
void setOffset(double xOffset, double yOffset)
Sets offset values to shift image (useful for live updates when moving item content) ...
Q_DECL_DEPRECATED QgsMapRenderer * mapRenderer()
Returns pointer to map renderer of qgis map canvas.
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:188
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
This class provides qgis with the ability to render raster datasets onto the mapcanvas.
void setOutputDpi(int dpi)
Set DPI used for conversion between real world units (e.g. mm) and pixels.
void itemChanged()
Emitted when the item changes.
void requestedExtent(QgsRectangle &extent) const
Calculates the extent to request and the yShift of the top-left point in case of rotation.
Q_DECL_DEPRECATED QColor gridFrameFillColor1() const
Get first fill color for grid zebra frame.
void addOverview(QgsComposerMapOverview *overview)
Adds a new map overview to the stack and takes ownership of the overview.
Q_DECL_DEPRECATED void connectMapOverviewSignals()
const QgsMapSettings & mapSettings() const
Return setting of QGIS map canvas.
QPainter::CompositionMode bufferBlendMode
A collection of grids which is drawn above the map content in a QgsComposerMap.
FrameStyle
Style for grid frame.
QStringList layerSet() const
Getter for stored layer set that is used if mKeepLayerSet is true.
Q_DECL_DEPRECATED void setAnnotationFontColor(const QColor &c)
Sets font color for grid annotations.
void cache()
Create cache image.
Q_DECL_DEPRECATED bool showGridAnnotation() const
bool centered() const
Returns whether the extent of the map is forced to center on the overview.
Q_DECL_DEPRECATED void setGridStyle(GridStyle style)
Sets coordinate grid style to solid or cross.
Q_DECL_DEPRECATED bool imageSizeConsideringRotation(double &width, double &height) const
Calculates width and hight of the picture (in mm) such that it fits into the item frame with the give...
QList< const QgsComposerMap * > composerMapItems() const
Returns pointers to all composer maps in the scene.
QMap< QgsComposerObject::DataDefinedProperty, QString > mDataDefinedNames
Map of data defined properties for the item to string name to use when exporting item to xml...
static QgsMapLayerRegistry * instance()
Definition: qgssingleton.h:23
A item that forms part of a map composition.
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:461
Border
Enum for different frame borders.
QgsRectangle visibleExtent() const
Return the actual extent derived from requested extent that takes takes output image size into accoun...
double annotationFrameDistance() const
Gets the distance between the map frame and annotations.
void setDpi(double dpi)
Set the dpi to be used in scale calculations.
double mLastValidViewScaleFactor
Backup to restore item appearance if no view scale factor is available.
QColor frameFillColor2() const
Retrieves the second fill color for the grid frame.
void drawItems(QPainter *painter)
Draws the items from the stack on a specified painter.
bool hasCrsTransformEnabled() const
returns true if projections are enabled for this layer set
void mapRotationChanged(double newRotation)
Is emitted on rotation change to notify north arrow pictures.
static QgsPalLayerSettings fromLayer(QgsVectorLayer *layer)
FrameStyle frameStyle() const
Gets the grid frame style.
static QColor decodeColor(QString str)
virtual void drawFrame(QPainter *p)
Draw black frame around item.
void updateCachedImage()
Called if map canvas has changed.
void setAnnotationFont(const QFont &font)
Sets the font used for drawing grid annotations.
Flags flags() const
Return combination of flags used for rendering.
DataDefinedProperty
Data defined properties for different item types.
Q_DECL_DEPRECATED double annotationFrameDistance() const
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Set map of map layer style overrides (key: layer ID, value: style name) where a different style shoul...
QColor framePenColor() const
Retrieves the color of the outline drawn in the grid frame.
Q_DECL_DEPRECATED bool cornerPointOnRotatedAndScaledRect(double &x, double &y, double width, double height) const
Calculates corner point after rotation and scaling.
QPolygonF transformedMapPolygon() const
Returns extent that considers rotation and shift with mOffsetX / mOffsetY.
QColor backgroundColor() const
Gets the background color for this item.
A non GUI class for rendering a map layer set onto a QPainter.
AnnotationDirection
Direction of grid annotations.
void setLayers(const QStringList &layers)
Set list of layer IDs for map rendering.
Enable layer transparency and blending effects.
void setGridLineColor(const QColor &color)
Sets color of grid lines.
Q_DECL_DEPRECATED double gridOffsetX() const
bool containsAdvancedEffects() const
True if composer map contains layers with blend modes or flattened layers for vectors.
AnnotationFormat annotationFormat() const
Gets the format for drawing grid annotations.
QMap< QString, QString > QgsStringMap
Definition: qgis.h:438
void setAnnotationDisplay(const DisplayMode display, const BorderSide border)
Sets what types of grid annotations should be drawn for a specified side of the map frame...
Q_DECL_DEPRECATED GridFrameStyle gridFrameStyle() const
AnnotationFormat
Format for displaying grid annotations.
int readNumEntry(const QString &scope, const QString &key, int def=0, bool *ok=0) const
Q_DECL_DEPRECATED void zoomContent(int delta, double x, double y) override
Zoom content of map.
double x() const
Definition: qgspoint.h:126
AnnotationPosition annotationPosition(const BorderSide border) const
Gets the position for the grid annotations on a specified side of the map frame.
Q_DECL_DEPRECATED void setGridPenColor(const QColor &c)
Sets the color of the grid pen.
virtual QString name() const =0
return a provider name
void setWidth(double width)
double intervalY() const
Gets the interval between grid lines in the y-direction.
void setCrossLength(const double length)
Sets the length of the cross segments drawn for the grid.
QFont annotationFont() const
Gets the font used for drawing grid annotations.
bool dataDefinedEvaluate(const QgsComposerObject::DataDefinedProperty property, QVariant &expressionValue)
Evaluate a data defined property and return the calculated value.
Vector graphics should not be cached and drawn as raster images.
void setFlag(Flag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
Q_DECL_DEPRECATED void setGridAnnotationPrecision(int p)
Sets coordinate precision for grid annotations.
Q_DECL_DEPRECATED QFont gridAnnotationFont() const
The QgsMapSettings class contains configuration for rendering of the map.
Q_DECL_DEPRECATED bool overviewInverted() const
Returns true if the overview frame is inverted.
bool _readXML(const QDomElement &itemElem, const QDomDocument &doc)
Reads parameter that are not subclass specific in document.
static bool staticWillUseLayer(QgsVectorLayer *layer)
called to find out whether the layer is used for labeling
void readFromLayer(QgsMapLayer *layer)
Store layer's active style information in the instance.
void zoomToExtent(const QgsRectangle &extent)
Zooms the map so that the specified extent is fully visible within the map item.
Q_DECL_DEPRECATED const QgsMapRenderer * mapRenderer() const
Q_DECL_DEPRECATED QPainter::CompositionMode gridBlendMode() const
Returns the grid's blending mode.
void storeCurrentLayerSet()
Stores the current layer set of the qgis mapcanvas in mLayerSet.
virtual void setFrameOutlineWidth(const double outlineWidth) override
Sets frame outline width.
void setColor(const QColor &color)
Stores style information (renderer, transparency, labeling, diagrams etc.) applicable to a map layer...
Q_DECL_DEPRECATED QColor gridFrameFillColor2() const
Get second fill color for grid zebra frame.
Q_DECL_DEPRECATED int overviewFrameMapId() const
Returns id of overview frame (or -1 if no overfiew frame)
double scale() const
Scale.
Q_DECL_DEPRECATED double gridFrameWidth() const
QPainter::CompositionMode blendMode() const
Read blend mode for layer.
double horizontalViewScaleFactor() const
Returns the zoom factor of the graphics view.
An individual overview which is drawn above the map content in a QgsComposerMap, and shows the extent...
void setFrameSymbol(QgsFillSymbolV2 *symbol)
Sets the fill symbol used for drawing the overview extent.
QPainter::CompositionMode featureBlendMode() const
Read blend mode for layer.
double calculate(const QgsRectangle &mapExtent, int canvasWidth)
Calculate the scale denominator.
QgsFillSymbolV2 * frameSymbol()
Gets the fill symbol used for drawing the overview extent.
void updateBoundingRect()
Updates the bounding rect of this item.
Q_DECL_DEPRECATED void setGridAnnotationFont(const QFont &f)
Sets font for grid annotations.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:193
QPainter::CompositionMode blendMode() const
Retrieves the blending mode used for drawing the overview.
Q_DECL_DEPRECATED QColor annotationFontColor() const
Get font color for grid annotations.
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:178
virtual void updateItem()
Updates item, with the possibility to do custom update for subclasses.
virtual void drawSelectionBoxes(QPainter *p)
Draws additional graphics on selected items.
void setRotation(double degrees)
Set the rotation of the resulting map image Units are clockwise degrees.
static QgsLineSymbolV2 * createSimple(const QgsStringMap &properties)
Create a line symbol with one symbol layer: SimpleLine with specified properties. ...
QPainter::CompositionMode blendMode
friend class QgsComposerMapOverview
void setNewScale(double scaleDenominator, bool forceUpdate=true)
Sets new scale and changes only mExtent.
bool mFrame
True if item fram needs to be painted.
Q_DECL_DEPRECATED QPainter::CompositionMode overviewBlendMode() const
Returns the overview's blending mode.
Whether vector selections should be shown in the rendered map.
void setMapUnits(QGis::UnitType u)
Set units of map's geographical coordinates - used for scale calculation.
const QgsComposition * composition() const
Returns the composition the item is attached to.
bool drawCanvasItems() const
void setCacheUpdated(bool u=false)
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:168
virtual void setEnabled(const bool enabled)
Controls whether the item will be drawn.
Q_DECL_DEPRECATED void setAnnotationFrameDistance(double d)
Sets distance between map frame and annotations.
void setAnnotationFormat(const AnnotationFormat format)
Sets the format for drawing grid annotations.
bool readXML(const QDomElement &elem, const QDomDocument &doc) override
Sets the grid stack's state from a DOM document.
AnnotationPosition
Position for grid annotations.
double offsetX() const
Gets the offset for grid lines in the x-direction.
void setCentered(const bool centered)
Sets whether the extent of the map is forced to center on the overview.
void setAnnotationEnabled(const bool enabled)
Sets whether annotations should be shown for the grid.
void setNewExtent(const QgsRectangle &extent)
Sets new extent for the map.
Q_DECL_DEPRECATED void setGridPen(const QPen &p)
Sets the pen to draw composer grid.
Q_DECL_DEPRECATED void setGridFrameFillColor2(const QColor &c)
Sets second fill color for grid zebra frame.
Q_DECL_DEPRECATED void setGridIntervalX(double interval)
Sets coordinate interval in x-direction for composergrid.
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
Definition: qgsmaplayer.cpp:98
GridStyle style() const
Gets the grid's style, which controls how the grid is drawn over the map's contents.
PropertyValueType
Specifies whether the value returned by a function should be the original, user set value...
Q_DECL_DEPRECATED bool atlasFixedScale() const
Returns true if the map uses a fixed scale when in atlas mode.
QGis::UnitType mapUnits() const
Get units of map's geographical coordinates - used for scale calculation.
void moveContent(double dx, double dy) override
Move content of map.
An individual grid which is drawn above the map content in a QgsComposerMap.
QPainter::CompositionMode shapeBlendMode
bool shouldDrawItem() const
Returns whether the item should be drawn in the current context.
void setOutputImageFormat(QImage::Format format)
sets format of internal QImage
Q_DECL_DEPRECATED void sizeChangedByRotation(double &width, double &height)
Calculates width / height of the bounding box of a rotated rectangle.
Q_DECL_DEPRECATED void setOverviewFrameMapSymbol(QgsFillSymbolV2 *symbol)
double offsetY() const
Gets the offset for grid lines in the y-direction.
Q_DECL_DEPRECATED void setGridFramePenSize(double w)
Set grid frame pen thickness.
void setGridLineWidth(const double width)
Sets width of grid lines.
double mapRotation(QgsComposerObject::PropertyValueType valueType=QgsComposerObject::EvaluatedValue) const
Returns the rotation used for drawing the map within the composer item.
double framePenSize() const
Retrieves the width of the outline drawn in the grid frame.
PreviewMode
Preview style.
Q_DECL_DEPRECATED GridAnnotationPosition gridAnnotationPosition(QgsComposerMap::Border border) const
QPolygonF visibleExtentPolygon() const
Returns a polygon representing the current visible map extent, considering map extents and rotation...
A class to represent a point.
Definition: qgspoint.h:63
void setFrameWidth(const double width)
Sets the grid frame width.
void setAnnotationFontColor(const QColor &color)
Sets the font color used for drawing grid annotations.
Graphics scene for map printing.
Q_DECL_DEPRECATED QColor gridFramePenColor() const
Get pen color for grid frame.
This class tracks map layers that are currently loaded and provides a means to fetch a pointer to a m...
Object representing map window.
BlendMode
Blending modes enum defining the available composition modes that can be used when rendering a layer...
Enable drawing of vertex markers for layers in editing mode.
static void rotate(const double angle, double &x, double &y)
Rotates a point / vector around the origin.
Q_DECL_DEPRECATED QPen gridPen() const
QgsRectangle * currentMapExtent()
Returns a pointer to the current map extent, which is either the original user specified extent or th...
QString xmlData() const
Return XML content of the style.
void paint(QPainter *painter, const QStyleOptionGraphicsItem *itemStyle, QWidget *pWidget) override
Reimplementation of QCanvasItem::paint - draw on canvas.
void renderModeUpdateCachedImage()
Call updateCachedImage if item is in render mode.
BorderSide
Border sides for annotations.
QString qgsDoubleToString(const double &a, const int &precision=17)
Definition: qgis.h:339
PreviewMode previewMode() const
void setFrameFillColor1(const QColor &color)
Sets the first fill color used for the grid frame.
void setFramePenColor(const QColor &color)
Sets the color of the outline drawn in the grid frame.
void setAnnotationPosition(const AnnotationPosition position, const BorderSide border)
Sets the position for the grid annotations on a specified side of the map frame.
virtual ~QgsComposerMap()
Q_DECL_DEPRECATED int gridAnnotationPrecision() const
Q_DECL_DEPRECATED void setGridAnnotationDirection(GridAnnotationDirection d, QgsComposerMap::Border border)
bool readXML(const QDomElement &itemElem, const QDomDocument &doc) override
sets state from Dom document
Calculates scale for a given combination of canvas size, map extent, and monitor dpi.
Q_DECL_DEPRECATED void setCrossLength(double l)
Sets length of the cross segments (if grid style is cross)
int layerTransparency() const
Read transparency for layer.
Q_DECL_DEPRECATED bool gridEnabled() const
static QPainter::CompositionMode getCompositionMode(const QgsMapRenderer::BlendMode &blendMode)
Returns a QPainter::CompositionMode corresponding to a BlendMode.
int annotationPrecision() const
Returns the coordinate precision for grid annotations.
virtual void setFrameOutlineWidth(const double outlineWidth)
Sets frame outline width.
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:462
bool useAdvancedEffects() const
Returns true if a composition should use advanced effects such as blend modes.
QPainter::CompositionMode blendMode() const
Retrieves the blending mode used for drawing the grid.
QgsComposition * mComposition
virtual bool enabled() const
Returns whether the item will be drawn.
void setBackgroundColor(const QColor &color)
Set the background color of the map.
QColor annotationFontColor() const
Gets the font color used for drawing grid annotations.
void writeXml(QDomElement &styleElement) const
Write style configuration (for project file writing)
QgsComposerMapOverview * overview(const QString &overviewId) const
Returns a reference to an overview within the stack.
Q_DECL_DEPRECATED bool cornerPointOnRotatedAndScaledRect(double &x, double &y, double width, double height, double rotation) const
Calculates corner point after rotation and scaling.
int numberExportLayers() const override
Get the number of layers that this item requires for exporting as layers.
void setBackgroundColor(const QColor &backgroundColor)
Sets the background color for this item.
Q_DECL_DEPRECATED void setOverviewInverted(bool inverted)
Sets the overview's inversion mode.
bool _writeXML(QDomElement &itemElem, QDomDocument &doc) const
Writes parameter that are not subclass specific in document.
int mCurrentExportLayer
The layer that needs to be exported.
virtual void refreshDataDefinedProperty(const QgsComposerObject::DataDefinedProperty property=QgsComposerObject::AllProperties) override
Refreshes a data defined property for the item by reevaluating the property's value and redrawing the...
QgsRectangle extent() const
virtual QString displayName() const override
Get item display name.
void setOutputSize(const QSize &size)
Set the size of the resulting map image.
void setYMaximum(double y)
Set the maximum y value.
Definition: qgsrectangle.h:173
virtual bool writeXML(QDomElement &elem, QDomDocument &doc) const
Stores the state of the item stack in a DOM node.
virtual void drawBackground(QPainter *p)
Draw background.
bool hasFrame() const
Whether this item has a frame or not.
QImage::Format outputImageFormat() const
format of internal QImage, default QImage::Format_ARGB32_Premultiplied
Q_DECL_DEPRECATED void setShowGridAnnotation(bool show)
Sets flag if grid annotation should be shown.
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:351
void setExtent(const QgsRectangle &rect)
Set coordinates of the rectangle which should be rendered.
void setMapRotation(double r)
Sets rotation for the map - this does not affect the composer item shape, only the way the map is dra...
virtual void setSceneRect(const QRectF &rectangle)
Sets this items bound in scene coordinates such that 1 item size units corresponds to 1 scene size un...
void setAnnotationPrecision(const int precision)
Sets the coordinate precision for grid annotations.
Q_DECL_DEPRECATED void setGridAnnotationPosition(GridAnnotationPosition p, QgsComposerMap::Border border)
Q_DECL_DEPRECATED double gridIntervalY() const
bool hasBackground() const
Whether this item has a Background or not.
void setIntervalY(const double interval)
Sets the interval between grid lines in the y-direction.
const QMap< QString, QgsMapLayer * > & mapLayers()
Retrieve the mapLayers collection (mainly intended for use by projection)
bool annotationEnabled() const
Gets whether annotations are shown for the grid.
QgsComposerMap(QgsComposition *composition, int x, int y, int width, int height)
Constructor.
void setInverted(const bool inverted)
Sets whether the overview frame is inverted, ie, whether the shaded area is drawn outside the extent ...
Q_DECL_DEPRECATED void setAtlasFixedScale(bool fixed)
Set to true if the map should use a fixed scale when in atlas mode.
void setFrameMap(const int mapId)
Sets overview frame map.
void resize(double dx, double dy)
resizes an item in x- and y direction (canvas coordinates)
void setSceneRect(const QRectF &rectangle) override
Sets new scene rectangle bounds and recalculates hight and extent.
Q_DECL_DEPRECATED void setRotation(double r) override
Sets rotation for the map - this does not affect the composer item shape, only the way the map is dra...
double y() const
Definition: qgspoint.h:134
double crossLength() const
Retrieves the length of the cross segments drawn for the grid.
virtual void refreshDataDefinedProperty(const QgsComposerObject::DataDefinedProperty property=QgsComposerObject::AllProperties) override
QStringList layers() const
Get list of layer IDs for map rendering The layers are stored in the reverse order of how they are re...
QgsAtlasComposition & atlasComposition()
Q_DECL_DEPRECATED double crossLength()
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
Q_DECL_DEPRECATED double gridOffsetY() const
Q_DECL_DEPRECATED void setGridOffsetX(double offset)
Sets x-coordinate offset for composer grid.
Enable vector simplification and other rendering optimizations.
QPainter::CompositionMode shadowBlendMode
QgsRasterDataProvider * dataProvider()
Returns the data provider.
Q_DECL_DEPRECATED QgsFillSymbolV2 * overviewFrameMapSymbol()
Q_DECL_DEPRECATED void setOverviewBlendMode(QPainter::CompositionMode blendMode)
Sets the overview's blending mode.
QgsVectorLayer * coverageLayer() const
Returns the coverage layer used for the atlas features.
Q_DECL_DEPRECATED void setGridLineSymbol(QgsLineSymbolV2 *symbol)
void extentChanged()
Q_DECL_DEPRECATED void setGridPenWidth(double w)
Sets width of grid pen.
static void setSpecialColumn(const QString &name, QVariant value)
Assign a special column.
void setAtlasDriven(bool enabled)
Sets whether the map extent will follow the current atlas feature.
double maxGridExtension() const
Calculates the maximum distance grids within the stack extend beyond the QgsComposerMap's item rect...
void setFrameFillColor2(const QColor &color)
Sets the second fill color used for the grid frame.
void setFrameStyle(const FrameStyle style)
Sets the grid frame style.
Q_DECL_DEPRECATED void setGridOffsetY(double offset)
Sets y-coordinate offset for composer grid.
QPointF mapToItemCoords(const QPointF &mapCoords) const
Transforms map coordinates to item coordinates (considering rotation and move offset) ...
const QgsComposerMap * getComposerMapById(const int id) const
Returns the composer map with specified id.
void setPreviewMode(PreviewMode m)
QgsComposition::PlotStyle plotStyle() const
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:198
AnnotationDirection annotationDirection(const BorderSide border) const
Gets the direction for drawing frame annotations.
QRectF boundingRect() const override
In case of annotations, the bounding rectangle can be larger than the map item rectangle.
bool writeXML(QDomElement &elem, QDomDocument &doc) const override
stores state in Dom node
Represents a vector layer which manages a vector based data sets.
void storeCurrentLayerStyles()
Stores the current layer styles into style overrides.
double size
Definition: qgssvgcache.cpp:77
Q_DECL_DEPRECATED void setGridFrameStyle(GridFrameStyle style)
Set grid frame style (NoGridFrame or Zebra)
virtual QgsSymbolV2 * clone() const override
void setFlags(Flags flags)
Set combination of flags that will be used for rendering.
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:183
ZoomMode
Modes for zooming item content.
Q_DECL_DEPRECATED GridAnnotationFormat gridAnnotationFormat() const
void renderSynchronously()
Render the map synchronously in this thread.
void setIntervalX(const double interval)
Sets the interval between grid lines in the x-direction.
int frameMapId() const
Returns id of source map.
bool readXML(const QDomElement &elem, const QDomDocument &doc) override
Sets the overview stack's state from a DOM document.
void setOffsetX(const double offset)
Sets the offset for grid lines in the x-direction.
Q_DECL_DEPRECATED void setGridBlendMode(QPainter::CompositionMode blendMode)
Sets the grid's blending mode.
Q_DECL_DEPRECATED void setOverviewFrameMap(int mapId)
Sets overview frame map.
void setBlendMode(const QPainter::CompositionMode blendMode)
Sets the blending mode used for drawing the overview.
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:158
QgsComposerMapGrid * grid()
Returns the map item's first grid.
Q_DECL_DEPRECATED void setGridFramePenColor(const QColor &c)
Sets pen color for grid frame.
void setAnnotationFrameDistance(const double distance)
Sets the distance between the map frame and annotations.
Q_DECL_DEPRECATED void sizeChangedByRotation(double &width, double &height, double rotation)
Calculates width / height of the bounding box of a rotated rectangle.
double frameWidth() const
Gets the grid frame width.
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:203
void setCrsTransformEnabled(bool enabled)
sets whether to use projections for this layer set
Q_DECL_DEPRECATED GridStyle gridStyle() const
Base class for raster data providers.
QColor color() const
QgsMapSettings mapSettings(const QgsRectangle &extent, const QSizeF &size, int dpi) const
Return map settings that would be used for drawing of the map.
bool inverted() const
Returns whether the overview frame is inverted, ie, whether the shaded area is drawn outside the exte...
QgsComposerMapOverview * overview()
Returns the map item's first overview.
#define tr(sourceText)
void scale(double scaleFactor, const QgsPoint *c=0)
Scale the rectangle around its center point.
Q_DECL_DEPRECATED bool overviewCentered() const
Returns true if the extent is forced to center on the overview.
A collection of overviews which are drawn above the map content in a QgsComposerMap.
QString id() const
Get item's id (which is not necessarly unique)