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