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