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