QGIS API Documentation  2.11.0-Master
qgsmapcanvas.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsmapcanvas.cpp - description
3  -------------------
4 begin : Sun Jun 30 2002
5 copyright : (C) 2002 by Gary E.Sherman
6 email : sherman at mrcc.com
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 
19 #include <QtGlobal>
20 #include <QApplication>
21 #include <QCursor>
22 #include <QDir>
23 #include <QFile>
24 #include <QGraphicsItem>
25 #include <QGraphicsScene>
26 #include <QGraphicsView>
27 #include <QKeyEvent>
28 #include <QMouseEvent>
29 #include <QPainter>
30 #include <QPaintEvent>
31 #include <QPixmap>
32 #include <QRect>
33 #include <QSettings>
34 #include <QTextStream>
35 #include <QResizeEvent>
36 #include <QString>
37 #include <QStringList>
38 #include <QWheelEvent>
39 
40 #include "qgis.h"
41 #include "qgsapplication.h"
42 #include "qgscrscache.h"
44 #include "qgslogger.h"
45 #include "qgsmapcanvas.h"
46 #include "qgsmapcanvasmap.h"
48 #include "qgsmaplayer.h"
49 #include "qgsmaplayerregistry.h"
50 #include "qgsmaptoolpan.h"
51 #include "qgsmaptoolzoom.h"
52 #include "qgsmaptopixel.h"
53 #include "qgsmapoverviewcanvas.h"
54 #include "qgsmaprenderer.h"
55 #include "qgsmaprenderercache.h"
59 #include "qgsmessagelog.h"
60 #include "qgsmessageviewer.h"
61 #include "qgspallabeling.h"
62 #include "qgsproject.h"
63 #include "qgsrubberband.h"
64 #include "qgsvectorlayer.h"
65 #include <math.h>
66 
67 
70 {
71  public:
72 
74 
77 
80 
83 
86 };
87 
88 
90  : QObject( canvas )
91  , mCanvas( canvas )
92  , mRenderer( renderer )
93  , mSyncingExtent( false )
94 {
95  connect( mCanvas, SIGNAL( extentsChanged() ), this, SLOT( onExtentC2R() ) );
96  connect( mRenderer, SIGNAL( extentsChanged() ), this, SLOT( onExtentR2C() ) );
97 
98  connect( mCanvas, SIGNAL( mapUnitsChanged() ), this, SLOT( onMapUnitsC2R() ) );
99  connect( mRenderer, SIGNAL( mapUnitsChanged() ), this, SLOT( onMapUnitsR2C() ) );
100 
101  connect( mCanvas, SIGNAL( rotationChanged( double ) ), this, SLOT( onMapRotationC2R() ) );
102  connect( mRenderer, SIGNAL( rotationChanged( double ) ), this, SLOT( onMapRotationR2C() ) );
103 
104  connect( mCanvas, SIGNAL( hasCrsTransformEnabledChanged( bool ) ), this, SLOT( onCrsTransformC2R() ) );
105  connect( mRenderer, SIGNAL( hasCrsTransformEnabled( bool ) ), this, SLOT( onCrsTransformR2C() ) );
106 
107  connect( mCanvas, SIGNAL( destinationCrsChanged() ), this, SLOT( onDestCrsC2R() ) );
108  connect( mRenderer, SIGNAL( destinationSrsChanged() ), this, SLOT( onDestCrsR2C() ) );
109 
110  connect( mCanvas, SIGNAL( layersChanged() ), this, SLOT( onLayersC2R() ) );
111  // TODO: layers R2C ? (should not happen!)
112 
113 }
114 
116 {
117  // protection against possible bounce back
118  if ( mSyncingExtent )
119  return;
120 
121  mSyncingExtent = true;
123  mSyncingExtent = false;
124 }
125 
127 {
128  // protection against possible bounce back
129  if ( mSyncingExtent )
130  return;
131 
132  mSyncingExtent = true;
134  mSyncingExtent = false;
135 }
136 
138 {
140 }
141 
143 {
145 }
146 
148 {
150 }
151 
153 {
155 }
156 
158 {
160 }
161 
163 {
165 }
166 
168 {
170 }
171 
173 {
175 }
176 
178 {
180 }
181 
182 
183 
184 QgsMapCanvas::QgsMapCanvas( QWidget * parent, const char *name )
185  : QGraphicsView( parent )
186  , mCanvasProperties( new CanvasProperties )
187  , mJob( 0 )
188  , mJobCancelled( false )
189  , mLabelingResults( 0 )
190  , mUseParallelRendering( false )
191  , mDrawRenderingStats( false )
192  , mCache( 0 )
193  , mPreviewEffect( 0 )
194  , mSnappingUtils( 0 )
195 {
196  setObjectName( name );
197  mScene = new QGraphicsScene();
198  setScene( mScene );
199  setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
200  setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
201  mLastExtentIndex = -1;
202  mCurrentLayer = NULL;
203  mMapOverview = NULL;
204  mMapTool = NULL;
205  mLastNonZoomMapTool = NULL;
206 
207  mFrozen = false;
208  mRefreshScheduled = false;
209 
211 
212  // by default, the canvas is rendered
213  mRenderFlag = true;
214 
215  setMouseTracking( true );
216  setFocusPolicy( Qt::StrongFocus );
217 
218  mMapRenderer = new QgsMapRenderer;
219 
220  mResizeTimer = new QTimer( this );
221  mResizeTimer->setSingleShot( true );
222  connect( mResizeTimer, SIGNAL( timeout() ), this, SLOT( refresh() ) );
223 
224  // create map canvas item which will show the map
225  mMap = new QgsMapCanvasMap( this );
226 
227  // project handling
228  connect( QgsProject::instance(), SIGNAL( readProject( const QDomDocument & ) ),
229  this, SLOT( readProject( const QDomDocument & ) ) );
231  this, SLOT( writeProject( QDomDocument & ) ) );
232 
235 
236  // class that will sync most of the changes between canvas and (legacy) map renderer
237  // it is parented to map canvas, will be deleted automatically
238  new QgsMapCanvasRendererSync( this, mMapRenderer );
239 
240  QSize s = viewport()->size();
241  mSettings.setOutputSize( s );
242  mMapRenderer->setOutputSize( s, mSettings.outputDpi() );
243  setSceneRect( 0, 0, s.width(), s.height() );
244  mScene->setSceneRect( QRectF( 0, 0, s.width(), s.height() ) );
245 
246  moveCanvasContents( true );
247 
248  connect( &mMapUpdateTimer, SIGNAL( timeout() ), SLOT( mapUpdateTimeout() ) );
249  mMapUpdateTimer.setInterval( 250 );
250 
251 #ifdef Q_OS_WIN
252  // Enable touch event on Windows.
253  // Qt on Windows needs to be told it can take touch events or else it ignores them.
254  grabGesture( Qt::PinchGesture );
255  viewport()->setAttribute( Qt::WA_AcceptTouchEvents );
256 #endif
257 
258  mPreviewEffect = new QgsPreviewEffect( this );
259  viewport()->setGraphicsEffect( mPreviewEffect );
260 
261  setInteractive( false );
262 
263  refresh();
264 
265 } // QgsMapCanvas ctor
266 
267 
269 {
270  if ( mMapTool )
271  {
272  mMapTool->deactivate();
273  mMapTool = NULL;
274  }
275  mLastNonZoomMapTool = NULL;
276 
277  // delete canvas items prior to deleteing the canvas
278  // because they might try to update canvas when it's
279  // already being destructed, ends with segfault
280  QList<QGraphicsItem*> list = mScene->items();
282  while ( it != list.end() )
283  {
284  QGraphicsItem* item = *it;
285  delete item;
286  ++it;
287  }
288 
289  mScene->deleteLater(); // crashes in python tests on windows
290 
291  delete mMapRenderer;
292  // mCanvasProperties auto-deleted via QScopedPointer
293  // CanvasProperties struct has its own dtor for freeing resources
294 
295  if ( mJob )
296  {
297  mJob->cancel();
298  Q_ASSERT( mJob == 0 );
299  }
300 
301  delete mCache;
302 
303  delete mLabelingResults;
304 
305 } // dtor
306 
308 {
309  mSettings.setFlag( QgsMapSettings::Antialiasing, theFlag );
310 
311  if ( mMapOverview )
312  mMapOverview->enableAntiAliasing( theFlag );
313 } // anti aliasing
314 
315 void QgsMapCanvas::useImageToRender( bool theFlag )
316 {
317  Q_UNUSED( theFlag );
318 }
319 
321 {
322  return mMap;
323 }
324 
326 {
327  return mMapRenderer;
328 }
329 
330 
332 {
333  const QStringList& layers = mapSettings().layers();
334  if ( index >= 0 && index < ( int ) layers.size() )
335  return QgsMapLayerRegistry::instance()->mapLayer( layers[index] );
336  else
337  return NULL;
338 }
339 
340 
342 {
343  mCurrentLayer = layer;
344  emit currentLayerChanged( layer );
345 }
346 
348 {
349  return mapSettings().scale();
350 } // scale
351 
352 void QgsMapCanvas::setDirty( bool dirty )
353 {
354  if ( dirty )
355  refresh();
356 }
357 
359 {
360  return false;
361 }
362 
363 
364 
366 {
367  return mJob != 0;
368 } // isDrawing
369 
370 
371 // return the current coordinate transform based on the extents and
372 // device size
374 {
375  return &mapSettings().mapToPixel();
376 }
377 
379 {
380  // create layer set
381  QStringList layerSet, layerSetOverview;
382 
383  int i;
384  for ( i = 0; i < layers.size(); i++ )
385  {
386  QgsMapCanvasLayer &lyr = layers[i];
387  if ( !lyr.layer() )
388  {
389  continue;
390  }
391 
392  if ( lyr.isVisible() )
393  {
394  layerSet.push_back( lyr.layer()->id() );
395  }
396 
397  if ( lyr.isInOverview() )
398  {
399  layerSetOverview.push_back( lyr.layer()->id() );
400  }
401  }
402 
403  const QStringList& layerSetOld = mapSettings().layers();
404 
405  bool layerSetChanged = layerSetOld != layerSet;
406 
407  // update only if needed
408  if ( layerSetChanged )
409  {
410  QgsDebugMsg( "Layers changed to: " + layerSet.join( ", " ) );
411 
412  for ( i = 0; i < layerCount(); i++ )
413  {
414  // Add check if vector layer when disconnecting from selectionChanged slot
415  // Ticket #811 - racicot
417  if ( !currentLayer )
418  continue;
419  disconnect( currentLayer, SIGNAL( repaintRequested() ), this, SLOT( refresh() ) );
420  disconnect( currentLayer, SIGNAL( layerCrsChanged() ), this, SLOT( layerCrsChange() ) );
421  QgsVectorLayer *isVectLyr = qobject_cast<QgsVectorLayer *>( currentLayer );
422  if ( isVectLyr )
423  {
424  disconnect( currentLayer, SIGNAL( selectionChanged() ), this, SLOT( selectionChangedSlot() ) );
425  }
426  }
427 
428  mSettings.setLayers( layerSet );
429 
430  for ( i = 0; i < layerCount(); i++ )
431  {
432  // Add check if vector layer when connecting to selectionChanged slot
433  // Ticket #811 - racicot
435  connect( currentLayer, SIGNAL( repaintRequested() ), this, SLOT( refresh() ) );
436  connect( currentLayer, SIGNAL( layerCrsChanged() ), this, SLOT( layerCrsChange() ) );
437  QgsVectorLayer *isVectLyr = qobject_cast<QgsVectorLayer *>( currentLayer );
438  if ( isVectLyr )
439  {
440  connect( currentLayer, SIGNAL( selectionChanged() ), this, SLOT( selectionChangedSlot() ) );
441  }
442  }
443 
445 
446  QgsDebugMsg( "Layers have changed, refreshing" );
447  emit layersChanged();
448 
449  refresh();
450  }
451 
452  if ( mMapOverview )
453  {
454  const QStringList& layerSetOvOld = mMapOverview->layerSet();
455  if ( layerSetOvOld != layerSetOverview )
456  {
457  mMapOverview->setLayerSet( layerSetOverview );
458  }
459 
460  // refresh overview maplayers even if layer set is the same
461  // because full extent might have changed
462  updateOverview();
463  }
464 } // setLayerSet
465 
467 {
468  if ( mMapOverview )
469  {
470  // disconnect old map overview if exists
471  disconnect( this, SIGNAL( hasCrsTransformEnabledChanged( bool ) ),
472  mMapOverview, SLOT( hasCrsTransformEnabled( bool ) ) );
473  disconnect( this, SIGNAL( destinationCrsChanged() ),
474  mMapOverview, SLOT( destinationSrsChanged() ) );
475 
476  // map overview is not owned by map canvas so don't delete it...
477  }
478 
479  mMapOverview = overview;
480 
481  if ( overview )
482  {
483  // connect to the map render to copy its projection settings
484  connect( this, SIGNAL( hasCrsTransformEnabledChanged( bool ) ),
485  overview, SLOT( hasCrsTransformEnabled( bool ) ) );
486  connect( this, SIGNAL( destinationCrsChanged() ),
487  overview, SLOT( destinationSrsChanged() ) );
488  }
489 }
490 
492 {
493  return mSettings;
494 }
495 
497 {
498  if ( mSettings.hasCrsTransformEnabled() == enabled )
499  return;
500 
501  mSettings.setCrsTransformEnabled( enabled );
502 
504 
505  refresh();
506 
507  emit hasCrsTransformEnabledChanged( enabled );
508 }
509 
511 {
512  if ( mSettings.destinationCrs() == crs )
513  return;
514 
515  if ( mSettings.hasCrsTransformEnabled() )
516  {
517  // try to reproject current extent to the new one
519  if ( !mSettings.visibleExtent().isEmpty() )
520  {
521  QgsCoordinateTransform transform( mSettings.destinationCrs(), crs );
522  try
523  {
524  rect = transform.transformBoundingBox( mSettings.visibleExtent() );
525  }
526  catch ( QgsCsException &e )
527  {
528  QgsDebugMsg( QString( "Transform error caught: %1" ).arg( e.what() ) );
529  }
530  }
531  if ( !rect.isEmpty() )
532  {
533  setExtent( rect );
534  }
535 
536  QgsDebugMsg( "refreshing after destination CRS changed" );
537  refresh();
538  }
539 
540  mSettings.setDestinationCrs( crs );
541 
543 
544  emit destinationCrsChanged();
545 }
546 
548 {
549  return mLabelingResults;
550 }
551 
553 {
554  if ( enabled == isCachingEnabled() )
555  return;
556 
557  if ( mJob && mJob->isActive() )
558  {
559  // wait for the current rendering to finish, before touching the cache
560  mJob->waitForFinished();
561  }
562 
563  if ( enabled )
564  {
565  mCache = new QgsMapRendererCache;
566  }
567  else
568  {
569  delete mCache;
570  mCache = 0;
571  }
572 }
573 
575 {
576  return mCache != 0;
577 }
578 
580 {
581  if ( mCache )
582  mCache->clear();
583 }
584 
586 {
587  mUseParallelRendering = enabled;
588 }
589 
591 {
592  return mUseParallelRendering;
593 }
594 
595 void QgsMapCanvas::setMapUpdateInterval( int timeMiliseconds )
596 {
597  mMapUpdateTimer.setInterval( timeMiliseconds );
598 }
599 
601 {
602  return mMapUpdateTimer.interval();
603 }
604 
605 
607 {
608  // redraw overview
609  if ( mMapOverview )
610  {
611  mMapOverview->refresh();
612  }
613 }
614 
615 
617 {
618  return mCurrentLayer;
619 }
620 
621 
623 {
624  if ( !mSettings.hasValidSettings() )
625  {
626  QgsDebugMsg( "CANVAS refresh - invalid settings -> nothing to do" );
627  return;
628  }
629 
630  if ( !mRenderFlag || mFrozen ) // do we really need two flags controlling rendering?
631  {
632  QgsDebugMsg( "CANVAS render flag off" );
633  return;
634  }
635 
636  if ( mRefreshScheduled )
637  {
638  QgsDebugMsg( "CANVAS refresh already scheduled" );
639  return;
640  }
641 
642  mRefreshScheduled = true;
643 
644  QgsDebugMsg( "CANVAS refresh scheduling" );
645 
646  // schedule a refresh
647  QTimer::singleShot( 1, this, SLOT( refreshMap() ) );
648 } // refresh
649 
650 void QgsMapCanvas::refreshMap()
651 {
652  Q_ASSERT( mRefreshScheduled );
653 
654  QgsDebugMsg( "CANVAS refresh!" );
655 
656  stopRendering(); // if any...
657 
658  // from now on we can accept refresh requests again
659  mRefreshScheduled = false;
660 
661  //update $map variable to canvas
662  QgsExpression::setSpecialColumn( "$map", tr( "canvas" ) );
663 
664  // create the renderer job
665  Q_ASSERT( mJob == 0 );
666  mJobCancelled = false;
667  if ( mUseParallelRendering )
668  mJob = new QgsMapRendererParallelJob( mSettings );
669  else
670  mJob = new QgsMapRendererSequentialJob( mSettings );
671  connect( mJob, SIGNAL( finished() ), SLOT( rendererJobFinished() ) );
672  mJob->setCache( mCache );
673 
674  QStringList layersForGeometryCache;
675  foreach ( QString id, mSettings.layers() )
676  {
677  if ( QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( id ) ) )
678  {
679  if ( vl->isEditable() )
680  layersForGeometryCache << id;
681  }
682  }
683  mJob->setRequestedGeometryCacheForLayers( layersForGeometryCache );
684 
685  mJob->start();
686 
687  mMapUpdateTimer.start();
688 
689  emit renderStarting();
690 }
691 
692 
693 void QgsMapCanvas::rendererJobFinished()
694 {
695  QgsDebugMsg( QString( "CANVAS finish! %1" ).arg( !mJobCancelled ) );
696 
697  mMapUpdateTimer.stop();
698 
699  // TODO: would be better to show the errors in message bar
700  foreach ( const QgsMapRendererJob::Error& error, mJob->errors() )
701  {
702  QgsMessageLog::logMessage( error.layerID + " :: " + error.message, tr( "Rendering" ) );
703  }
704 
705  if ( !mJobCancelled )
706  {
707  // take labeling results before emitting renderComplete, so labeling map tools
708  // connected to signal work with correct results
709  delete mLabelingResults;
710  mLabelingResults = mJob->takeLabelingResults();
711 
712  QImage img = mJob->renderedImage();
713 
714  // emit renderComplete to get our decorations drawn
715  QPainter p( &img );
716  emit renderComplete( &p );
717 
718  QSettings settings;
719  if ( settings.value( "/Map/logCanvasRefreshEvent", false ).toBool() )
720  {
721  QString logMsg = tr( "Canvas refresh: %1 ms" ).arg( mJob->renderingTime() );
722  QgsMessageLog::logMessage( logMsg, tr( "Rendering" ) );
723  }
724 
725  if ( mDrawRenderingStats )
726  {
727  int w = img.width(), h = img.height();
728  QFont fnt = p.font();
729  fnt.setBold( true );
730  p.setFont( fnt );
731  int lh = p.fontMetrics().height() * 2;
732  QRect r( 0, h - lh, w, lh );
733  p.setPen( Qt::NoPen );
734  p.setBrush( QColor( 0, 0, 0, 110 ) );
735  p.drawRect( r );
736  p.setPen( Qt::white );
737  QString msg = QString( "%1 :: %2 ms" ).arg( mUseParallelRendering ? "PARALLEL" : "SEQUENTIAL" ).arg( mJob->renderingTime() );
738  p.drawText( r, msg, QTextOption( Qt::AlignCenter ) );
739  }
740 
741  p.end();
742 
743  mMap->setContent( img, imageRect( img, mJob->mapSettings() ) );
744  }
745 
746  // now we are in a slot called from mJob - do not delete it immediately
747  // so the class is still valid when the execution returns to the class
748  mJob->deleteLater();
749  mJob = 0;
750 
751  emit mapCanvasRefreshed();
752 }
753 
754 QgsRectangle QgsMapCanvas::imageRect( const QImage& img, const QgsMapSettings& mapSettings )
755 {
756  // This is a hack to pass QgsMapCanvasItem::setRect what it
757  // expects (encoding of position and size of the item)
758  const QgsMapToPixel& m2p = mapSettings.mapToPixel();
759  QgsPoint topLeft = m2p.toMapPoint( 0, 0 );
760  double res = m2p.mapUnitsPerPixel();
761  QgsRectangle rect( topLeft.x(), topLeft.y(), topLeft.x() + img.width()*res, topLeft.y() - img.height()*res );
762  return rect;
763 }
764 
765 void QgsMapCanvas::mapUpdateTimeout()
766 {
767  const QImage& img = mJob->renderedImage();
768  mMap->setContent( img, imageRect( img, mJob->mapSettings() ) );
769 }
770 
772 {
773  if ( mJob )
774  {
775  QgsDebugMsg( "CANVAS stop rendering!" );
776  mJobCancelled = true;
777  mJob->cancel();
778  Q_ASSERT( mJob == 0 ); // no need to delete here: already deleted in finished()
779  }
780 }
781 
783 {
784 }
785 
786 //the format defaults to "PNG" if not specified
787 void QgsMapCanvas::saveAsImage( QString theFileName, QPixmap * theQPixmap, QString theFormat )
788 {
789  //
790  //check if the optional QPaintDevice was supplied
791  //
792  if ( theQPixmap != NULL )
793  {
794  // render
795  QPainter painter;
796  painter.begin( theQPixmap );
797  QgsMapRendererCustomPainterJob job( mSettings, &painter );
798  job.start();
799  job.waitForFinished();
800  emit renderComplete( &painter );
801  painter.end();
802 
803  theQPixmap->save( theFileName, theFormat.toLocal8Bit().data() );
804  }
805  else //use the map view
806  {
807  mMap->contentImage().save( theFileName, theFormat.toLocal8Bit().data() );
808  }
809  //create a world file to go with the image...
811  QString myHeader;
812  // note: use 17 places of precision for all numbers output
813  //Pixel XDim
814  myHeader += qgsDoubleToString( mapUnitsPerPixel() ) + "\r\n";
815  //Rotation on y axis - hard coded
816  myHeader += "0 \r\n";
817  //Rotation on x axis - hard coded
818  myHeader += "0 \r\n";
819  //Pixel YDim - almost always negative - see
820  //http://en.wikipedia.org/wiki/World_file#cite_note-2
821  myHeader += "-" + qgsDoubleToString( mapUnitsPerPixel() ) + "\r\n";
822  //Origin X (center of top left cell)
823  myHeader += qgsDoubleToString( myRect.xMinimum() + ( mapUnitsPerPixel() / 2 ) ) + "\r\n";
824  //Origin Y (center of top left cell)
825  myHeader += qgsDoubleToString( myRect.yMaximum() - ( mapUnitsPerPixel() / 2 ) ) + "\r\n";
826  QFileInfo myInfo = QFileInfo( theFileName );
827  // allow dotted names
828  QString myWorldFileName = myInfo.absolutePath() + "/" + myInfo.completeBaseName() + "." + theFormat + "w";
829  QFile myWorldFile( myWorldFileName );
830  if ( !myWorldFile.open( QIODevice::WriteOnly ) ) //don't use QIODevice::Text
831  {
832  return;
833  }
834  QTextStream myStream( &myWorldFile );
835  myStream << myHeader;
836 } // saveAsImage
837 
838 
839 
841 {
842  return mapSettings().visibleExtent();
843 } // extent
844 
846 {
847  return mapSettings().fullExtent();
848 } // extent
849 
850 
852 {
853  QgsRectangle current = extent();
854 
855  if ( r == current )
856  return;
857 
858  if ( r.isEmpty() )
859  {
860  if ( !mSettings.hasValidSettings() )
861  {
862  // we can't even just move the map center
863  QgsDebugMsg( "Empty extent - ignoring" );
864  return;
865  }
866 
867  // ### QGIS 3: do not allow empty extent - require users to call setCenter() explicitly
868  QgsDebugMsg( "Empty extent - keeping old scale with new center!" );
869  setCenter( r.center() );
870  }
871  else
872  {
873  mSettings.setExtent( r );
874  }
875  emit extentsChanged();
876  updateScale();
877  if ( mLastExtent.size() > 20 )
878  mLastExtent.removeAt( 0 );
879 
880  //clear all extent items after current index
881  for ( int i = mLastExtent.size() - 1; i > mLastExtentIndex; i-- )
882  {
883  mLastExtent.removeAt( i );
884  }
885 
886  mLastExtent.append( extent() );
887 
888  // adjust history to no more than 20
889  if ( mLastExtent.size() > 20 )
890  {
891  mLastExtent.removeAt( 0 );
892  }
893 
894  // the last item is the current extent
895  mLastExtentIndex = mLastExtent.size() - 1;
896 
897  // update controls' enabled state
898  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
899  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
900  // notify canvas items of change
902 
903 } // setExtent
904 
905 void QgsMapCanvas::setCenter( const QgsPoint& center )
906 {
908  double x = center.x();
909  double y = center.y();
910  setExtent(
911  QgsRectangle(
912  x - r.width() / 2.0, y - r.height() / 2.0,
913  x + r.width() / 2.0, y + r.height() / 2.0
914  )
915  );
916 } // setCenter
917 
919 {
921  return r.center();
922 }
923 
924 
926 {
927  return mapSettings().rotation();
928 } // rotation
929 
930 void QgsMapCanvas::setRotation( double degrees )
931 {
932  if ( !rotationEnabled() )
933  return;
934 
935  double current = rotation();
936 
937  if ( degrees == current )
938  return;
939 
940  mSettings.setRotation( degrees );
941  emit rotationChanged( degrees );
942  emit extentsChanged(); // visible extent changes with rotation
943 
944  // notify canvas items of change (needed?)
946 
947 } // setRotation
948 
949 
951 {
952  emit scaleChanged( mapSettings().scale() );
953 }
954 
955 
957 {
958  refresh();
959 } // clear
960 
961 
962 
964 {
966  // If the full extent is an empty set, don't do the zoom
967  if ( !extent.isEmpty() )
968  {
969  // Add a 5% margin around the full extent
970  extent.scale( 1.05 );
971  setExtent( extent );
972  }
973  refresh();
974 
975 } // zoomToFullExtent
976 
977 
978 
980 {
981  if ( mLastExtentIndex > 0 )
982  {
983  mLastExtentIndex--;
984  mSettings.setExtent( mLastExtent[mLastExtentIndex] );
985  emit extentsChanged();
986  updateScale();
987  refresh();
988  // update controls' enabled state
989  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
990  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
991  // notify canvas items of change
993  }
994 
995 } // zoomToPreviousExtent
996 
998 {
999  if ( mLastExtentIndex < mLastExtent.size() - 1 )
1000  {
1001  mLastExtentIndex++;
1002  mSettings.setExtent( mLastExtent[mLastExtentIndex] );
1003  emit extentsChanged();
1004  updateScale();
1005  refresh();
1006  // update controls' enabled state
1007  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
1008  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
1009  // notify canvas items of change
1011  }
1012 }// zoomToNextExtent
1013 
1015 {
1016  mLastExtent.clear(); // clear the zoom history list
1017  mLastExtent.append( extent() ) ; // set the current extent in the list
1018  mLastExtentIndex = mLastExtent.size() - 1;
1019  // update controls' enabled state
1020  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
1021  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
1022 }// clearExtentHistory
1023 
1024 
1026 {
1028 }
1029 
1031 {
1032  if ( layer == NULL )
1033  {
1034  // use current layer by default
1035  layer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
1036  }
1037 
1038  if ( layer == NULL )
1039  {
1040  return;
1041  }
1042 
1043  if ( layer->selectedFeatureCount() == 0 )
1044  {
1045  return;
1046  }
1047 
1049 
1050  // no selected features, only one selected point feature
1051  //or two point features with the same x- or y-coordinates
1052  if ( rect.isEmpty() )
1053  {
1054  // zoom in
1055  QgsPoint c = rect.center();
1056  rect = extent();
1057  rect.scale( 1.0, &c );
1058  }
1059  //zoom to an area
1060  else
1061  {
1062  // Expand rect to give a bit of space around the selected
1063  // objects so as to keep them clear of the map boundaries
1064  // The same 5% should apply to all margins.
1065  rect.scale( 1.05 );
1066  }
1067 
1068  setExtent( rect );
1069  refresh();
1070 } // zoomToSelected
1071 
1073 {
1074  if ( layer == NULL )
1075  {
1076  // use current layer by default
1077  layer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
1078  }
1079 
1080  if ( layer == NULL )
1081  {
1082  return;
1083  }
1084 
1085  if ( layer->selectedFeatureCount() == 0 )
1086  {
1087  return;
1088  }
1089 
1091  setExtent( QgsRectangle( rect.center(), rect.center() ) );
1092  refresh();
1093 } // panToSelected
1094 
1096 {
1097  if ( mCanvasProperties->mouseButtonDown || mCanvasProperties->panSelectorDown )
1098  {
1099  emit keyPressed( e );
1100  return;
1101  }
1102 
1103  QPainter paint;
1104  QPen pen( Qt::gray );
1105  QgsPoint ll, ur;
1106 
1107  if ( ! mCanvasProperties->mouseButtonDown )
1108  {
1109  // Don't want to interfer with mouse events
1110 
1111  QgsRectangle currentExtent = mapSettings().visibleExtent();
1112  double dx = qAbs(( currentExtent.xMaximum() - currentExtent.xMinimum() ) / 4 );
1113  double dy = qAbs(( currentExtent.yMaximum() - currentExtent.yMinimum() ) / 4 );
1114 
1115  switch ( e->key() )
1116  {
1117  case Qt::Key_Left:
1118  QgsDebugMsg( "Pan left" );
1119 
1120  currentExtent.setXMinimum( currentExtent.xMinimum() - dx );
1121  currentExtent.setXMaximum( currentExtent.xMaximum() - dx );
1122  setExtent( currentExtent );
1123  refresh();
1124  break;
1125 
1126  case Qt::Key_Right:
1127  QgsDebugMsg( "Pan right" );
1128 
1129  currentExtent.setXMinimum( currentExtent.xMinimum() + dx );
1130  currentExtent.setXMaximum( currentExtent.xMaximum() + dx );
1131  setExtent( currentExtent );
1132  refresh();
1133  break;
1134 
1135  case Qt::Key_Up:
1136  QgsDebugMsg( "Pan up" );
1137 
1138  currentExtent.setYMaximum( currentExtent.yMaximum() + dy );
1139  currentExtent.setYMinimum( currentExtent.yMinimum() + dy );
1140  setExtent( currentExtent );
1141  refresh();
1142  break;
1143 
1144  case Qt::Key_Down:
1145  QgsDebugMsg( "Pan down" );
1146 
1147  currentExtent.setYMaximum( currentExtent.yMaximum() - dy );
1148  currentExtent.setYMinimum( currentExtent.yMinimum() - dy );
1149  setExtent( currentExtent );
1150  refresh();
1151  break;
1152 
1153 
1154 
1155  case Qt::Key_Space:
1156  QgsDebugMsg( "Pressing pan selector" );
1157 
1158  //mCanvasProperties->dragging = true;
1159  if ( ! e->isAutoRepeat() )
1160  {
1161  mCanvasProperties->panSelectorDown = true;
1162  mCanvasProperties->rubberStartPoint = mCanvasProperties->mouseLastXY;
1163  }
1164  break;
1165 
1166  case Qt::Key_PageUp:
1167  QgsDebugMsg( "Zoom in" );
1168  zoomIn();
1169  break;
1170 
1171  case Qt::Key_PageDown:
1172  QgsDebugMsg( "Zoom out" );
1173  zoomOut();
1174  break;
1175 
1176 #if 0
1177  case Qt::Key_P:
1178  mUseParallelRendering = !mUseParallelRendering;
1179  refresh();
1180  break;
1181 
1182  case Qt::Key_S:
1183  mDrawRenderingStats = !mDrawRenderingStats;
1184  refresh();
1185  break;
1186 #endif
1187 
1188  default:
1189  // Pass it on
1190  if ( mMapTool )
1191  {
1192  mMapTool->keyPressEvent( e );
1193  }
1194  else e->ignore();
1195 
1196  QgsDebugMsg( "Ignoring key: " + QString::number( e->key() ) );
1197  }
1198  }
1199 
1200  emit keyPressed( e );
1201 
1202 } //keyPressEvent()
1203 
1205 {
1206  QgsDebugMsg( "keyRelease event" );
1207 
1208  switch ( e->key() )
1209  {
1210  case Qt::Key_Space:
1211  if ( !e->isAutoRepeat() && mCanvasProperties->panSelectorDown )
1212  {
1213  QgsDebugMsg( "Releasing pan selector" );
1214 
1215  mCanvasProperties->panSelectorDown = false;
1216  panActionEnd( mCanvasProperties->mouseLastXY );
1217  }
1218  break;
1219 
1220  default:
1221  // Pass it on
1222  if ( mMapTool )
1223  {
1224  mMapTool->keyReleaseEvent( e );
1225  }
1226  else e->ignore();
1227 
1228  QgsDebugMsg( "Ignoring key release: " + QString::number( e->key() ) );
1229  }
1230 
1231  emit keyReleased( e );
1232 
1233 } //keyReleaseEvent()
1234 
1235 
1237 {
1238  // call handler of current map tool
1239  if ( mMapTool )
1240  {
1241  mMapTool->canvasDoubleClickEvent( e );
1242  }
1243 }// mouseDoubleClickEvent
1244 
1245 
1247 {
1248  //use middle mouse button for panning, map tools won't receive any events in that case
1249  if ( e->button() == Qt::MidButton )
1250  {
1251  mCanvasProperties->panSelectorDown = true;
1252  mCanvasProperties->rubberStartPoint = mCanvasProperties->mouseLastXY;
1253  }
1254  else
1255  {
1256 
1257  // call handler of current map tool
1258  if ( mMapTool )
1259  {
1260  mMapTool->canvasPressEvent( e );
1261  }
1262  }
1263 
1264  if ( mCanvasProperties->panSelectorDown )
1265  {
1266  return;
1267  }
1268 
1269  mCanvasProperties->mouseButtonDown = true;
1270  mCanvasProperties->rubberStartPoint = e->pos();
1271 
1272 } // mousePressEvent
1273 
1274 
1276 {
1277  //use middle mouse button for panning, map tools won't receive any events in that case
1278  if ( e->button() == Qt::MidButton )
1279  {
1280  mCanvasProperties->panSelectorDown = false;
1281  panActionEnd( mCanvasProperties->mouseLastXY );
1282  }
1283  else
1284  {
1285  // call handler of current map tool
1286  if ( mMapTool )
1287  {
1288  // right button was pressed in zoom tool? return to previous non zoom tool
1289  if ( e->button() == Qt::RightButton && mMapTool->isTransient() )
1290  {
1291  QgsDebugMsg( "Right click in map tool zoom or pan, last tool is " +
1292  QString( mLastNonZoomMapTool ? "not null." : "null." ) );
1293 
1294  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
1295 
1296  // change to older non-zoom tool
1297  if ( mLastNonZoomMapTool
1298  && ( !mLastNonZoomMapTool->isEditTool() || ( vlayer && vlayer->isEditable() ) ) )
1299  {
1300  QgsMapTool* t = mLastNonZoomMapTool;
1301  mLastNonZoomMapTool = NULL;
1302  setMapTool( t );
1303  }
1304  return;
1305  }
1306  mMapTool->canvasReleaseEvent( e );
1307  }
1308  }
1309 
1310 
1311  mCanvasProperties->mouseButtonDown = false;
1312 
1313  if ( mCanvasProperties->panSelectorDown )
1314  return;
1315 
1316 } // mouseReleaseEvent
1317 
1319 {
1321  mResizeTimer->start( 500 );
1322 
1323  QSize lastSize = viewport()->size();
1324 
1325  mSettings.setOutputSize( lastSize );
1326  mMapRenderer->setOutputSize( lastSize, mSettings.outputDpi() );
1327 
1328  mScene->setSceneRect( QRectF( 0, 0, lastSize.width(), lastSize.height() ) );
1329 
1330  moveCanvasContents( true );
1331 
1332  // notify canvas items of change
1334 
1335  updateScale();
1336 
1337  //refresh();
1338 
1339  emit extentsChanged();
1340 }
1341 
1343 {
1344  // no custom event handling anymore
1345 
1347 } // paintEvent
1348 
1350 {
1351  QList<QGraphicsItem*> list = mScene->items();
1353  while ( it != list.end() )
1354  {
1355  QgsMapCanvasItem* item = dynamic_cast<QgsMapCanvasItem *>( *it );
1356 
1357  if ( item )
1358  {
1359  item->updatePosition();
1360  }
1361 
1362  ++it;
1363  }
1364 }
1365 
1366 
1368 {
1369  // Zoom the map canvas in response to a mouse wheel event. Moving the
1370  // wheel forward (away) from the user zooms in
1371 
1372  QgsDebugMsg( "Wheel event delta " + QString::number( e->delta() ) );
1373 
1374  if ( mMapTool )
1375  {
1376  mMapTool->wheelEvent( e );
1377  }
1378 
1380  {
1381  // leave the wheel for map tools if any modifier pressed
1382  return;
1383  }
1384 
1385  switch ( mWheelAction )
1386  {
1387  case WheelZoom:
1388  // zoom without changing extent
1389  if ( e->delta() > 0 )
1390  zoomIn();
1391  else
1392  zoomOut();
1393  break;
1394 
1395  case WheelZoomAndRecenter:
1396  // zoom and don't change extent
1397  zoomWithCenter( e->x(), e->y(), e->delta() > 0 );
1398  break;
1399 
1401  {
1402  // zoom map to mouse cursor
1403  double scaleFactor = e->delta() > 0 ? 1 / mWheelZoomFactor : mWheelZoomFactor;
1404 
1405  QgsPoint oldCenter = center();
1406  QgsPoint mousePos( getCoordinateTransform()->toMapPoint( e->x(), e->y() ) );
1407  QgsPoint newCenter( mousePos.x() + (( oldCenter.x() - mousePos.x() ) * scaleFactor ),
1408  mousePos.y() + (( oldCenter.y() - mousePos.y() ) * scaleFactor ) );
1409 
1410  zoomByFactor( scaleFactor, &newCenter );
1411  break;
1412  }
1413 
1414  case WheelNothing:
1415  // well, nothing!
1416  break;
1417  }
1418 }
1419 
1420 void QgsMapCanvas::setWheelAction( WheelAction action, double factor )
1421 {
1422  mWheelAction = action;
1423  mWheelZoomFactor = factor;
1424 }
1425 
1427 {
1428  zoomByFactor( 1 / mWheelZoomFactor );
1429 }
1430 
1432 {
1433  zoomByFactor( mWheelZoomFactor );
1434 }
1435 
1436 void QgsMapCanvas::zoomScale( double newScale )
1437 {
1438  zoomByFactor( newScale / scale() );
1439 }
1440 
1441 void QgsMapCanvas::zoomWithCenter( int x, int y, bool zoomIn )
1442 {
1443  double scaleFactor = ( zoomIn ? 1 / mWheelZoomFactor : mWheelZoomFactor );
1444 
1445  // transform the mouse pos to map coordinates
1448  r.scale( scaleFactor, &center );
1449  setExtent( r );
1450  refresh();
1451 }
1452 
1454 {
1455  mCanvasProperties->mouseLastXY = e->pos();
1456 
1457  if ( mCanvasProperties->panSelectorDown )
1458  {
1459  panAction( e );
1460  }
1461  else
1462  {
1463  // call handler of current map tool
1464  if ( mMapTool )
1465  {
1466  mMapTool->canvasMoveEvent( e );
1467  }
1468  }
1469 
1470  // show x y on status bar
1471  QPoint xy = e->pos();
1473  emit xyCoordinates( coord );
1474 } // mouseMoveEvent
1475 
1476 
1477 
1480 {
1481  if ( !tool )
1482  return;
1483 
1484  if ( mMapTool )
1485  {
1486  disconnect( mMapTool, SIGNAL( destroyed() ), this, SLOT( mapToolDestroyed() ) );
1487  mMapTool->deactivate();
1488  }
1489 
1490  if ( tool->isTransient() && mMapTool && !mMapTool->isTransient() )
1491  {
1492  // if zoom or pan tool will be active, save old tool
1493  // to bring it back on right click
1494  // (but only if it wasn't also zoom or pan tool)
1495  mLastNonZoomMapTool = mMapTool;
1496  }
1497  else
1498  {
1499  mLastNonZoomMapTool = NULL;
1500  }
1501 
1502  QgsMapTool* oldTool = mMapTool;
1503 
1504  // set new map tool and activate it
1505  mMapTool = tool;
1506  if ( mMapTool )
1507  {
1508  connect( mMapTool, SIGNAL( destroyed() ), this, SLOT( mapToolDestroyed() ) );
1509  mMapTool->activate();
1510  }
1511 
1512  emit mapToolSet( mMapTool );
1513  emit mapToolSet( mMapTool, oldTool );
1514 } // setMapTool
1515 
1517 {
1518  if ( mMapTool && mMapTool == tool )
1519  {
1520  mMapTool->deactivate();
1521  mMapTool = NULL;
1522  emit mapToolSet( NULL );
1523  emit mapToolSet( NULL, mMapTool );
1524  setCursor( Qt::ArrowCursor );
1525  }
1526 
1527  if ( mLastNonZoomMapTool && mLastNonZoomMapTool == tool )
1528  {
1529  mLastNonZoomMapTool = NULL;
1530  }
1531 }
1532 
1534 void QgsMapCanvas::setCanvasColor( const QColor & theColor )
1535 {
1536  // background of map's pixmap
1537  mSettings.setBackgroundColor( theColor );
1538 
1539  // background of the QGraphicsView
1540  QBrush bgBrush( theColor );
1541  setBackgroundBrush( bgBrush );
1542 #if 0
1543  QPalette palette;
1544  palette.setColor( backgroundRole(), theColor );
1545  setPalette( palette );
1546 #endif
1547 
1548  // background of QGraphicsScene
1549  mScene->setBackgroundBrush( bgBrush );
1550 } // setBackgroundColor
1551 
1553 {
1554  return mScene->backgroundBrush().color();
1555 }
1556 
1558 {
1559  mSettings.setSelectionColor( color );
1560 }
1561 
1563 {
1564  return mapSettings().layers().size();
1565 } // layerCount
1566 
1567 
1569 {
1570  QList<QgsMapLayer*> lst;
1571  foreach ( QString layerID, mapSettings().layers() )
1572  {
1574  if ( layer )
1575  lst.append( layer );
1576  }
1577  return lst;
1578 }
1579 
1580 
1582 {
1583  // called when a layer has changed visibility setting
1584 
1585  refresh();
1586 
1587 } // layerStateChange
1588 
1590 {
1591  // called when a layer's CRS has been changed
1592  QObject *theSender = sender();
1593  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( theSender );
1594  QString destAuthId = mSettings.destinationCrs().authid();
1595  getDatumTransformInfo( layer, layer->crs().authid(), destAuthId );
1596 
1597 } // layerCrsChange
1598 
1599 
1600 void QgsMapCanvas::freeze( bool frz )
1601 {
1602  mFrozen = frz;
1603 } // freeze
1604 
1606 {
1607  return mFrozen;
1608 } // freeze
1609 
1610 
1612 {
1614  return mMap->paintDevice();
1616 }
1617 
1619 {
1620  return mapSettings().mapUnitsPerPixel();
1621 } // mapUnitsPerPixel
1622 
1623 
1625 {
1626  if ( mSettings.mapUnits() == u )
1627  return;
1628 
1629  QgsDebugMsg( "Setting map units to " + QString::number( static_cast<int>( u ) ) );
1630  mSettings.setMapUnits( u );
1631 
1632  updateScale();
1633 
1634  refresh(); // this will force the scale bar to be updated
1635 
1636  emit mapUnitsChanged();
1637 }
1638 
1639 
1641 {
1642  return mapSettings().mapUnits();
1643 }
1644 
1645 
1646 void QgsMapCanvas::setRenderFlag( bool theFlag )
1647 {
1648  mRenderFlag = theFlag;
1649 
1650  if ( mRenderFlag )
1651  {
1652  refresh();
1653  }
1654  else
1655  stopRendering();
1656 }
1657 
1658 #if 0
1659 void QgsMapCanvas::connectNotify( const char * signal )
1660 {
1661  Q_UNUSED( signal );
1662  QgsDebugMsg( "QgsMapCanvas connected to " + QString( signal ) );
1663 } //connectNotify
1664 #endif
1665 
1667 {
1668  if ( !mSettings.hasCrsTransformEnabled() )
1669  return;
1670 
1671  QString destAuthId = mSettings.destinationCrs().authid();
1672  foreach ( QString layerID, mSettings.layers() )
1673  {
1675  if ( !layer )
1676  continue;
1677 
1678  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
1679  if ( vl && vl->geometryType() == QGis::NoGeometry )
1680  continue;
1681 
1682  // if there are more options, ask the user which datum transform to use
1683  if ( !mSettings.datumTransformStore().hasEntryForLayer( layer ) )
1684  getDatumTransformInfo( layer, layer->crs().authid(), destAuthId );
1685  }
1686 }
1687 
1688 
1689 
1691 {
1692  return mMapTool;
1693 }
1694 
1696 {
1697  // move map image and other items to standard position
1698  moveCanvasContents( true ); // true means reset
1699 
1700  // use start and end box points to calculate the extent
1701  QgsPoint start = getCoordinateTransform()->toMapCoordinates( mCanvasProperties->rubberStartPoint );
1702  QgsPoint end = getCoordinateTransform()->toMapCoordinates( releasePoint );
1703 
1704  // modify the center
1705  double dx = end.x() - start.x();
1706  double dy = end.y() - start.y();
1707  QgsPoint c = center();
1708  c.set( c.x() - dx, c.y() - dy );
1709  setCenter( c );
1710 
1711  refresh();
1712 }
1713 
1715 {
1716  Q_UNUSED( e );
1717 
1718  // move all map canvas items
1720 }
1721 
1723 {
1724  QPoint pnt( 0, 0 );
1725  if ( !reset )
1726  pnt += mCanvasProperties->mouseLastXY - mCanvasProperties->rubberStartPoint;
1727 
1728  setSceneRect( -pnt.x(), -pnt.y(), viewport()->size().width(), viewport()->size().height() );
1729 }
1730 
1732 {
1733  Q_UNUSED( mapLayer );
1734 }
1735 
1737 {
1738  return mCanvasProperties->mouseLastXY;
1739 }
1740 
1741 void QgsMapCanvas::setPreviewModeEnabled( bool previewEnabled )
1742 {
1743  if ( !mPreviewEffect )
1744  {
1745  return;
1746  }
1747 
1748  mPreviewEffect->setEnabled( previewEnabled );
1749 }
1750 
1752 {
1753  if ( !mPreviewEffect )
1754  {
1755  return false;
1756  }
1757 
1758  return mPreviewEffect->isEnabled();
1759 }
1760 
1762 {
1763  if ( !mPreviewEffect )
1764  {
1765  return;
1766  }
1767 
1768  mPreviewEffect->setMode( mode );
1769 }
1770 
1772 {
1773  if ( !mPreviewEffect )
1774  {
1776  }
1777 
1778  return mPreviewEffect->mode();
1779 }
1780 
1782 {
1783  if ( !mSnappingUtils )
1784  {
1785  // associate a dummy instance, but better than null pointer
1786  QgsMapCanvas* c = const_cast<QgsMapCanvas*>( this );
1787  c->mSnappingUtils = new QgsMapCanvasSnappingUtils( c, c );
1788  }
1789  return mSnappingUtils;
1790 }
1791 
1793 {
1794  mSnappingUtils = utils;
1795 }
1796 
1798 {
1799  QDomNodeList nodes = doc.elementsByTagName( "mapcanvas" );
1800  if ( nodes.count() )
1801  {
1802  QDomNode node = nodes.item( 0 );
1803 
1804  QgsMapSettings tmpSettings;
1805  tmpSettings.readXML( node );
1806  setMapUnits( tmpSettings.mapUnits() );
1808  setDestinationCrs( tmpSettings.destinationCrs() );
1809  setExtent( tmpSettings.extent() );
1810  setRotation( tmpSettings.rotation() );
1811  mSettings.datumTransformStore() = tmpSettings.datumTransformStore();
1812 
1813  clearExtentHistory(); // clear the extent history on project load
1814  }
1815  else
1816  {
1817  QgsDebugMsg( "Couldn't read mapcanvas information from project" );
1818  }
1819 }
1820 
1822 {
1823  // create node "mapcanvas" and call mMapRenderer->writeXML()
1824 
1825  QDomNodeList nl = doc.elementsByTagName( "qgis" );
1826  if ( !nl.count() )
1827  {
1828  QgsDebugMsg( "Unable to find qgis element in project file" );
1829  return;
1830  }
1831  QDomNode qgisNode = nl.item( 0 ); // there should only be one, so zeroth element ok
1832 
1833  QDomElement mapcanvasNode = doc.createElement( "mapcanvas" );
1834  qgisNode.appendChild( mapcanvasNode );
1835 
1836  mSettings.writeXML( mapcanvasNode, doc );
1837  // TODO: store only units, extent, projections, dest CRS
1838 }
1839 
1841 void QgsMapCanvas::getDatumTransformInfo( const QgsMapLayer* ml, const QString& srcAuthId, const QString& destAuthId )
1842 {
1843  if ( !ml )
1844  {
1845  return;
1846  }
1847 
1848  //check if default datum transformation available
1849  QSettings s;
1850  QString settingsString = "/Projections/" + srcAuthId + "//" + destAuthId;
1851  QVariant defaultSrcTransform = s.value( settingsString + "_srcTransform" );
1852  QVariant defaultDestTransform = s.value( settingsString + "_destTransform" );
1853  if ( defaultSrcTransform.isValid() && defaultDestTransform.isValid() )
1854  {
1855  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, defaultSrcTransform.toInt(), defaultDestTransform.toInt() );
1856  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, defaultSrcTransform.toInt(), defaultDestTransform.toInt() );
1857  return;
1858  }
1859 
1860  const QgsCoordinateReferenceSystem& srcCRS = QgsCRSCache::instance()->crsByAuthId( srcAuthId );
1861  const QgsCoordinateReferenceSystem& destCRS = QgsCRSCache::instance()->crsByAuthId( destAuthId );
1862 
1863  if ( !s.value( "/Projections/showDatumTransformDialog", false ).toBool() )
1864  {
1865  // just use the default transform
1866  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, -1, -1 );
1867  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, -1, -1 );
1868  return;
1869  }
1870 
1871  //get list of datum transforms
1873  if ( dt.size() < 2 )
1874  {
1875  return;
1876  }
1877 
1878  //if several possibilities: present dialog
1879  QgsDatumTransformDialog d( ml->name(), dt );
1880  d.setDatumTransformInfo( srcCRS.authid(), destCRS.authid() );
1881  if ( d.exec() == QDialog::Accepted )
1882  {
1883  int srcTransform = -1;
1884  int destTransform = -1;
1885  QList<int> t = d.selectedDatumTransform();
1886  if ( t.size() > 0 )
1887  {
1888  srcTransform = t.at( 0 );
1889  }
1890  if ( t.size() > 1 )
1891  {
1892  destTransform = t.at( 1 );
1893  }
1894  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, srcTransform, destTransform );
1895  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, srcTransform, destTransform );
1896  if ( d.rememberSelection() )
1897  {
1898  s.setValue( settingsString + "_srcTransform", srcTransform );
1899  s.setValue( settingsString + "_destTransform", destTransform );
1900  }
1901  }
1902  else
1903  {
1904  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, -1, -1 );
1905  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, -1, -1 );
1906  }
1907 }
1908 
1909 void QgsMapCanvas::zoomByFactor( double scaleFactor, const QgsPoint* center )
1910 {
1912  r.scale( scaleFactor, center );
1913  setExtent( r );
1914  refresh();
1915 }
1916 
1918 {
1919  // Find out which layer it was that sent the signal.
1920  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() );
1921  emit selectionChanged( layer );
1922  refresh();
1923 }
1924 
1926 {
1927  // By default graphics view delegates the drag events to graphics items.
1928  // But we do not want that and by ignoring the drag enter we let the
1929  // parent (e.g. QgisApp) to handle drops of map layers etc.
1930  e->ignore();
1931 }
1932 
1933 void QgsMapCanvas::mapToolDestroyed()
1934 {
1935  QgsDebugMsg( "maptool destroyed" );
1936  mMapTool = 0;
1937 }
1938 
1939 #ifdef HAVE_TOUCH
1940 bool QgsMapCanvas::event( QEvent * e )
1941 {
1942  bool done = false;
1943  if ( e->type() == QEvent::Gesture )
1944  {
1945  // call handler of current map tool
1946  if ( mMapTool )
1947  {
1948  done = mMapTool->gestureEvent( static_cast<QGestureEvent*>( e ) );
1949  }
1950  }
1951  else
1952  {
1953  // pass other events to base class
1954  done = QGraphicsView::event( e );
1955  }
1956  return done;
1957 }
1958 #endif
1959 
1961 {
1962  return QSettings().value( "/qgis/canvasRotation", true ).toBool();
1963 }
1964 
1965 void QgsMapCanvas::enableRotation( bool enable )
1966 {
1967  QSettings().setValue( "/qgis/canvasRotation", enable );
1968 }
1969 
1971 {
1972  // reload all layers in canvas
1973  for ( int i = 0; i < layerCount(); i++ )
1974  {
1975  QgsMapLayer *l = layer( i );
1976  if ( l )
1977  l->reload();
1978  }
1979 
1980  // clear the cache
1981  clearCache();
1982 
1983  // and then refresh
1984  refresh();
1985 }
void unsetMapTool(QgsMapTool *mapTool)
Unset the current map tool or last non zoom tool.
void setInterval(int msec)
void zoomToSelected(QgsVectorLayer *layer=NULL)
Zoom to the extent of the selected features of current (vector) layer.
void setRequestedGeometryCacheForLayers(const QStringList &layerIds)
Set which vector layers should be cached while rendering.
void clear()
void updateCanvasItemPositions()
called on resize or changed extent to notify canvas items to change their rectangle ...
void setParallelRenderingEnabled(bool enabled)
Set whether the layers are rendered in parallel or sequentially.
const QgsDatumTransformStore & datumTransformStore() const
static unsigned index
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
sets destination coordinate reference system
QPoint mouseLastXY
Last seen point of the mouse.
virtual QColor canvasColor() const
Read property of QColor bgColor.
A rectangle specified with double values.
Definition: qgsrectangle.h:35
Base class for all map layer types.
Definition: qgsmaplayer.h:49
Job implementation that renders everything sequentially using a custom painter.
void setRotation(double degrees)
Set the rotation of the map canvas in clockwise degrees.
Type type() const
const QgsCoordinateReferenceSystem & crsByAuthId(const QString &authid)
Returns the CRS for authid, e.g.
bool isEmpty() const
test if rectangle is empty.
const QPalette & palette() const
QDomNode item(int index) const
void zoomToNextExtent()
Zoom to the next extent (view)
void zoomWithCenter(int x, int y, bool zoomIn)
Zooms in/out with a given center.
Q_DECL_DEPRECATED bool isDirty() const
Return the state of the canvas (dirty or not)
void freeze(bool frz=true)
virtual void setCanvasColor(const QColor &_newVal)
Write property of QColor bgColor.
int width() const
void enableOverviewMode(QgsMapOverviewCanvas *overview)
int x() const
int y() const
bool end()
void setCursor(const QCursor &)
double scale() const
Return the calculated scale of the map.
void zoomByFactor(double scaleFactor, const QgsPoint *center=0)
Zoom with the factor supplied.
double mapUnitsPerPixel() const
Returns the mapUnitsPerPixel (map units per pixel) for the canvas.
bool hasEntryForLayer(QgsMapLayer *layer) const
Qt::KeyboardModifiers keyboardModifiers()
int layerCount() const
return number of layers on the map
iterator end()
A widget that displays an overview map.
QDomNode appendChild(const QDomNode &newChild)
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:167
void clearExtentHistory()
void setColor(ColorGroup group, ColorRole role, const QColor &color)
void readXML(QDomNode &theNode)
QgsRectangle fullExtent() const
returns current extent of layer set
void push_back(const T &value)
bool mouseButtonDown
Flag to indicate status of mouse button.
static QList< QList< int > > datumTransformations(const QgsCoordinateReferenceSystem &srcCRS, const QgsCoordinateReferenceSystem &destCRS)
Returns list of datum transformations for the given src and dest CRS.
void wheelEvent(QWheelEvent *e) override
Overridden mouse wheel event.
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:192
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
QList< QGraphicsItem * > items() const
UnitType
Map units that qgis supports.
Definition: qgis.h:229
void stopRendering()
stop rendering (if there is any right now)
void setFocusPolicy(Qt::FocusPolicy policy)
bool save(const QString &fileName, const char *format, int quality) const
QObject * sender() const
double rotation() const
Get the current map canvas rotation in clockwise degrees.
virtual void canvasMoveEvent(QMouseEvent *e)
Mouse move event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:139
QgsRectangle extent() const
returns current extent
void setExtent(const QgsRectangle &r)
Set the extent of the map canvas.
void addLayerCoordinateTransform(const QString &layerId, const QString &srcAuthId, const QString &destAuthId, int srcDatumTransform=-1, int destDatumTransform=-1)
void keyPressEvent(QKeyEvent *e) override
Overridden key press event.
const T & at(int i) const
virtual void reload()
Synchronises with changes in the datasource.
Definition: qgsmaplayer.h:129
void setBackgroundBrush(const QBrush &brush)
void removeAt(int i)
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:464
An abstract class for items that can be placed on the map canvas.
A class that stores visibility and presence in overview flags together with pointer to the layer...
Definition: qgsmapcanvas.h:75
bool hasCrsTransformEnabled()
A simple helper method to find out if on the fly projections are enabled or not.
void setCurrentLayer(QgsMapLayer *layer)
bool previewModeEnabled() const
Returns whether a preview mode is enabled for the map canvas.
QgsRectangle visibleExtent() const
Return the actual extent derived from requested extent that takes takes output image size into accoun...
QList< QgsMapLayer * > layers() const
return list of layers within map canvas.
int y() const
void moveCanvasContents(bool reset=false)
called when panning is in action, reset indicates end of panning
void setSceneRect(const QRectF &rect)
bool isVisible() const
Definition: qgsmapcanvas.h:84
void setAttribute(Qt::WidgetAttribute attribute, bool on)
const QgsMapSettings & mapSettings() const
Get access to properties used for map rendering.
bool hasCrsTransformEnabled() const
returns true if projections are enabled for this layer set
QgsRectangle layerExtentToOutputExtent(QgsMapLayer *theLayer, QgsRectangle extent) const
transform bounding box from layer's CRS to output CRS
void readProject(const QDomDocument &)
called to read map canvas settings from project
bool panSelectorDown
Flag to indicate the pan selector key is held down by user.
void refresh()
Repaints the canvas map.
QWidget * viewport() const
void renderComplete(QPainter *)
Emitted when the canvas has rendered.
void setSceneRect(const QRectF &rect)
void setProjectionsEnabled(bool enabled)
sets whether to use projections for this layer set
~QgsMapCanvas()
Destructor.
Snapping utils instance that is connected to a canvas and updates the configuration (map settings + c...
const QgsMapToPixel & mapToPixel() const
QString join(const QString &separator) const
QgsMapTool * mapTool()
Returns the currently active tool.
double rotation() const
Return the rotation of the resulting map image Units are clockwise degrees.
bool isAutoRepeat() const
void setLayerSet(const QStringList &layers)
change current layer set
virtual void canvasDoubleClickEvent(QMouseEvent *e)
Mouse double click event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:144
const QgsLabelingResults * labelingResults() const
Get access to the labeling results (may be null)
A non GUI class for rendering a map layer set onto a QPainter.
virtual void canvasPressEvent(QMouseEvent *e)
Mouse press event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:149
void setLayers(const QStringList &layers)
Set list of layer IDs for map rendering.
void mousePressEvent(QMouseEvent *e) override
Overridden mouse press event.
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
virtual bool isEditable() const override
Returns true if the provider is in editing mode.
void setEnabled(bool enable)
QString tr(const char *sourceText, const char *disambiguation, int n)
virtual QImage renderedImage()=0
Get a preview/resulting image.
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:105
double x() const
Definition: qgspoint.h:126
int x() const
int y() const
void zoomLastStatusChanged(bool)
Emitted when zoom last status changed.
A graphics effect which can be applied to a widget to simulate various printing and color blindness m...
void setCache(QgsMapRendererCache *cache)
Assign a cache to be used for reading and storing rendered images of individual layers.
int size() const
static void logMessage(QString message, QString tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
void setFlag(Flag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
void updateScale()
Emits signal scaleChanged to update scale in main window.
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
sets destination coordinate reference system
The QgsMapSettings class contains configuration for rendering of the map.
void resizeEvent(QResizeEvent *e) override
Overridden resize event.
void setDatumTransformInfo(const QString &srcCRSauthId, const QString &destCRSauthId)
void hasCrsTransformEnabledChanged(bool flag)
Emitted when on-the-fly projection has been turned on/off.
void setBold(bool enable)
void setMapTool(QgsMapTool *mapTool)
Sets the map tool currently being used on the canvas.
void enableAntiAliasing(bool flag)
const QString & name() const
Get the display name of the layer.
virtual void activate()
called when set as currently active map tool
Definition: qgsmaptool.cpp:77
void setValue(const QString &key, const QVariant &value)
void setCrsTransformEnabled(bool enabled)
sets whether to use projections for this layer set
QgsMapRenderer * mRenderer
Definition: qgsmapcanvas.h:728
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:34
void setSnappingUtils(QgsSnappingUtils *utils)
Assign an instance of snapping utils to the map canvas.
virtual void keyReleaseEvent(QKeyEvent *e)
Key event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:169
QTransform transform() const
int outputDpi() const
Return DPI used for conversion between real world units (e.g.
int count() const
QString number(int n, int base)
void append(const T &value)
Q_DECL_DEPRECATED void showError(QgsMapLayer *mapLayer)
bool save(const QString &fileName, const char *format, int quality) const
A rectangular graphics item representing the map on the canvas.
QgsSnappingUtils * snappingUtils() const
Return snapping utility class that is associated with map canvas.
void ignore()
virtual void start() override
Start the rendering job and immediately return.
Q_DECL_DEPRECATED void clear()
Clear the map canvas.
void addEntry(const QString &layerId, const QString &srcAuthId, const QString &destAuthId, int srcDatumTransform, int destDatumTransform)
void mapCanvasRefreshed()
Emitted when canvas finished a refresh request.
int toInt(bool *ok) const
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:197
int x() const
double scale()
Get the last reported scale of the canvas.
void rotationChanged(double)
Emitted when the rotation of the map changes.
double xMaximum() const
Get the x maximum value (right side of rectangle)
Definition: qgsrectangle.h:182
void setInteractive(bool allowed)
void zoomNextStatusChanged(bool)
Emitted when zoom next status changed.
void setRotation(double degrees)
Set the rotation of the resulting map image Units are clockwise degrees.
virtual bool event(QEvent *event)
bool hasCrsTransformEnabled() const
returns true if projections are enabled for this layer set
bool hasValidSettings() const
Check whether the map settings are valid and can be used for rendering.
void clearCache()
Make sure to remove any rendered images from cache (does nothing if cache is not enabled) ...
int width() const
void layerCrsChange()
This slot is connected to the layer's CRS change.
void setBackgroundBrush(const QBrush &brush)
void setMapUnits(QGis::UnitType u)
Set units of map's geographical coordinates - used for scale calculation.
Qt::MouseButton button() const
Job implementation that renders all layers in parallel.
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
QPalette::ColorRole backgroundRole() const
void panToSelected(QgsVectorLayer *layer=NULL)
Pan to the selected features of current (vector) layer keeping same extent.
void setLayerSet(QList< QgsMapCanvasLayer > &layers)
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
void setHorizontalScrollBarPolicy(Qt::ScrollBarPolicy)
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:172
QDomNodeList elementsByTagName(const QString &tagname) const
QgsMapCanvas * mCanvas
Definition: qgsmapcanvas.h:727
void setObjectName(const QString &name)
void keyReleased(QKeyEvent *e)
Emit key release event.
Q_DECL_DEPRECATED QPaintDevice & paintDevice()
virtual void waitForFinished()=0
Block until the job has finished.
bool setExtent(const QgsRectangle &extent)
sets extent and checks whether suitable (returns false if not)
Enable anti-aliasin for map rendering.
const QgsMapSettings & mapSettings() const
Return map settings with which this job was started.
void setMapUnits(QGis::UnitType u)
void getDatumTransformInfo(const QgsMapLayer *ml, const QString &srcAuthId, const QString &destAuthId)
ask user about datum transformation
Q_DECL_DEPRECATED QPaintDevice & canvasPaintDevice()
Accessor for the canvas paint device.
void mouseDoubleClickEvent(QMouseEvent *e) override
Overridden mouse double click event.
static bool rotationEnabled()
return if canvas rotation is enabled
double mapUnitsPerPixel() const
Return the distance in geographical coordinates that equals to one pixel in the map.
void setScene(QGraphicsScene *scene)
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
Definition: qgsmaplayer.cpp:99
void destinationCrsChanged()
Emitted when map CRS has changed.
double rotation() const
returns current rotation in clockwise degrees
double mapUnitsPerPixel() const
Return current map units per pixel.
int mapUpdateInterval() const
Find out how often map preview should be updated while it is being rendered (in milliseconds) ...
void updateDatumTransformEntries()
Make sure the datum transform store is properly populated.
QGis::GeometryType geometryType() const
Returns point, line or polygon.
void setRenderFlag(bool theFlag)
Whether to suppress rendering or not.
QGis::UnitType mapUnits() const
Get units of map's geographical coordinates - used for scale calculation.
void deleteLater()
QGis::UnitType mapUnits() const
Get the current canvas map units.
void setOutputSize(QSize size, int dpi)
void setCachingEnabled(bool enabled)
Set whether to cache images of rendered layers.
virtual void deactivate()
called when map tool is being deactivated
Definition: qgsmaptool.cpp:93
virtual bool isEditTool()
Check whether this MapTool performs an edit operation.
Definition: qgsmaptool.cpp:191
QgsMapCanvasMap * map()
virtual bool open(QFlags< QIODevice::OpenModeFlag > mode)
void setPreviewMode(QgsPreviewEffect::PreviewMode mode)
Sets a preview mode for the map canvas.
virtual void wheelEvent(QWheelEvent *e)
Mouse wheel event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:159
void refresh()
renders overview and updates panning widget
void set(double x, double y)
Definition: qgspoint.h:117
void setMode(PreviewMode mode)
Sets the mode for the preview effect, which controls how the effect modifies a widgets appearance...
void renderStarting()
Emitted when the canvas is about to be rendered.
A class to represent a point.
Definition: qgspoint.h:63
void saveAsImage(QString theFileName, QPixmap *QPixmap=0, QString="PNG")
Save the convtents of the map canvas to disk as an image.
QRect rect() const
void keyPressed(QKeyEvent *e)
Emit key press event.
void currentLayerChanged(QgsMapLayer *layer)
Emitted when the current layer is changed.
void zoomOut()
Zoom out with fixed factor.
QgsPreviewEffect::PreviewMode previewMode() const
Returns the current preview mode for the map canvas.
Enable drawing of vertex markers for layers in editing mode.
void zoomToPreviousExtent()
Zoom to the previous extent (view)
void xyCoordinates(const QgsPoint &p)
emits current mouse position
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs, bool refreshCoordinateTransformInfo=true, bool transformExtent=true)
sets destination coordinate reference system
bool isDrawing()
Find out whether rendering is in progress.
virtual void connectNotify(const char *signal)
iterator end()
QByteArray toLocal8Bit() const
int key() const
void setRotation(double degrees)
sets rotation value in clockwise degrees
QScopedPointer< CanvasProperties > mCanvasProperties
Handle pattern for implementation object.
Definition: qgsmapcanvas.h:592
QString qgsDoubleToString(const double &a, const int &precision=17)
Definition: qgis.h:339
void setPreviewModeEnabled(bool previewEnabled)
Enables a preview mode for the map canvas.
virtual void start()=0
Start the rendering job and immediately return.
static void enableRotation(bool enabled)
change canvas rotation support
QPoint mouseLastXY()
returns last position of mouse cursor
QgsMapLayer * currentLayer()
returns current layer (set by legend widget)
void setWheelAction(WheelAction action, double factor=2)
set wheel action and zoom factor (should be greater than 1)
void mouseMoveEvent(QMouseEvent *e) override
Overridden mouse move event.
void keyReleaseEvent(QKeyEvent *e) override
Overridden key release event.
void stop()
void selectionChanged(QgsMapLayer *layer)
Emitted when selection in any layer gets changed.
virtual void keyPressEvent(QKeyEvent *e)
Key event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:164
bool isCachingEnabled() const
Check whether images of rendered layers are curerently being cached.
QgsPoint toMapCoordinates(int x, int y) const
int delta() const
void clear()
invalidate the cache contents
Abstract base class for all map tools.
Definition: qgsmaptool.h:48
void selectionChangedSlot()
Receives signal about selection change, and pass it on with layer info.
virtual void paintEvent(QPaintEvent *event)
Job implementation that renders everything sequentially in one thread.
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:465
void setBackgroundColor(const QColor &color)
Set the background color of the map.
QString what() const
Definition: qgsexception.h:35
QVariant value(const QString &key, const QVariant &defaultValue) const
void mouseReleaseEvent(QMouseEvent *e) override
Overridden mouse release event.
QImage contentImage() const
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
Q_DECL_DEPRECATED void useImageToRender(bool theFlag)
Select which Qt class to render with.
void setContent(const QImage &image, const QgsRectangle &rect)
bool isInOverview() const
Definition: qgsmapcanvas.h:85
virtual void canvasReleaseEvent(QMouseEvent *e)
Mouse release event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:154
void setSelectionColor(const QColor &color)
Set color that is used for drawing of selected vector features.
void setLayerSet(const QStringList &layerSet)
updates layer set for overview
void dragEnterEvent(QDragEnterEvent *e) override
Overridden drag enter event.
void setOutputSize(const QSize &size)
Set the size of the resulting map image.
void setYMaximum(double y)
Set the maximum y value.
Definition: qgsrectangle.h:177
QgsPoint center() const
Get map center, in geographical coordinates.
void writeProject(QDomDocument &)
called to write map canvas settings to project
void panAction(QMouseEvent *event)
Called when mouse is moving and pan is activated.
static QgsProject * instance()
access to canonical QgsProject instance
Definition: qgsproject.cpp:351
Q_DECL_DEPRECATED QgsMapRenderer * mapRenderer()
void zoomToFullExtent()
Zoom to the full extent of all layers.
Class for storing a coordinate reference system (CRS)
void setExtent(const QgsRectangle &rect)
Set coordinates of the rectangle which should be rendered.
This class has all the configuration of snapping and can return answers to snapping queries...
QgsMapCanvasRendererSync(QgsMapCanvas *canvas, QgsMapRenderer *renderer)
int height() const
void setGraphicsEffect(QGraphicsEffect *effect)
void refreshAllLayers()
Reload all layers, clear the cache and refresh the canvas.
QgsRectangle extent() const
Return geographical coordinates of the rectangle that should be rendered.
void zoomScale(double scale)
Zoom to a specific scale.
Class for doing transforms between two map coordinate systems.
bool toBool() const
void setMouseTracking(bool enable)
char * data()
const QgsMapToPixel * getCoordinateTransform()
Get the current coordinate transform.
void scaleChanged(double)
Emitted when the scale of the map changes.
virtual bool isTransient()
Check whether this MapTool performs a zoom or pan operation.
Definition: qgsmaptool.cpp:186
QString completeBaseName() const
double y() const
Definition: qgspoint.h:134
void setCenter(const QgsPoint &center)
Set the center of the map canvas, in geographical coordinates.
const QgsCoordinateReferenceSystem & crs() const
Returns layer's spatial reference system.
void start(int msec)
bool isValid() const
virtual void cancel()=0
Stop the rendering job - does not return until the job has terminated.
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 enableAntiAliasing(bool theFlag)
used to determine if anti-aliasing is enabled or not
int height() const
QgsMapLayer * mapLayer(QString theLayerId)
Retrieve a pointer to a loaded layer by id.
void setSelectionColor(const QColor &color)
Set color of selected vector features.
void paintEvent(QPaintEvent *e) override
Overridden paint event.
void setMapUpdateInterval(int timeMiliseconds)
Set how often map preview should be updated while it is being rendered (in milliseconds) ...
void layerStateChange()
This slot is connected to the visibility change of one or more layers.
Enable vector simplification and other rendering optimizations.
Class that stores computed placement from labeling engine.
QgsRectangle extent() const
Returns the current zoom exent of the map canvas.
This class is responsible for keeping cache of rendered images of individual layers.
QgsMapCanvas(QWidget *parent=0, const char *name=0)
Constructor.
void setMapUnits(QGis::UnitType mapUnits)
Set map units (needed by project properties dialog)
Custom exception class for Coordinate Reference System related exceptions.
const QPoint & pos() const
void updateOverview()
bool isParallelRenderingEnabled() const
Check whether the layers are rendered in parallel or sequentially.
PreviewMode mode() const
Returns the mode used for the preview effect.
Q_DECL_DEPRECATED void setDirty(bool _dirty)
Flag the canvas as dirty and needed a refresh.
static void setSpecialColumn(const QString &name, QVariant value)
Assign a special column.
QDomElement createElement(const QString &tagName)
QPoint rubberStartPoint
Beginning point of a rubber band.
Errors errors() const
List of errors that happened during the rendering job - available when the rendering has been finishe...
Class that does synchronization between QgsMapCanvas and its associated QgsMapRenderer: ...
Definition: qgsmapcanvas.h:700
QString absolutePath() const
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:202
virtual QgsLabelingResults * takeLabelingResults()=0
Get pointer to internal labeling engine (in order to get access to the results)
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
void zoomIn()
Zoom in with fixed factor.
QGis::UnitType mapUnits() const
virtual void waitForFinished() override
Block until the job has finished.
Represents a vector layer which manages a vector based data sets.
bool begin(QPaintDevice *device)
virtual void updatePosition()
called on changed extent or resize event to update position of the item
int selectedFeatureCount()
The number of features that are selected in this layer.
QString arg(qlonglong a, int fieldWidth, int base, const QChar &fillChar) const
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:187
void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy)
static QgsCRSCache * instance()
Definition: qgscrscache.cpp:87
QgsPoint center() const
Center point of the rectangle.
Definition: qgsrectangle.h:212
QgsMapLayer * layer()
Definition: qgsmapcanvas.h:87
void extentsChanged()
Emitted when the extents of the map change.
QgsPoint toMapPoint(qreal x, qreal y) const
iterator begin()
int renderingTime() const
Find out how log it took to finish the job (in miliseconds)
void destroyed(QObject *obj)
QgsMapLayer * layer(int index)
return the map layer at position index in the layer stack
virtual bool isActive() const =0
Tell whether the rendering job is currently running in background.
Q_DECL_DEPRECATED void updateMap()
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:162
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:207
void setCrsTransformEnabled(bool enabled)
sets whether to use projections for this layer set
void panActionEnd(QPoint releasePoint)
Ends pan action and redraws the canvas.
void mapUnitsChanged()
Emmitted when map units are changed.
QStringList layerSet() const
QgsRectangle fullExtent() const
Returns the combined exent for all layers on the map canvas.
void grabGesture(Qt::GestureType gesture, QFlags< Qt::GestureFlag > flags)
void layersChanged()
Emitted when a new set of layers has been received.
void setSingleShot(bool singleShot)
QgsRectangle boundingBoxOfSelected()
Returns the bounding box of the selected features.
void writeXML(QDomNode &theNode, QDomDocument &theDoc)
void mapToolSet(QgsMapTool *tool)
Emit map tool changed event.
void scale(double scaleFactor, const QgsPoint *c=0)
Scale the rectangle around its center point.
virtual void resizeEvent(QResizeEvent *event)