QGIS API Documentation  2.12.0-Lyon
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  //build the expression context
662  QgsExpressionContext expressionContext;
663  expressionContext << QgsExpressionContextUtils::globalScope()
666  << new QgsExpressionContextScope( mExpressionContextScope );
667 
668  mSettings.setExpressionContext( expressionContext );
669 
670  // create the renderer job
671  Q_ASSERT( mJob == 0 );
672  mJobCancelled = false;
673  if ( mUseParallelRendering )
674  mJob = new QgsMapRendererParallelJob( mSettings );
675  else
676  mJob = new QgsMapRendererSequentialJob( mSettings );
677  connect( mJob, SIGNAL( finished() ), SLOT( rendererJobFinished() ) );
678  mJob->setCache( mCache );
679 
680  QStringList layersForGeometryCache;
681  Q_FOREACH ( const QString& id, mSettings.layers() )
682  {
683  if ( QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( id ) ) )
684  {
685  if ( vl->isEditable() )
686  layersForGeometryCache << id;
687  }
688  }
689  mJob->setRequestedGeometryCacheForLayers( layersForGeometryCache );
690 
691  mJob->start();
692 
693  mMapUpdateTimer.start();
694 
695  emit renderStarting();
696 }
697 
698 
699 void QgsMapCanvas::rendererJobFinished()
700 {
701  QgsDebugMsg( QString( "CANVAS finish! %1" ).arg( !mJobCancelled ) );
702 
703  mMapUpdateTimer.stop();
704 
705  // TODO: would be better to show the errors in message bar
706  Q_FOREACH ( const QgsMapRendererJob::Error& error, mJob->errors() )
707  {
708  QgsMessageLog::logMessage( error.layerID + " :: " + error.message, tr( "Rendering" ) );
709  }
710 
711  if ( !mJobCancelled )
712  {
713  // take labeling results before emitting renderComplete, so labeling map tools
714  // connected to signal work with correct results
715  delete mLabelingResults;
716  mLabelingResults = mJob->takeLabelingResults();
717 
718  QImage img = mJob->renderedImage();
719 
720  // emit renderComplete to get our decorations drawn
721  QPainter p( &img );
722  emit renderComplete( &p );
723 
724  QSettings settings;
725  if ( settings.value( "/Map/logCanvasRefreshEvent", false ).toBool() )
726  {
727  QString logMsg = tr( "Canvas refresh: %1 ms" ).arg( mJob->renderingTime() );
728  QgsMessageLog::logMessage( logMsg, tr( "Rendering" ) );
729  }
730 
731  if ( mDrawRenderingStats )
732  {
733  int w = img.width(), h = img.height();
734  QFont fnt = p.font();
735  fnt.setBold( true );
736  p.setFont( fnt );
737  int lh = p.fontMetrics().height() * 2;
738  QRect r( 0, h - lh, w, lh );
739  p.setPen( Qt::NoPen );
740  p.setBrush( QColor( 0, 0, 0, 110 ) );
741  p.drawRect( r );
742  p.setPen( Qt::white );
743  QString msg = QString( "%1 :: %2 ms" ).arg( mUseParallelRendering ? "PARALLEL" : "SEQUENTIAL" ).arg( mJob->renderingTime() );
744  p.drawText( r, msg, QTextOption( Qt::AlignCenter ) );
745  }
746 
747  p.end();
748 
749  mMap->setContent( img, imageRect( img, mJob->mapSettings() ) );
750  }
751 
752  // now we are in a slot called from mJob - do not delete it immediately
753  // so the class is still valid when the execution returns to the class
754  mJob->deleteLater();
755  mJob = 0;
756 
757  emit mapCanvasRefreshed();
758 }
759 
760 QgsRectangle QgsMapCanvas::imageRect( const QImage& img, const QgsMapSettings& mapSettings )
761 {
762  // This is a hack to pass QgsMapCanvasItem::setRect what it
763  // expects (encoding of position and size of the item)
764  const QgsMapToPixel& m2p = mapSettings.mapToPixel();
765  QgsPoint topLeft = m2p.toMapPoint( 0, 0 );
766  double res = m2p.mapUnitsPerPixel();
767  QgsRectangle rect( topLeft.x(), topLeft.y(), topLeft.x() + img.width()*res, topLeft.y() - img.height()*res );
768  return rect;
769 }
770 
771 void QgsMapCanvas::mapUpdateTimeout()
772 {
773  const QImage& img = mJob->renderedImage();
774  mMap->setContent( img, imageRect( img, mJob->mapSettings() ) );
775 }
776 
778 {
779  if ( mJob )
780  {
781  QgsDebugMsg( "CANVAS stop rendering!" );
782  mJobCancelled = true;
783  mJob->cancel();
784  Q_ASSERT( mJob == 0 ); // no need to delete here: already deleted in finished()
785  }
786 }
787 
789 {
790 }
791 
792 //the format defaults to "PNG" if not specified
793 void QgsMapCanvas::saveAsImage( const QString& theFileName, QPixmap * theQPixmap, const QString& theFormat )
794 {
795  //
796  //check if the optional QPaintDevice was supplied
797  //
798  if ( theQPixmap != NULL )
799  {
800  // render
801  QPainter painter;
802  painter.begin( theQPixmap );
803  QgsMapRendererCustomPainterJob job( mSettings, &painter );
804  job.start();
805  job.waitForFinished();
806  emit renderComplete( &painter );
807  painter.end();
808 
809  theQPixmap->save( theFileName, theFormat.toLocal8Bit().data() );
810  }
811  else //use the map view
812  {
813  mMap->contentImage().save( theFileName, theFormat.toLocal8Bit().data() );
814  }
815  //create a world file to go with the image...
817  QString myHeader;
818  // note: use 17 places of precision for all numbers output
819  //Pixel XDim
820  myHeader += qgsDoubleToString( mapUnitsPerPixel() ) + "\r\n";
821  //Rotation on y axis - hard coded
822  myHeader += "0 \r\n";
823  //Rotation on x axis - hard coded
824  myHeader += "0 \r\n";
825  //Pixel YDim - almost always negative - see
826  //http://en.wikipedia.org/wiki/World_file#cite_note-2
827  myHeader += "-" + qgsDoubleToString( mapUnitsPerPixel() ) + "\r\n";
828  //Origin X (center of top left cell)
829  myHeader += qgsDoubleToString( myRect.xMinimum() + ( mapUnitsPerPixel() / 2 ) ) + "\r\n";
830  //Origin Y (center of top left cell)
831  myHeader += qgsDoubleToString( myRect.yMaximum() - ( mapUnitsPerPixel() / 2 ) ) + "\r\n";
832  QFileInfo myInfo = QFileInfo( theFileName );
833  // allow dotted names
834  QString myWorldFileName = myInfo.absolutePath() + "/" + myInfo.completeBaseName() + "." + theFormat + "w";
835  QFile myWorldFile( myWorldFileName );
836  if ( !myWorldFile.open( QIODevice::WriteOnly ) ) //don't use QIODevice::Text
837  {
838  return;
839  }
840  QTextStream myStream( &myWorldFile );
841  myStream << myHeader;
842 } // saveAsImage
843 
844 
845 
847 {
848  return mapSettings().visibleExtent();
849 } // extent
850 
852 {
853  return mapSettings().fullExtent();
854 } // extent
855 
856 
858 {
859  QgsRectangle current = extent();
860 
861  if ( r == current )
862  return;
863 
864  if ( r.isEmpty() )
865  {
866  if ( !mSettings.hasValidSettings() )
867  {
868  // we can't even just move the map center
869  QgsDebugMsg( "Empty extent - ignoring" );
870  return;
871  }
872 
873  // ### QGIS 3: do not allow empty extent - require users to call setCenter() explicitly
874  QgsDebugMsg( "Empty extent - keeping old scale with new center!" );
875  setCenter( r.center() );
876  }
877  else
878  {
879  mSettings.setExtent( r );
880  }
881  emit extentsChanged();
882  updateScale();
883  if ( mLastExtent.size() > 20 )
884  mLastExtent.removeAt( 0 );
885 
886  //clear all extent items after current index
887  for ( int i = mLastExtent.size() - 1; i > mLastExtentIndex; i-- )
888  {
889  mLastExtent.removeAt( i );
890  }
891 
892  mLastExtent.append( extent() );
893 
894  // adjust history to no more than 20
895  if ( mLastExtent.size() > 20 )
896  {
897  mLastExtent.removeAt( 0 );
898  }
899 
900  // the last item is the current extent
901  mLastExtentIndex = mLastExtent.size() - 1;
902 
903  // update controls' enabled state
904  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
905  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
906  // notify canvas items of change
908 
909 } // setExtent
910 
911 void QgsMapCanvas::setCenter( const QgsPoint& center )
912 {
914  double x = center.x();
915  double y = center.y();
916  setExtent(
917  QgsRectangle(
918  x - r.width() / 2.0, y - r.height() / 2.0,
919  x + r.width() / 2.0, y + r.height() / 2.0
920  )
921  );
922 } // setCenter
923 
925 {
927  return r.center();
928 }
929 
930 
932 {
933  return mapSettings().rotation();
934 } // rotation
935 
936 void QgsMapCanvas::setRotation( double degrees )
937 {
938  if ( !rotationEnabled() )
939  return;
940 
941  double current = rotation();
942 
943  if ( degrees == current )
944  return;
945 
946  mSettings.setRotation( degrees );
947  emit rotationChanged( degrees );
948  emit extentsChanged(); // visible extent changes with rotation
949 
950  // notify canvas items of change (needed?)
952 
953 } // setRotation
954 
955 
957 {
958  emit scaleChanged( mapSettings().scale() );
959 }
960 
961 
963 {
964  refresh();
965 } // clear
966 
967 
968 
970 {
972  // If the full extent is an empty set, don't do the zoom
973  if ( !extent.isEmpty() )
974  {
975  // Add a 5% margin around the full extent
976  extent.scale( 1.05 );
977  setExtent( extent );
978  }
979  refresh();
980 
981 } // zoomToFullExtent
982 
983 
984 
986 {
987  if ( mLastExtentIndex > 0 )
988  {
989  mLastExtentIndex--;
990  mSettings.setExtent( mLastExtent[mLastExtentIndex] );
991  emit extentsChanged();
992  updateScale();
993  refresh();
994  // update controls' enabled state
995  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
996  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
997  // notify canvas items of change
999  }
1000 
1001 } // zoomToPreviousExtent
1002 
1004 {
1005  if ( mLastExtentIndex < mLastExtent.size() - 1 )
1006  {
1007  mLastExtentIndex++;
1008  mSettings.setExtent( mLastExtent[mLastExtentIndex] );
1009  emit extentsChanged();
1010  updateScale();
1011  refresh();
1012  // update controls' enabled state
1013  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
1014  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
1015  // notify canvas items of change
1017  }
1018 }// zoomToNextExtent
1019 
1021 {
1022  mLastExtent.clear(); // clear the zoom history list
1023  mLastExtent.append( extent() ) ; // set the current extent in the list
1024  mLastExtentIndex = mLastExtent.size() - 1;
1025  // update controls' enabled state
1026  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
1027  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
1028 }// clearExtentHistory
1029 
1030 
1032 {
1034 }
1035 
1037 {
1038  if ( layer == NULL )
1039  {
1040  // use current layer by default
1041  layer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
1042  }
1043 
1044  if ( layer == NULL )
1045  {
1046  return;
1047  }
1048 
1049  if ( layer->selectedFeatureCount() == 0 )
1050  {
1051  return;
1052  }
1053 
1055 
1056  // no selected features, only one selected point feature
1057  //or two point features with the same x- or y-coordinates
1058  if ( rect.isEmpty() )
1059  {
1060  // zoom in
1061  QgsPoint c = rect.center();
1062  rect = extent();
1063  rect.scale( 1.0, &c );
1064  }
1065  //zoom to an area
1066  else
1067  {
1068  // Expand rect to give a bit of space around the selected
1069  // objects so as to keep them clear of the map boundaries
1070  // The same 5% should apply to all margins.
1071  rect.scale( 1.05 );
1072  }
1073 
1074  setExtent( rect );
1075  refresh();
1076 } // zoomToSelected
1077 
1079 {
1080  if ( layer == NULL )
1081  {
1082  // use current layer by default
1083  layer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
1084  }
1085 
1086  if ( layer == NULL )
1087  {
1088  return;
1089  }
1090 
1091  if ( layer->selectedFeatureCount() == 0 )
1092  {
1093  return;
1094  }
1095 
1097  setExtent( QgsRectangle( rect.center(), rect.center() ) );
1098  refresh();
1099 } // panToSelected
1100 
1102 {
1103  if ( mCanvasProperties->mouseButtonDown || mCanvasProperties->panSelectorDown )
1104  {
1105  emit keyPressed( e );
1106  return;
1107  }
1108 
1109  QPainter paint;
1110  QPen pen( Qt::gray );
1111  QgsPoint ll, ur;
1112 
1113  if ( ! mCanvasProperties->mouseButtonDown )
1114  {
1115  // Don't want to interfer with mouse events
1116 
1117  QgsRectangle currentExtent = mapSettings().visibleExtent();
1118  double dx = qAbs(( currentExtent.xMaximum() - currentExtent.xMinimum() ) / 4 );
1119  double dy = qAbs(( currentExtent.yMaximum() - currentExtent.yMinimum() ) / 4 );
1120 
1121  switch ( e->key() )
1122  {
1123  case Qt::Key_Left:
1124  QgsDebugMsg( "Pan left" );
1125 
1126  currentExtent.setXMinimum( currentExtent.xMinimum() - dx );
1127  currentExtent.setXMaximum( currentExtent.xMaximum() - dx );
1128  setExtent( currentExtent );
1129  refresh();
1130  break;
1131 
1132  case Qt::Key_Right:
1133  QgsDebugMsg( "Pan right" );
1134 
1135  currentExtent.setXMinimum( currentExtent.xMinimum() + dx );
1136  currentExtent.setXMaximum( currentExtent.xMaximum() + dx );
1137  setExtent( currentExtent );
1138  refresh();
1139  break;
1140 
1141  case Qt::Key_Up:
1142  QgsDebugMsg( "Pan up" );
1143 
1144  currentExtent.setYMaximum( currentExtent.yMaximum() + dy );
1145  currentExtent.setYMinimum( currentExtent.yMinimum() + dy );
1146  setExtent( currentExtent );
1147  refresh();
1148  break;
1149 
1150  case Qt::Key_Down:
1151  QgsDebugMsg( "Pan down" );
1152 
1153  currentExtent.setYMaximum( currentExtent.yMaximum() - dy );
1154  currentExtent.setYMinimum( currentExtent.yMinimum() - dy );
1155  setExtent( currentExtent );
1156  refresh();
1157  break;
1158 
1159 
1160 
1161  case Qt::Key_Space:
1162  QgsDebugMsg( "Pressing pan selector" );
1163 
1164  //mCanvasProperties->dragging = true;
1165  if ( ! e->isAutoRepeat() )
1166  {
1167  mCanvasProperties->panSelectorDown = true;
1168  mCanvasProperties->rubberStartPoint = mCanvasProperties->mouseLastXY;
1169  }
1170  break;
1171 
1172  case Qt::Key_PageUp:
1173  QgsDebugMsg( "Zoom in" );
1174  zoomIn();
1175  break;
1176 
1177  case Qt::Key_PageDown:
1178  QgsDebugMsg( "Zoom out" );
1179  zoomOut();
1180  break;
1181 
1182 #if 0
1183  case Qt::Key_P:
1184  mUseParallelRendering = !mUseParallelRendering;
1185  refresh();
1186  break;
1187 
1188  case Qt::Key_S:
1189  mDrawRenderingStats = !mDrawRenderingStats;
1190  refresh();
1191  break;
1192 #endif
1193 
1194  default:
1195  // Pass it on
1196  if ( mMapTool )
1197  {
1198  mMapTool->keyPressEvent( e );
1199  }
1200  else e->ignore();
1201 
1202  QgsDebugMsg( "Ignoring key: " + QString::number( e->key() ) );
1203  }
1204  }
1205 
1206  emit keyPressed( e );
1207 
1208 } //keyPressEvent()
1209 
1211 {
1212  QgsDebugMsg( "keyRelease event" );
1213 
1214  switch ( e->key() )
1215  {
1216  case Qt::Key_Space:
1217  if ( !e->isAutoRepeat() && mCanvasProperties->panSelectorDown )
1218  {
1219  QgsDebugMsg( "Releasing pan selector" );
1220 
1221  mCanvasProperties->panSelectorDown = false;
1222  panActionEnd( mCanvasProperties->mouseLastXY );
1223  }
1224  break;
1225 
1226  default:
1227  // Pass it on
1228  if ( mMapTool )
1229  {
1230  mMapTool->keyReleaseEvent( e );
1231  }
1232  else e->ignore();
1233 
1234  QgsDebugMsg( "Ignoring key release: " + QString::number( e->key() ) );
1235  }
1236 
1237  emit keyReleased( e );
1238 
1239 } //keyReleaseEvent()
1240 
1241 
1243 {
1244  // call handler of current map tool
1245  if ( mMapTool )
1246  {
1248  mMapTool->canvasDoubleClickEvent( me.data() );
1249  }
1250 }// mouseDoubleClickEvent
1251 
1252 
1254 {
1255  //use middle mouse button for panning, map tools won't receive any events in that case
1256  if ( e->button() == Qt::MidButton )
1257  {
1258  mCanvasProperties->panSelectorDown = true;
1259  mCanvasProperties->rubberStartPoint = mCanvasProperties->mouseLastXY;
1260  }
1261  else
1262  {
1263 
1264  // call handler of current map tool
1265  if ( mMapTool )
1266  {
1268  mMapTool->canvasPressEvent( me.data() );
1269  }
1270  }
1271 
1272  if ( mCanvasProperties->panSelectorDown )
1273  {
1274  return;
1275  }
1276 
1277  mCanvasProperties->mouseButtonDown = true;
1278  mCanvasProperties->rubberStartPoint = e->pos();
1279 
1280 } // mousePressEvent
1281 
1282 
1284 {
1285  //use middle mouse button for panning, map tools won't receive any events in that case
1286  if ( e->button() == Qt::MidButton )
1287  {
1288  mCanvasProperties->panSelectorDown = false;
1289  panActionEnd( mCanvasProperties->mouseLastXY );
1290  }
1291  else
1292  {
1293  // call handler of current map tool
1294  if ( mMapTool )
1295  {
1296  // right button was pressed in zoom tool? return to previous non zoom tool
1297  if ( e->button() == Qt::RightButton && mMapTool->isTransient() )
1298  {
1299  QgsDebugMsg( "Right click in map tool zoom or pan, last tool is " +
1300  QString( mLastNonZoomMapTool ? "not null." : "null." ) );
1301 
1302  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
1303 
1304  // change to older non-zoom tool
1305  if ( mLastNonZoomMapTool
1306  && ( !mLastNonZoomMapTool->isEditTool() || ( vlayer && vlayer->isEditable() ) ) )
1307  {
1308  QgsMapTool* t = mLastNonZoomMapTool;
1309  mLastNonZoomMapTool = NULL;
1310  setMapTool( t );
1311  }
1312  return;
1313  }
1315  mMapTool->canvasReleaseEvent( me.data() );
1316  }
1317  }
1318 
1319 
1320  mCanvasProperties->mouseButtonDown = false;
1321 
1322  if ( mCanvasProperties->panSelectorDown )
1323  return;
1324 
1325 } // mouseReleaseEvent
1326 
1328 {
1330  mResizeTimer->start( 500 );
1331 
1332  QSize lastSize = viewport()->size();
1333 
1334  mSettings.setOutputSize( lastSize );
1335  mMapRenderer->setOutputSize( lastSize, mSettings.outputDpi() );
1336 
1337  mScene->setSceneRect( QRectF( 0, 0, lastSize.width(), lastSize.height() ) );
1338 
1339  moveCanvasContents( true );
1340 
1341  // notify canvas items of change
1343 
1344  updateScale();
1345 
1346  //refresh();
1347 
1348  emit extentsChanged();
1349 }
1350 
1352 {
1353  // no custom event handling anymore
1354 
1356 } // paintEvent
1357 
1359 {
1360  QList<QGraphicsItem*> list = mScene->items();
1362  while ( it != list.end() )
1363  {
1364  QgsMapCanvasItem* item = dynamic_cast<QgsMapCanvasItem *>( *it );
1365 
1366  if ( item )
1367  {
1368  item->updatePosition();
1369  }
1370 
1371  ++it;
1372  }
1373 }
1374 
1375 
1377 {
1378  // Zoom the map canvas in response to a mouse wheel event. Moving the
1379  // wheel forward (away) from the user zooms in
1380 
1381  QgsDebugMsg( "Wheel event delta " + QString::number( e->delta() ) );
1382 
1383  if ( mMapTool )
1384  {
1385  mMapTool->wheelEvent( e );
1386  }
1387 
1389  {
1390  // leave the wheel for map tools if any modifier pressed
1391  return;
1392  }
1393 
1394  switch ( mWheelAction )
1395  {
1396  case WheelZoom:
1397  // zoom without changing extent
1398  if ( e->delta() > 0 )
1399  zoomIn();
1400  else
1401  zoomOut();
1402  break;
1403 
1404  case WheelZoomAndRecenter:
1405  // zoom and don't change extent
1406  zoomWithCenter( e->x(), e->y(), e->delta() > 0 );
1407  break;
1408 
1410  {
1411  // zoom map to mouse cursor
1412  double scaleFactor = e->delta() > 0 ? 1 / mWheelZoomFactor : mWheelZoomFactor;
1413 
1414  QgsPoint oldCenter = center();
1415  QgsPoint mousePos( getCoordinateTransform()->toMapPoint( e->x(), e->y() ) );
1416  QgsPoint newCenter( mousePos.x() + (( oldCenter.x() - mousePos.x() ) * scaleFactor ),
1417  mousePos.y() + (( oldCenter.y() - mousePos.y() ) * scaleFactor ) );
1418 
1419  zoomByFactor( scaleFactor, &newCenter );
1420  break;
1421  }
1422 
1423  case WheelNothing:
1424  // well, nothing!
1425  break;
1426  }
1427 }
1428 
1429 void QgsMapCanvas::setWheelAction( WheelAction action, double factor )
1430 {
1431  mWheelAction = action;
1432  mWheelZoomFactor = factor;
1433 }
1434 
1436 {
1437  zoomByFactor( 1 / mWheelZoomFactor );
1438 }
1439 
1441 {
1442  zoomByFactor( mWheelZoomFactor );
1443 }
1444 
1445 void QgsMapCanvas::zoomScale( double newScale )
1446 {
1447  zoomByFactor( newScale / scale() );
1448 }
1449 
1450 void QgsMapCanvas::zoomWithCenter( int x, int y, bool zoomIn )
1451 {
1452  double scaleFactor = ( zoomIn ? 1 / mWheelZoomFactor : mWheelZoomFactor );
1453 
1454  // transform the mouse pos to map coordinates
1457  r.scale( scaleFactor, &center );
1458  setExtent( r );
1459  refresh();
1460 }
1461 
1463 {
1464  mCanvasProperties->mouseLastXY = e->pos();
1465 
1466  if ( mCanvasProperties->panSelectorDown )
1467  {
1468  panAction( e );
1469  }
1470  else
1471  {
1472  // call handler of current map tool
1473  if ( mMapTool )
1474  {
1476  mMapTool->canvasMoveEvent( me.data() );
1477  }
1478  }
1479 
1480  // show x y on status bar
1481  QPoint xy = e->pos();
1483  emit xyCoordinates( coord );
1484 } // mouseMoveEvent
1485 
1486 
1487 
1490 {
1491  if ( !tool )
1492  return;
1493 
1494  if ( mMapTool )
1495  {
1496  disconnect( mMapTool, SIGNAL( destroyed() ), this, SLOT( mapToolDestroyed() ) );
1497  mMapTool->deactivate();
1498  }
1499 
1500  if ( tool->isTransient() && mMapTool && !mMapTool->isTransient() )
1501  {
1502  // if zoom or pan tool will be active, save old tool
1503  // to bring it back on right click
1504  // (but only if it wasn't also zoom or pan tool)
1505  mLastNonZoomMapTool = mMapTool;
1506  }
1507  else
1508  {
1509  mLastNonZoomMapTool = NULL;
1510  }
1511 
1512  QgsMapTool* oldTool = mMapTool;
1513 
1514  // set new map tool and activate it
1515  mMapTool = tool;
1516  if ( mMapTool )
1517  {
1518  connect( mMapTool, SIGNAL( destroyed() ), this, SLOT( mapToolDestroyed() ) );
1519  mMapTool->activate();
1520  }
1521 
1522  emit mapToolSet( mMapTool );
1523  emit mapToolSet( mMapTool, oldTool );
1524 } // setMapTool
1525 
1527 {
1528  if ( mMapTool && mMapTool == tool )
1529  {
1530  mMapTool->deactivate();
1531  mMapTool = NULL;
1532  emit mapToolSet( NULL );
1533  emit mapToolSet( NULL, mMapTool );
1534  setCursor( Qt::ArrowCursor );
1535  }
1536 
1537  if ( mLastNonZoomMapTool && mLastNonZoomMapTool == tool )
1538  {
1539  mLastNonZoomMapTool = NULL;
1540  }
1541 }
1542 
1544 void QgsMapCanvas::setCanvasColor( const QColor & theColor )
1545 {
1546  // background of map's pixmap
1547  mSettings.setBackgroundColor( theColor );
1548 
1549  // background of the QGraphicsView
1550  QBrush bgBrush( theColor );
1551  setBackgroundBrush( bgBrush );
1552 #if 0
1553  QPalette palette;
1554  palette.setColor( backgroundRole(), theColor );
1555  setPalette( palette );
1556 #endif
1557 
1558  // background of QGraphicsScene
1559  mScene->setBackgroundBrush( bgBrush );
1560 } // setBackgroundColor
1561 
1563 {
1564  return mScene->backgroundBrush().color();
1565 }
1566 
1568 {
1569  mSettings.setSelectionColor( color );
1570 }
1571 
1573 {
1574  return mapSettings().layers().size();
1575 } // layerCount
1576 
1577 
1579 {
1580  QList<QgsMapLayer*> lst;
1581  Q_FOREACH ( const QString& layerID, mapSettings().layers() )
1582  {
1584  if ( layer )
1585  lst.append( layer );
1586  }
1587  return lst;
1588 }
1589 
1590 
1592 {
1593  // called when a layer has changed visibility setting
1594 
1595  refresh();
1596 
1597 } // layerStateChange
1598 
1600 {
1601  // called when a layer's CRS has been changed
1602  QObject *theSender = sender();
1603  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( theSender );
1604  QString destAuthId = mSettings.destinationCrs().authid();
1605  getDatumTransformInfo( layer, layer->crs().authid(), destAuthId );
1606 
1607 } // layerCrsChange
1608 
1609 
1610 void QgsMapCanvas::freeze( bool frz )
1611 {
1612  mFrozen = frz;
1613 } // freeze
1614 
1616 {
1617  return mFrozen;
1618 } // freeze
1619 
1620 
1622 {
1624  return mMap->paintDevice();
1626 }
1627 
1629 {
1630  return mapSettings().mapUnitsPerPixel();
1631 } // mapUnitsPerPixel
1632 
1633 
1635 {
1636  if ( mSettings.mapUnits() == u )
1637  return;
1638 
1639  QgsDebugMsg( "Setting map units to " + QString::number( static_cast<int>( u ) ) );
1640  mSettings.setMapUnits( u );
1641 
1642  updateScale();
1643 
1644  refresh(); // this will force the scale bar to be updated
1645 
1646  emit mapUnitsChanged();
1647 }
1648 
1649 
1651 {
1652  return mapSettings().mapUnits();
1653 }
1654 
1656 {
1657  return mSettings.layerStyleOverrides();
1658 }
1659 
1661 {
1662  if ( overrides == mSettings.layerStyleOverrides() )
1663  return;
1664 
1665  mSettings.setLayerStyleOverrides( overrides );
1667 }
1668 
1669 
1670 void QgsMapCanvas::setRenderFlag( bool theFlag )
1671 {
1672  mRenderFlag = theFlag;
1673 
1674  if ( mRenderFlag )
1675  {
1676  refresh();
1677  }
1678  else
1679  stopRendering();
1680 }
1681 
1682 #if 0
1683 void QgsMapCanvas::connectNotify( const char * signal )
1684 {
1685  Q_UNUSED( signal );
1686  QgsDebugMsg( "QgsMapCanvas connected to " + QString( signal ) );
1687 } //connectNotify
1688 #endif
1689 
1691 {
1692  if ( !mSettings.hasCrsTransformEnabled() )
1693  return;
1694 
1695  QString destAuthId = mSettings.destinationCrs().authid();
1696  Q_FOREACH ( const QString& layerID, mSettings.layers() )
1697  {
1699  if ( !layer )
1700  continue;
1701 
1702  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
1703  if ( vl && vl->geometryType() == QGis::NoGeometry )
1704  continue;
1705 
1706  // if there are more options, ask the user which datum transform to use
1707  if ( !mSettings.datumTransformStore().hasEntryForLayer( layer ) )
1708  getDatumTransformInfo( layer, layer->crs().authid(), destAuthId );
1709  }
1710 }
1711 
1712 
1713 
1715 {
1716  return mMapTool;
1717 }
1718 
1720 {
1721  // move map image and other items to standard position
1722  moveCanvasContents( true ); // true means reset
1723 
1724  // use start and end box points to calculate the extent
1725  QgsPoint start = getCoordinateTransform()->toMapCoordinates( mCanvasProperties->rubberStartPoint );
1726  QgsPoint end = getCoordinateTransform()->toMapCoordinates( releasePoint );
1727 
1728  // modify the center
1729  double dx = end.x() - start.x();
1730  double dy = end.y() - start.y();
1731  QgsPoint c = center();
1732  c.set( c.x() - dx, c.y() - dy );
1733  setCenter( c );
1734 
1735  refresh();
1736 }
1737 
1739 {
1740  Q_UNUSED( e );
1741 
1742  // move all map canvas items
1744 }
1745 
1747 {
1748  QPoint pnt( 0, 0 );
1749  if ( !reset )
1750  pnt += mCanvasProperties->mouseLastXY - mCanvasProperties->rubberStartPoint;
1751 
1752  setSceneRect( -pnt.x(), -pnt.y(), viewport()->size().width(), viewport()->size().height() );
1753 }
1754 
1756 {
1757  Q_UNUSED( mapLayer );
1758 }
1759 
1761 {
1762  return mCanvasProperties->mouseLastXY;
1763 }
1764 
1765 void QgsMapCanvas::setPreviewModeEnabled( bool previewEnabled )
1766 {
1767  if ( !mPreviewEffect )
1768  {
1769  return;
1770  }
1771 
1772  mPreviewEffect->setEnabled( previewEnabled );
1773 }
1774 
1776 {
1777  if ( !mPreviewEffect )
1778  {
1779  return false;
1780  }
1781 
1782  return mPreviewEffect->isEnabled();
1783 }
1784 
1786 {
1787  if ( !mPreviewEffect )
1788  {
1789  return;
1790  }
1791 
1792  mPreviewEffect->setMode( mode );
1793 }
1794 
1796 {
1797  if ( !mPreviewEffect )
1798  {
1800  }
1801 
1802  return mPreviewEffect->mode();
1803 }
1804 
1806 {
1807  if ( !mSnappingUtils )
1808  {
1809  // associate a dummy instance, but better than null pointer
1810  QgsMapCanvas* c = const_cast<QgsMapCanvas*>( this );
1811  c->mSnappingUtils = new QgsMapCanvasSnappingUtils( c, c );
1812  }
1813  return mSnappingUtils;
1814 }
1815 
1817 {
1818  mSnappingUtils = utils;
1819 }
1820 
1822 {
1823  QDomNodeList nodes = doc.elementsByTagName( "mapcanvas" );
1824  if ( nodes.count() )
1825  {
1826  QDomNode node = nodes.item( 0 );
1827 
1828  QgsMapSettings tmpSettings;
1829  tmpSettings.readXML( node );
1830  setMapUnits( tmpSettings.mapUnits() );
1832  setDestinationCrs( tmpSettings.destinationCrs() );
1833  setExtent( tmpSettings.extent() );
1834  setRotation( tmpSettings.rotation() );
1835  mSettings.datumTransformStore() = tmpSettings.datumTransformStore();
1836 
1837  clearExtentHistory(); // clear the extent history on project load
1838  }
1839  else
1840  {
1841  QgsDebugMsg( "Couldn't read mapcanvas information from project" );
1842  }
1843 }
1844 
1846 {
1847  // create node "mapcanvas" and call mMapRenderer->writeXML()
1848 
1849  QDomNodeList nl = doc.elementsByTagName( "qgis" );
1850  if ( !nl.count() )
1851  {
1852  QgsDebugMsg( "Unable to find qgis element in project file" );
1853  return;
1854  }
1855  QDomNode qgisNode = nl.item( 0 ); // there should only be one, so zeroth element ok
1856 
1857  QDomElement mapcanvasNode = doc.createElement( "mapcanvas" );
1858  qgisNode.appendChild( mapcanvasNode );
1859 
1860  mSettings.writeXML( mapcanvasNode, doc );
1861  // TODO: store only units, extent, projections, dest CRS
1862 }
1863 
1865 void QgsMapCanvas::getDatumTransformInfo( const QgsMapLayer* ml, const QString& srcAuthId, const QString& destAuthId )
1866 {
1867  if ( !ml )
1868  {
1869  return;
1870  }
1871 
1872  //check if default datum transformation available
1873  QSettings s;
1874  QString settingsString = "/Projections/" + srcAuthId + "//" + destAuthId;
1875  QVariant defaultSrcTransform = s.value( settingsString + "_srcTransform" );
1876  QVariant defaultDestTransform = s.value( settingsString + "_destTransform" );
1877  if ( defaultSrcTransform.isValid() && defaultDestTransform.isValid() )
1878  {
1879  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, defaultSrcTransform.toInt(), defaultDestTransform.toInt() );
1880  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, defaultSrcTransform.toInt(), defaultDestTransform.toInt() );
1881  return;
1882  }
1883 
1884  const QgsCoordinateReferenceSystem& srcCRS = QgsCRSCache::instance()->crsByAuthId( srcAuthId );
1885  const QgsCoordinateReferenceSystem& destCRS = QgsCRSCache::instance()->crsByAuthId( destAuthId );
1886 
1887  if ( !s.value( "/Projections/showDatumTransformDialog", false ).toBool() )
1888  {
1889  // just use the default transform
1890  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, -1, -1 );
1891  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, -1, -1 );
1892  return;
1893  }
1894 
1895  //get list of datum transforms
1897  if ( dt.size() < 2 )
1898  {
1899  return;
1900  }
1901 
1902  //if several possibilities: present dialog
1903  QgsDatumTransformDialog d( ml->name(), dt );
1904  d.setDatumTransformInfo( srcCRS.authid(), destCRS.authid() );
1905  if ( d.exec() == QDialog::Accepted )
1906  {
1907  int srcTransform = -1;
1908  int destTransform = -1;
1909  QList<int> t = d.selectedDatumTransform();
1910  if ( t.size() > 0 )
1911  {
1912  srcTransform = t.at( 0 );
1913  }
1914  if ( t.size() > 1 )
1915  {
1916  destTransform = t.at( 1 );
1917  }
1918  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, srcTransform, destTransform );
1919  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, srcTransform, destTransform );
1920  if ( d.rememberSelection() )
1921  {
1922  s.setValue( settingsString + "_srcTransform", srcTransform );
1923  s.setValue( settingsString + "_destTransform", destTransform );
1924  }
1925  }
1926  else
1927  {
1928  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, -1, -1 );
1929  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, -1, -1 );
1930  }
1931 }
1932 
1933 void QgsMapCanvas::zoomByFactor( double scaleFactor, const QgsPoint* center )
1934 {
1936  r.scale( scaleFactor, center );
1937  setExtent( r );
1938  refresh();
1939 }
1940 
1942 {
1943  // Find out which layer it was that sent the signal.
1944  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() );
1945  emit selectionChanged( layer );
1946  refresh();
1947 }
1948 
1950 {
1951  // By default graphics view delegates the drag events to graphics items.
1952  // But we do not want that and by ignoring the drag enter we let the
1953  // parent (e.g. QgisApp) to handle drops of map layers etc.
1954  e->ignore();
1955 }
1956 
1957 void QgsMapCanvas::mapToolDestroyed()
1958 {
1959  QgsDebugMsg( "maptool destroyed" );
1960  mMapTool = 0;
1961 }
1962 
1963 #ifdef HAVE_TOUCH
1964 bool QgsMapCanvas::event( QEvent * e )
1965 {
1966  bool done = false;
1967  if ( e->type() == QEvent::Gesture )
1968  {
1969  // call handler of current map tool
1970  if ( mMapTool )
1971  {
1972  done = mMapTool->gestureEvent( static_cast<QGestureEvent*>( e ) );
1973  }
1974  }
1975  else
1976  {
1977  // pass other events to base class
1978  done = QGraphicsView::event( e );
1979  }
1980  return done;
1981 }
1982 #endif
1983 
1985 {
1986  return QSettings().value( "/qgis/canvasRotation", true ).toBool();
1987 }
1988 
1989 void QgsMapCanvas::enableRotation( bool enable )
1990 {
1991  QSettings().setValue( "/qgis/canvasRotation", enable );
1992 }
1993 
1995 {
1996  // reload all layers in canvas
1997  for ( int i = 0; i < layerCount(); i++ )
1998  {
1999  QgsMapLayer *l = layer( i );
2000  if ( l )
2001  l->reload();
2002  }
2003 
2004  // clear the cache
2005  clearCache();
2006 
2007  // and then refresh
2008  refresh();
2009 }
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.
virtual void canvasMoveEvent(QgsMapMouseEvent *e)
Mouse move event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:145
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)
Freeze/thaw the map canvas.
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()
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Setter for stored overrides of styles for layers.
A widget that displays an overview map.
QDomNode appendChild(const QDomNode &newChild)
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:171
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:196
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
QList< QGraphicsItem * > items() const
UnitType
Map units that qgis supports.
Definition: qgis.h:147
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.
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:390
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:76
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
QMap< QString, QString > layerStyleOverrides() const
Get map of map layer style overrides (key: layer ID, value: style name) where a different style shoul...
void moveCanvasContents(bool reset=false)
called when panning is in action, reset indicates end of panning
A QgsMapMouseEvent is the result of a user interaction with the mouse on a QgsMapCanvas.
void setSceneRect(const QRectF &rect)
bool isVisible() const
Definition: qgsmapcanvas.h:85
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
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Set map of map layer style overrides (key: layer ID, value: style name) where a different style shoul...
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
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.
void setLayers(const QStringList &layers)
Set list of layer IDs for map rendering.
void mousePressEvent(QMouseEvent *e) override
Overridden mouse press event.
QMap< QString, QString > layerStyleOverrides() const
Getter for stored overrides of styles for layers.
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:107
double x() const
Get the x value of the point.
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...
virtual void canvasPressEvent(QgsMapMouseEvent *e)
Mouse press event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:155
void setCache(QgsMapRendererCache *cache)
Assign a cache to be used for reading and storing rendered images of individual layers.
int size() const
QgsMapLayer * mapLayer(const QString &theLayerId)
Retrieve a pointer to a loaded layer by id.
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:83
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:769
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:175
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
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context...
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:201
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:186
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:176
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
QDomNodeList elementsByTagName(const QString &tagname) const
QgsMapCanvas * mCanvas
Definition: qgsmapcanvas.h:768
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 void logMessage(const QString &message, const QString &tag=QString::null, MessageLevel level=WARNING)
add a message to the instance (and create it if necessary)
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.
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:99
virtual bool isEditTool()
Check whether this MapTool performs an edit operation.
Definition: qgsmaptool.cpp:197
Single scope for storing variables and functions for use within a QgsExpressionContext.
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:165
void refresh()
renders overview and updates panning widget
void set(double x, double y)
Sets the x and y value of the point.
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
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.
T * data() const
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:630
QString qgsDoubleToString(const double &a, const int &precision=17)
Definition: qgis.h:257
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:170
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:50
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:391
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 QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object...
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:86
void saveAsImage(const QString &theFileName, QPixmap *QPixmap=0, const QString &="PNG")
Save the convtents of the map canvas to disk as an image.
void setSelectionColor(const QColor &color)
Set color that is used for drawing of selected vector features.
void layerStyleOverridesChanged()
Emitted when the configuration of overridden layer styles changes.
virtual void canvasDoubleClickEvent(QgsMapMouseEvent *e)
Mouse double click event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:150
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:181
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:353
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.
QString authid() const
Get the authority identifier for this srs.
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()
bool isFrozen()
Accessor for frozen status of canvas.
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:192
QString completeBaseName() const
double y() const
Get the y value of the point.
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
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.
static QgsExpressionContextScope * projectScope()
Creates a new scope which contains variables and functions relating to the current QGIS project...
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.
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:741
QString absolutePath() const
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:206
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:191
void setVerticalScrollBarPolicy(Qt::ScrollBarPolicy)
static QgsCRSCache * instance()
Definition: qgscrscache.cpp:87
QgsPoint center() const
Center point of the rectangle.
Definition: qgsrectangle.h:216
QgsMapLayer * layer()
Definition: qgsmapcanvas.h:88
void extentsChanged()
Emitted when the extents of the map change.
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:166
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:211
QgsPoint toMapPoint(double x, double y) const
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)
virtual void canvasReleaseEvent(QgsMapMouseEvent *e)
Mouse release event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:160