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