QGIS API Documentation  2.7.0-Master
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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"
47 #include "qgsmaplayer.h"
48 #include "qgsmaplayerregistry.h"
49 #include "qgsmaptoolpan.h"
50 #include "qgsmaptoolzoom.h"
51 #include "qgsmaptopixel.h"
52 #include "qgsmapoverviewcanvas.h"
53 #include "qgsmaprenderer.h"
54 #include "qgsmaprenderercache.h"
58 #include "qgsmessagelog.h"
59 #include "qgsmessageviewer.h"
60 #include "qgspallabeling.h"
61 #include "qgsproject.h"
62 #include "qgsrubberband.h"
63 #include "qgsvectorlayer.h"
64 #include <math.h>
65 
66 
69 {
70  public:
71 
73 
76 
78  QPoint mouseLastXY;
79 
82 
85 };
86 
87 
89  : QObject( canvas )
90  , mCanvas( canvas )
91  , mRenderer( renderer )
92  , mSyncingExtent( false )
93 {
94  connect( mCanvas, SIGNAL( extentsChanged() ), this, SLOT( onExtentC2R() ) );
95  connect( mRenderer, SIGNAL( extentsChanged() ), this, SLOT( onExtentR2C() ) );
96 
97  connect( mCanvas, SIGNAL( mapUnitsChanged() ), this, SLOT( onMapUnitsC2R() ) );
98  connect( mRenderer, SIGNAL( mapUnitsChanged() ), this, SLOT( onMapUnitsR2C() ) );
99 
100  connect( mCanvas, SIGNAL( rotationChanged( double ) ), this, SLOT( onMapRotationC2R() ) );
101  connect( mRenderer, SIGNAL( rotationChanged( double ) ), this, SLOT( onMapRotationR2C() ) );
102 
103  connect( mCanvas, SIGNAL( hasCrsTransformEnabledChanged( bool ) ), this, SLOT( onCrsTransformC2R() ) );
104  connect( mRenderer, SIGNAL( hasCrsTransformEnabled( bool ) ), this, SLOT( onCrsTransformR2C() ) );
105 
106  connect( mCanvas, SIGNAL( destinationCrsChanged() ), this, SLOT( onDestCrsC2R() ) );
107  connect( mRenderer, SIGNAL( destinationSrsChanged() ), this, SLOT( onDestCrsR2C() ) );
108 
109  connect( mCanvas, SIGNAL( layersChanged() ), this, SLOT( onLayersC2R() ) );
110  // TODO: layers R2C ? (should not happen!)
111 
112 }
113 
115 {
116  // protection against possible bounce back
117  if ( mSyncingExtent )
118  return;
119 
120  mSyncingExtent = true;
122  mSyncingExtent = false;
123 }
124 
126 {
127  // protection against possible bounce back
128  if ( mSyncingExtent )
129  return;
130 
131  mSyncingExtent = true;
133  mSyncingExtent = false;
134 }
135 
137 {
139 }
140 
142 {
144 }
145 
147 {
149 }
150 
152 {
154 }
155 
157 {
159 }
160 
162 {
164 }
165 
167 {
169 }
170 
172 {
174 }
175 
177 {
179 }
180 
181 
182 
183 QgsMapCanvas::QgsMapCanvas( QWidget * parent, const char *name )
184  : QGraphicsView( parent )
185  , mCanvasProperties( new CanvasProperties )
186  , mJob( 0 )
187  , mJobCancelled( false )
188  , mLabelingResults( 0 )
189  , mUseParallelRendering( false )
190  , mDrawRenderingStats( false )
191  , mCache( 0 )
192  , mPreviewEffect( 0 )
193 {
194  setObjectName( name );
195  mScene = new QGraphicsScene();
196  setScene( mScene );
197  setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
198  setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
199  mLastExtentIndex = -1;
200  mCurrentLayer = NULL;
201  mMapOverview = NULL;
202  mMapTool = NULL;
203  mLastNonZoomMapTool = NULL;
204 
205  mFrozen = false;
206  mRefreshScheduled = false;
207 
209 
210  // by default, the canvas is rendered
211  mRenderFlag = true;
212 
213  setMouseTracking( true );
214  setFocusPolicy( Qt::StrongFocus );
215 
216  mMapRenderer = new QgsMapRenderer;
217 
218  mResizeTimer = new QTimer( this );
219  mResizeTimer->setSingleShot( true );
220  connect( mResizeTimer, SIGNAL( timeout() ), this, SLOT( refresh() ) );
221 
222  // create map canvas item which will show the map
223  mMap = new QgsMapCanvasMap( this );
224  mScene->addItem( mMap );
225 
226  // project handling
227  connect( QgsProject::instance(), SIGNAL( readProject( const QDomDocument & ) ),
228  this, SLOT( readProject( const QDomDocument & ) ) );
229  connect( QgsProject::instance(), SIGNAL( writeProject( QDomDocument & ) ),
230  this, SLOT( writeProject( QDomDocument & ) ) );
231 
234 
235  // class that will sync most of the changes between canvas and (legacy) map renderer
236  // it is parented to map canvas, will be deleted automatically
237  new QgsMapCanvasRendererSync( this, mMapRenderer );
238 
239  QSize s = viewport()->size();
240  mSettings.setOutputSize( s );
241  mMapRenderer->setOutputSize( s, mSettings.outputDpi() );
242  setSceneRect( 0, 0, s.width(), s.height() );
243  mScene->setSceneRect( QRectF( 0, 0, s.width(), s.height() ) );
244 
245  moveCanvasContents( true );
246 
247  connect( &mMapUpdateTimer, SIGNAL( timeout() ), SLOT( mapUpdateTimeout() ) );
248  mMapUpdateTimer.setInterval( 250 );
249 
250 #ifdef Q_OS_WIN
251  // Enable touch event on Windows.
252  // Qt on Windows needs to be told it can take touch events or else it ignores them.
253  grabGesture( Qt::PinchGesture );
254  viewport()->setAttribute( Qt::WA_AcceptTouchEvents );
255 #endif
256 
257  mPreviewEffect = new QgsPreviewEffect( this );
258  viewport()->setGraphicsEffect( mPreviewEffect );
259 
260  setInteractive( false );
261 
262  refresh();
263 
264 } // QgsMapCanvas ctor
265 
266 
268 {
269  if ( mMapTool )
270  {
271  mMapTool->deactivate();
272  mMapTool = NULL;
273  }
274  mLastNonZoomMapTool = NULL;
275 
276  // delete canvas items prior to deleteing the canvas
277  // because they might try to update canvas when it's
278  // already being destructed, ends with segfault
279  QList<QGraphicsItem*> list = mScene->items();
280  QList<QGraphicsItem*>::iterator it = list.begin();
281  while ( it != list.end() )
282  {
283  QGraphicsItem* item = *it;
284  delete item;
285  ++it;
286  }
287 
288  mScene->deleteLater(); // crashes in python tests on windows
289 
290  delete mMapRenderer;
291  // mCanvasProperties auto-deleted via std::auto_ptr
292  // CanvasProperties struct has its own dtor for freeing resources
293 
294  if ( mJob )
295  {
296  mJob->cancel();
297  Q_ASSERT( mJob == 0 );
298  }
299 
300  delete mCache;
301 
302  delete mLabelingResults;
303 
304 } // dtor
305 
307 {
308  mSettings.setFlag( QgsMapSettings::Antialiasing, theFlag );
309 
310  if ( mMapOverview )
311  mMapOverview->enableAntiAliasing( theFlag );
312 } // anti aliasing
313 
314 void QgsMapCanvas::useImageToRender( bool theFlag )
315 {
316  Q_UNUSED( theFlag );
317 }
318 
320 {
321  return mMap;
322 }
323 
325 {
326  return mMapRenderer;
327 }
328 
329 
331 {
332  const QStringList& layers = mapSettings().layers();
333  if ( index >= 0 && index < ( int ) layers.size() )
334  return QgsMapLayerRegistry::instance()->mapLayer( layers[index] );
335  else
336  return NULL;
337 }
338 
339 
341 {
342  mCurrentLayer = layer;
343 }
344 
346 {
347  return mapSettings().scale();
348 } // scale
349 
350 void QgsMapCanvas::setDirty( bool dirty )
351 {
352  if ( dirty )
353  refresh();
354 }
355 
357 {
358  return false;
359 }
360 
361 
362 
364 {
365  return mJob != 0;
366 } // isDrawing
367 
368 
369 // return the current coordinate transform based on the extents and
370 // device size
372 {
373  return &mapSettings().mapToPixel();
374 }
375 
376 void QgsMapCanvas::setLayerSet( QList<QgsMapCanvasLayer> &layers )
377 {
378  // create layer set
379  QStringList layerSet, layerSetOverview;
380 
381  int i;
382  for ( i = 0; i < layers.size(); i++ )
383  {
384  QgsMapCanvasLayer &lyr = layers[i];
385  if ( !lyr.layer() )
386  {
387  continue;
388  }
389 
390  if ( lyr.isVisible() )
391  {
392  layerSet.push_back( lyr.layer()->id() );
393  }
394 
395  if ( lyr.isInOverview() )
396  {
397  layerSetOverview.push_back( lyr.layer()->id() );
398  }
399  }
400 
401  const QStringList& layerSetOld = mapSettings().layers();
402 
403  bool layerSetChanged = layerSetOld != layerSet;
404 
405  // update only if needed
406  if ( layerSetChanged )
407  {
408  QgsDebugMsg( "Layers changed to: " + layerSet.join( ", " ) );
409 
410  for ( i = 0; i < layerCount(); i++ )
411  {
412  // Add check if vector layer when disconnecting from selectionChanged slot
413  // Ticket #811 - racicot
415  if ( !currentLayer )
416  continue;
417  disconnect( currentLayer, SIGNAL( repaintRequested() ), this, SLOT( refresh() ) );
418  QgsVectorLayer *isVectLyr = qobject_cast<QgsVectorLayer *>( currentLayer );
419  if ( isVectLyr )
420  {
421  disconnect( currentLayer, SIGNAL( selectionChanged() ), this, SLOT( selectionChangedSlot() ) );
422  }
423  }
424 
425  mSettings.setLayers( layerSet );
426 
427  for ( i = 0; i < layerCount(); i++ )
428  {
429  // Add check if vector layer when connecting to selectionChanged slot
430  // Ticket #811 - racicot
432  connect( currentLayer, SIGNAL( repaintRequested() ), this, SLOT( refresh() ) );
433  QgsVectorLayer *isVectLyr = qobject_cast<QgsVectorLayer *>( currentLayer );
434  if ( isVectLyr )
435  {
436  connect( currentLayer, SIGNAL( selectionChanged() ), this, SLOT( selectionChangedSlot() ) );
437  }
438  }
439 
441 
442  QgsDebugMsg( "Layers have changed, refreshing" );
443  emit layersChanged();
444 
445  refresh();
446  }
447 
448  if ( mMapOverview )
449  {
450  const QStringList& layerSetOvOld = mMapOverview->layerSet();
451  if ( layerSetOvOld != layerSetOverview )
452  {
453  mMapOverview->setLayerSet( layerSetOverview );
454  }
455 
456  // refresh overview maplayers even if layer set is the same
457  // because full extent might have changed
458  updateOverview();
459  }
460 } // setLayerSet
461 
463 {
464  if ( mMapOverview )
465  {
466  // disconnect old map overview if exists
467  disconnect( this, SIGNAL( hasCrsTransformEnabledChanged( bool ) ),
468  mMapOverview, SLOT( hasCrsTransformEnabled( bool ) ) );
469  disconnect( this, SIGNAL( destinationCrsChanged() ),
470  mMapOverview, SLOT( destinationSrsChanged() ) );
471 
472  // map overview is not owned by map canvas so don't delete it...
473  }
474 
475  mMapOverview = overview;
476 
477  if ( overview )
478  {
479  // connect to the map render to copy its projection settings
480  connect( this, SIGNAL( hasCrsTransformEnabledChanged( bool ) ),
481  overview, SLOT( hasCrsTransformEnabled( bool ) ) );
482  connect( this, SIGNAL( destinationCrsChanged() ),
483  overview, SLOT( destinationSrsChanged() ) );
484  }
485 }
486 
488 {
489  return mSettings;
490 }
491 
493 {
494  if ( mSettings.hasCrsTransformEnabled() == enabled )
495  return;
496 
497  mSettings.setCrsTransformEnabled( enabled );
498 
500 
501  refresh();
502 
503  emit hasCrsTransformEnabledChanged( enabled );
504 }
505 
507 {
508  if ( mSettings.destinationCrs() == crs )
509  return;
510 
511  if ( mSettings.hasCrsTransformEnabled() )
512  {
513  // try to reproject current extent to the new one
514  QgsRectangle rect;
515  if ( !mSettings.visibleExtent().isEmpty() )
516  {
517  QgsCoordinateTransform transform( mSettings.destinationCrs(), crs );
518  rect = transform.transformBoundingBox( mSettings.visibleExtent() );
519  }
520  if ( !rect.isEmpty() )
521  {
522  setExtent( rect );
523  }
524 
525  QgsDebugMsg( "refreshing after destination CRS changed" );
526  refresh();
527  }
528 
529  mSettings.setDestinationCrs( crs );
530 
532 
533  emit destinationCrsChanged();
534 }
535 
537 {
538  return mLabelingResults;
539 }
540 
542 {
543  if ( enabled == isCachingEnabled() )
544  return;
545 
546  if ( enabled )
547  {
548  mCache = new QgsMapRendererCache;
549  }
550  else
551  {
552  delete mCache;
553  mCache = 0;
554  }
555 }
556 
558 {
559  return mCache != 0;
560 }
561 
563 {
564  if ( mCache )
565  mCache->clear();
566 }
567 
569 {
570  mUseParallelRendering = enabled;
571 }
572 
574 {
575  return mUseParallelRendering;
576 }
577 
578 void QgsMapCanvas::setMapUpdateInterval( int timeMiliseconds )
579 {
580  mMapUpdateTimer.setInterval( timeMiliseconds );
581 }
582 
584 {
585  return mMapUpdateTimer.interval();
586 }
587 
588 
590 {
591  // redraw overview
592  if ( mMapOverview )
593  {
594  mMapOverview->refresh();
595  }
596 }
597 
598 
600 {
601  return mCurrentLayer;
602 }
603 
604 
606 {
607  if ( !mSettings.hasValidSettings() )
608  {
609  QgsDebugMsg( "CANVAS refresh - invalid settings -> nothing to do" );
610  return;
611  }
612 
613  if ( !mRenderFlag || mFrozen ) // do we really need two flags controlling rendering?
614  {
615  QgsDebugMsg( "CANVAS render flag off" );
616  return;
617  }
618 
619  if ( mRefreshScheduled )
620  {
621  QgsDebugMsg( "CANVAS refresh already scheduled" );
622  return;
623  }
624 
625  mRefreshScheduled = true;
626 
627  QgsDebugMsg( "CANVAS refresh scheduling" );
628 
629  // schedule a refresh
630  QTimer::singleShot( 1, this, SLOT( refreshMap() ) );
631 } // refresh
632 
633 void QgsMapCanvas::refreshMap()
634 {
635  Q_ASSERT( mRefreshScheduled );
636 
637  QgsDebugMsg( "CANVAS refresh!" );
638 
639  stopRendering(); // if any...
640 
641  // from now on we can accept refresh requests again
642  mRefreshScheduled = false;
643 
644  //update $map variable to canvas
645  QgsExpression::setSpecialColumn( "$map", tr( "canvas" ) );
646 
647  // create the renderer job
648  Q_ASSERT( mJob == 0 );
649  mJobCancelled = false;
650  if ( mUseParallelRendering )
651  mJob = new QgsMapRendererParallelJob( mSettings );
652  else
653  mJob = new QgsMapRendererSequentialJob( mSettings );
654  connect( mJob, SIGNAL( finished() ), SLOT( rendererJobFinished() ) );
655  mJob->setCache( mCache );
656 
657  QStringList layersForGeometryCache;
658  foreach ( QString id, mSettings.layers() )
659  {
660  if ( QgsVectorLayer* vl = qobject_cast<QgsVectorLayer*>( QgsMapLayerRegistry::instance()->mapLayer( id ) ) )
661  {
662  if ( vl->isEditable() )
663  layersForGeometryCache << id;
664  }
665  }
666  mJob->setRequestedGeometryCacheForLayers( layersForGeometryCache );
667 
668  mJob->start();
669 
670  mMapUpdateTimer.start();
671 
672  emit renderStarting();
673 }
674 
675 
676 void QgsMapCanvas::rendererJobFinished()
677 {
678  QgsDebugMsg( QString( "CANVAS finish! %1" ).arg( !mJobCancelled ) );
679 
680  mMapUpdateTimer.stop();
681 
682  // TODO: would be better to show the errors in message bar
683  foreach ( const QgsMapRendererJob::Error& error, mJob->errors() )
684  {
685  QgsMessageLog::logMessage( error.layerID + " :: " + error.message, tr( "Rendering" ) );
686  }
687 
688  if ( !mJobCancelled )
689  {
690  // take labeling results before emitting renderComplete, so labeling map tools
691  // connected to signal work with correct results
692  delete mLabelingResults;
693  mLabelingResults = mJob->takeLabelingResults();
694 
695  QImage img = mJob->renderedImage();
696 
697  // emit renderComplete to get our decorations drawn
698  QPainter p( &img );
699  emit renderComplete( &p );
700 
701  QSettings settings;
702  if ( settings.value( "/Map/logCanvasRefreshEvent", false ).toBool() )
703  {
704  QString logMsg = tr( "Canvas refresh: %1 ms" ).arg( mJob->renderingTime() );
705  QgsMessageLog::logMessage( logMsg, tr( "Rendering" ) );
706  }
707 
708  if ( mDrawRenderingStats )
709  {
710  int w = img.width(), h = img.height();
711  QFont fnt = p.font();
712  fnt.setBold( true );
713  p.setFont( fnt );
714  int lh = p.fontMetrics().height() * 2;
715  QRect r( 0, h - lh, w, lh );
716  p.setPen( Qt::NoPen );
717  p.setBrush( QColor( 0, 0, 0, 110 ) );
718  p.drawRect( r );
719  p.setPen( Qt::white );
720  QString msg = QString( "%1 :: %2 ms" ).arg( mUseParallelRendering ? "PARALLEL" : "SEQUENTIAL" ).arg( mJob->renderingTime() );
721  p.drawText( r, msg, QTextOption( Qt::AlignCenter ) );
722  }
723 
724  p.end();
725 
726  QgsRectangle rect = mSettings.visibleExtent();
727  mMap->setContent( img, rect );
728  }
729 
730  // now we are in a slot called from mJob - do not delete it immediately
731  // so the class is still valid when the execution returns to the class
732  mJob->deleteLater();
733  mJob = 0;
734 
735  emit mapCanvasRefreshed();
736 }
737 
738 void QgsMapCanvas::mapUpdateTimeout()
739 {
740  mMap->setContent( mJob->renderedImage(), mJob->mapSettings().visibleExtent() );
741 }
742 
744 {
745  if ( mJob )
746  {
747  QgsDebugMsg( "CANVAS stop rendering!" );
748  mJobCancelled = true;
749  mJob->cancel();
750  Q_ASSERT( mJob == 0 ); // no need to delete here: already deleted in finished()
751  }
752 }
753 
755 {
756 }
757 
758 //the format defaults to "PNG" if not specified
759 void QgsMapCanvas::saveAsImage( QString theFileName, QPixmap * theQPixmap, QString theFormat )
760 {
761  //
762  //check if the optional QPaintDevice was supplied
763  //
764  if ( theQPixmap != NULL )
765  {
766  // render
767  QPainter painter;
768  painter.begin( theQPixmap );
769  QgsMapRendererCustomPainterJob job( mSettings, &painter );
770  job.start();
771  job.waitForFinished();
772  emit renderComplete( &painter );
773  painter.end();
774 
775  theQPixmap->save( theFileName, theFormat.toLocal8Bit().data() );
776  }
777  else //use the map view
778  {
779  mMap->contentImage().save( theFileName, theFormat.toLocal8Bit().data() );
780  }
781  //create a world file to go with the image...
783  QString myHeader;
784  // note: use 17 places of precision for all numbers output
785  //Pixel XDim
786  myHeader += qgsDoubleToString( mapUnitsPerPixel() ) + "\r\n";
787  //Rotation on y axis - hard coded
788  myHeader += "0 \r\n";
789  //Rotation on x axis - hard coded
790  myHeader += "0 \r\n";
791  //Pixel YDim - almost always negative - see
792  //http://en.wikipedia.org/wiki/World_file#cite_note-2
793  myHeader += "-" + qgsDoubleToString( mapUnitsPerPixel() ) + "\r\n";
794  //Origin X (center of top left cell)
795  myHeader += qgsDoubleToString( myRect.xMinimum() + ( mapUnitsPerPixel() / 2 ) ) + "\r\n";
796  //Origin Y (center of top left cell)
797  myHeader += qgsDoubleToString( myRect.yMaximum() - ( mapUnitsPerPixel() / 2 ) ) + "\r\n";
798  QFileInfo myInfo = QFileInfo( theFileName );
799  // allow dotted names
800  QString myWorldFileName = myInfo.absolutePath() + "/" + myInfo.completeBaseName() + "." + theFormat + "w";
801  QFile myWorldFile( myWorldFileName );
802  if ( !myWorldFile.open( QIODevice::WriteOnly ) ) //don't use QIODevice::Text
803  {
804  return;
805  }
806  QTextStream myStream( &myWorldFile );
807  myStream << myHeader;
808 } // saveAsImage
809 
810 
811 
813 {
814  return mapSettings().visibleExtent();
815 } // extent
816 
818 {
819  return mapSettings().fullExtent();
820 } // extent
821 
822 
824 {
825  QgsRectangle current = extent();
826 
827  if ( r == current )
828  return;
829 
830  if ( r.isEmpty() )
831  {
832  QgsDebugMsg( "Empty extent - keeping old scale with new center!" );
833  setCenter( r.center() );
834  }
835  else
836  {
837  mSettings.setExtent( r );
838  }
839  emit extentsChanged();
840  updateScale();
841  if ( mLastExtent.size() > 20 )
842  mLastExtent.removeAt( 0 );
843 
844  //clear all extent items after current index
845  for ( int i = mLastExtent.size() - 1; i > mLastExtentIndex; i-- )
846  {
847  mLastExtent.removeAt( i );
848  }
849 
850  mLastExtent.append( extent() );
851 
852  // adjust history to no more than 20
853  if ( mLastExtent.size() > 20 )
854  {
855  mLastExtent.removeAt( 0 );
856  }
857 
858  // the last item is the current extent
859  mLastExtentIndex = mLastExtent.size() - 1;
860 
861  // update controls' enabled state
862  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
863  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
864  // notify canvas items of change
866 
867 } // setExtent
868 
869 void QgsMapCanvas::setCenter( const QgsPoint& center )
870 {
872  double x = center.x();
873  double y = center.y();
874  setExtent(
875  QgsRectangle(
876  x - r.width() / 2.0, y - r.height() / 2.0,
877  x + r.width() / 2.0, y + r.height() / 2.0
878  )
879  );
880 } // setCenter
881 
883 {
885  return r.center();
886 }
887 
888 
890 {
891  return mapSettings().rotation();
892 } // rotation
893 
894 void QgsMapCanvas::setRotation( double degrees )
895 {
896  double current = rotation();
897 
898  if ( degrees == current )
899  return;
900 
901  mSettings.setRotation( degrees );
902  emit rotationChanged( degrees );
903  emit extentsChanged(); // visible extent changes with rotation
904 
905  // notify canvas items of change (needed?)
907 
908 } // setRotation
909 
910 
912 {
913  emit scaleChanged( mapSettings().scale() );
914 }
915 
916 
918 {
919  refresh();
920 } // clear
921 
922 
923 
925 {
927  // If the full extent is an empty set, don't do the zoom
928  if ( !extent.isEmpty() )
929  {
930  // Add a 5% margin around the full extent
931  extent.scale( 1.05 );
932  setExtent( extent );
933  }
934  refresh();
935 
936 } // zoomToFullExtent
937 
938 
939 
941 {
942  if ( mLastExtentIndex > 0 )
943  {
944  mLastExtentIndex--;
945  mSettings.setExtent( mLastExtent[mLastExtentIndex] );
946  emit extentsChanged();
947  updateScale();
948  refresh();
949  // update controls' enabled state
950  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
951  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
952  // notify canvas items of change
954  }
955 
956 } // zoomToPreviousExtent
957 
959 {
960  if ( mLastExtentIndex < mLastExtent.size() - 1 )
961  {
962  mLastExtentIndex++;
963  mSettings.setExtent( mLastExtent[mLastExtentIndex] );
964  emit extentsChanged();
965  updateScale();
966  refresh();
967  // update controls' enabled state
968  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
969  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
970  // notify canvas items of change
972  }
973 }// zoomToNextExtent
974 
976 {
977  mLastExtent.clear(); // clear the zoom history list
978  mLastExtent.append( extent() ) ; // set the current extent in the list
979  mLastExtentIndex = mLastExtent.size() - 1;
980  // update controls' enabled state
981  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
982  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
983 }// clearExtentHistory
984 
985 
987 {
989 }
990 
992 {
993  if ( layer == NULL )
994  {
995  // use current layer by default
996  layer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
997  }
998 
999  if ( layer == NULL )
1000  {
1001  return;
1002  }
1003 
1004  if ( layer->selectedFeatureCount() == 0 )
1005  {
1006  return;
1007  }
1008 
1010 
1011  // no selected features, only one selected point feature
1012  //or two point features with the same x- or y-coordinates
1013  if ( rect.isEmpty() )
1014  {
1015  // zoom in
1016  QgsPoint c = rect.center();
1017  rect = extent();
1018  rect.scale( 1.0, &c );
1019  }
1020  //zoom to an area
1021  else
1022  {
1023  // Expand rect to give a bit of space around the selected
1024  // objects so as to keep them clear of the map boundaries
1025  // The same 5% should apply to all margins.
1026  rect.scale( 1.05 );
1027  }
1028 
1029  setExtent( rect );
1030  refresh();
1031 } // zoomToSelected
1032 
1034 {
1035  if ( layer == NULL )
1036  {
1037  // use current layer by default
1038  layer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
1039  }
1040 
1041  if ( layer == NULL )
1042  {
1043  return;
1044  }
1045 
1046  if ( layer->selectedFeatureCount() == 0 )
1047  {
1048  return;
1049  }
1050 
1052  setExtent( QgsRectangle( rect.center(), rect.center() ) );
1053  refresh();
1054 } // panToSelected
1055 
1056 void QgsMapCanvas::keyPressEvent( QKeyEvent * e )
1057 {
1058  if ( mCanvasProperties->mouseButtonDown || mCanvasProperties->panSelectorDown )
1059  {
1060  emit keyPressed( e );
1061  return;
1062  }
1063 
1064  QPainter paint;
1065  QPen pen( Qt::gray );
1066  QgsPoint ll, ur;
1067 
1068  if ( ! mCanvasProperties->mouseButtonDown )
1069  {
1070  // Don't want to interfer with mouse events
1071 
1072  QgsRectangle currentExtent = mapSettings().visibleExtent();
1073  double dx = qAbs(( currentExtent.xMaximum() - currentExtent.xMinimum() ) / 4 );
1074  double dy = qAbs(( currentExtent.yMaximum() - currentExtent.yMinimum() ) / 4 );
1075 
1076  switch ( e->key() )
1077  {
1078  case Qt::Key_Left:
1079  QgsDebugMsg( "Pan left" );
1080 
1081  currentExtent.setXMinimum( currentExtent.xMinimum() - dx );
1082  currentExtent.setXMaximum( currentExtent.xMaximum() - dx );
1083  setExtent( currentExtent );
1084  refresh();
1085  break;
1086 
1087  case Qt::Key_Right:
1088  QgsDebugMsg( "Pan right" );
1089 
1090  currentExtent.setXMinimum( currentExtent.xMinimum() + dx );
1091  currentExtent.setXMaximum( currentExtent.xMaximum() + dx );
1092  setExtent( currentExtent );
1093  refresh();
1094  break;
1095 
1096  case Qt::Key_Up:
1097  QgsDebugMsg( "Pan up" );
1098 
1099  currentExtent.setYMaximum( currentExtent.yMaximum() + dy );
1100  currentExtent.setYMinimum( currentExtent.yMinimum() + dy );
1101  setExtent( currentExtent );
1102  refresh();
1103  break;
1104 
1105  case Qt::Key_Down:
1106  QgsDebugMsg( "Pan down" );
1107 
1108  currentExtent.setYMaximum( currentExtent.yMaximum() - dy );
1109  currentExtent.setYMinimum( currentExtent.yMinimum() - dy );
1110  setExtent( currentExtent );
1111  refresh();
1112  break;
1113 
1114 
1115 
1116  case Qt::Key_Space:
1117  QgsDebugMsg( "Pressing pan selector" );
1118 
1119  //mCanvasProperties->dragging = true;
1120  if ( ! e->isAutoRepeat() )
1121  {
1122  mCanvasProperties->panSelectorDown = true;
1123  mCanvasProperties->rubberStartPoint = mCanvasProperties->mouseLastXY;
1124  }
1125  break;
1126 
1127  case Qt::Key_PageUp:
1128  QgsDebugMsg( "Zoom in" );
1129  zoomIn();
1130  break;
1131 
1132  case Qt::Key_PageDown:
1133  QgsDebugMsg( "Zoom out" );
1134  zoomOut();
1135  break;
1136 
1137 #if 0
1138  case Qt::Key_P:
1139  mUseParallelRendering = !mUseParallelRendering;
1140  refresh();
1141  break;
1142 
1143  case Qt::Key_S:
1144  mDrawRenderingStats = !mDrawRenderingStats;
1145  refresh();
1146  break;
1147 #endif
1148 
1149  default:
1150  // Pass it on
1151  if ( mMapTool )
1152  {
1153  mMapTool->keyPressEvent( e );
1154  }
1155  else e->ignore();
1156 
1157  QgsDebugMsg( "Ignoring key: " + QString::number( e->key() ) );
1158  }
1159  }
1160 
1161  emit keyPressed( e );
1162 
1163 } //keyPressEvent()
1164 
1165 void QgsMapCanvas::keyReleaseEvent( QKeyEvent * e )
1166 {
1167  QgsDebugMsg( "keyRelease event" );
1168 
1169  switch ( e->key() )
1170  {
1171  case Qt::Key_Space:
1172  if ( !e->isAutoRepeat() && mCanvasProperties->panSelectorDown )
1173  {
1174  QgsDebugMsg( "Releasing pan selector" );
1175 
1176  mCanvasProperties->panSelectorDown = false;
1177  panActionEnd( mCanvasProperties->mouseLastXY );
1178  }
1179  break;
1180 
1181  default:
1182  // Pass it on
1183  if ( mMapTool )
1184  {
1185  mMapTool->keyReleaseEvent( e );
1186  }
1187  else e->ignore();
1188 
1189  QgsDebugMsg( "Ignoring key release: " + QString::number( e->key() ) );
1190  }
1191 
1192  emit keyReleased( e );
1193 
1194 } //keyReleaseEvent()
1195 
1196 
1198 {
1199  // call handler of current map tool
1200  if ( mMapTool )
1201  {
1202  mMapTool->canvasDoubleClickEvent( e );
1203  }
1204 }// mouseDoubleClickEvent
1205 
1206 
1207 void QgsMapCanvas::mousePressEvent( QMouseEvent * e )
1208 {
1209  //use middle mouse button for panning, map tools won't receive any events in that case
1210  if ( e->button() == Qt::MidButton )
1211  {
1212  mCanvasProperties->panSelectorDown = true;
1213  mCanvasProperties->rubberStartPoint = mCanvasProperties->mouseLastXY;
1214  }
1215  else
1216  {
1217 
1218  // call handler of current map tool
1219  if ( mMapTool )
1220  {
1221  mMapTool->canvasPressEvent( e );
1222  }
1223  }
1224 
1225  if ( mCanvasProperties->panSelectorDown )
1226  {
1227  return;
1228  }
1229 
1230  mCanvasProperties->mouseButtonDown = true;
1231  mCanvasProperties->rubberStartPoint = e->pos();
1232 
1233 } // mousePressEvent
1234 
1235 
1236 void QgsMapCanvas::mouseReleaseEvent( QMouseEvent * e )
1237 {
1238  //use middle mouse button for panning, map tools won't receive any events in that case
1239  if ( e->button() == Qt::MidButton )
1240  {
1241  mCanvasProperties->panSelectorDown = false;
1242  panActionEnd( mCanvasProperties->mouseLastXY );
1243  }
1244  else
1245  {
1246  // call handler of current map tool
1247  if ( mMapTool )
1248  {
1249  // right button was pressed in zoom tool? return to previous non zoom tool
1250  if ( e->button() == Qt::RightButton && mMapTool->isTransient() )
1251  {
1252  QgsDebugMsg( "Right click in map tool zoom or pan, last tool is " +
1253  QString( mLastNonZoomMapTool ? "not null." : "null." ) );
1254 
1255  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
1256 
1257  // change to older non-zoom tool
1258  if ( mLastNonZoomMapTool
1259  && ( !mLastNonZoomMapTool->isEditTool() || ( vlayer && vlayer->isEditable() ) ) )
1260  {
1261  QgsMapTool* t = mLastNonZoomMapTool;
1262  mLastNonZoomMapTool = NULL;
1263  setMapTool( t );
1264  }
1265  return;
1266  }
1267  mMapTool->canvasReleaseEvent( e );
1268  }
1269  }
1270 
1271 
1272  mCanvasProperties->mouseButtonDown = false;
1273 
1274  if ( mCanvasProperties->panSelectorDown )
1275  return;
1276 
1277 } // mouseReleaseEvent
1278 
1279 void QgsMapCanvas::resizeEvent( QResizeEvent * e )
1280 {
1281  QGraphicsView::resizeEvent( e );
1282  mResizeTimer->start( 500 );
1283 
1284  QSize lastSize = viewport()->size();
1285 
1286  mSettings.setOutputSize( lastSize );
1287  mMapRenderer->setOutputSize( lastSize, mSettings.outputDpi() );
1288 
1289  mScene->setSceneRect( QRectF( 0, 0, lastSize.width(), lastSize.height() ) );
1290 
1291  moveCanvasContents( true );
1292 
1293  // notify canvas items of change
1295 
1296  updateScale();
1297 
1298  //refresh();
1299 
1300  emit extentsChanged();
1301 }
1302 
1303 void QgsMapCanvas::paintEvent( QPaintEvent *e )
1304 {
1305  // no custom event handling anymore
1306 
1307  QGraphicsView::paintEvent( e );
1308 } // paintEvent
1309 
1311 {
1312  QList<QGraphicsItem*> list = mScene->items();
1313  QList<QGraphicsItem*>::iterator it = list.begin();
1314  while ( it != list.end() )
1315  {
1316  QgsMapCanvasItem* item = dynamic_cast<QgsMapCanvasItem *>( *it );
1317 
1318  if ( item )
1319  {
1320  item->updatePosition();
1321  }
1322 
1323  ++it;
1324  }
1325 }
1326 
1327 
1328 void QgsMapCanvas::wheelEvent( QWheelEvent *e )
1329 {
1330  // Zoom the map canvas in response to a mouse wheel event. Moving the
1331  // wheel forward (away) from the user zooms in
1332 
1333  QgsDebugMsg( "Wheel event delta " + QString::number( e->delta() ) );
1334 
1335  if ( mMapTool )
1336  {
1337  mMapTool->wheelEvent( e );
1338  }
1339 
1340  if ( QgsApplication::keyboardModifiers() )
1341  {
1342  // leave the wheel for map tools if any modifier pressed
1343  return;
1344  }
1345 
1346  switch ( mWheelAction )
1347  {
1348  case WheelZoom:
1349  // zoom without changing extent
1350  if ( e->delta() > 0 )
1351  zoomIn();
1352  else
1353  zoomOut();
1354  break;
1355 
1356  case WheelZoomAndRecenter:
1357  // zoom and don't change extent
1358  zoomWithCenter( e->x(), e->y(), e->delta() > 0 );
1359  break;
1360 
1362  {
1363  // zoom map to mouse cursor
1364  double scaleFactor = e->delta() > 0 ? 1 / mWheelZoomFactor : mWheelZoomFactor;
1365 
1366  QgsPoint oldCenter = center();
1367  QgsPoint mousePos( getCoordinateTransform()->toMapPoint( e->x(), e->y() ) );
1368  QgsPoint newCenter( mousePos.x() + (( oldCenter.x() - mousePos.x() ) * scaleFactor ),
1369  mousePos.y() + (( oldCenter.y() - mousePos.y() ) * scaleFactor ) );
1370 
1371  zoomByFactor( scaleFactor, &newCenter );
1372  break;
1373  }
1374 
1375  case WheelNothing:
1376  // well, nothing!
1377  break;
1378  }
1379 }
1380 
1381 void QgsMapCanvas::setWheelAction( WheelAction action, double factor )
1382 {
1383  mWheelAction = action;
1384  mWheelZoomFactor = factor;
1385 }
1386 
1388 {
1389  zoomByFactor( 1 / mWheelZoomFactor );
1390 }
1391 
1393 {
1394  zoomByFactor( mWheelZoomFactor );
1395 }
1396 
1397 void QgsMapCanvas::zoomScale( double newScale )
1398 {
1399  zoomByFactor( newScale / scale() );
1400 }
1401 
1402 void QgsMapCanvas::zoomWithCenter( int x, int y, bool zoomIn )
1403 {
1404  double scaleFactor = ( zoomIn ? 1 / mWheelZoomFactor : mWheelZoomFactor );
1405 
1406  // transform the mouse pos to map coordinates
1409  r.scale( scaleFactor, &center );
1410  setExtent( r );
1411  refresh();
1412 }
1413 
1414 void QgsMapCanvas::mouseMoveEvent( QMouseEvent * e )
1415 {
1416  mCanvasProperties->mouseLastXY = e->pos();
1417 
1418  if ( mCanvasProperties->panSelectorDown )
1419  {
1420  panAction( e );
1421  }
1422  else
1423  {
1424  // call handler of current map tool
1425  if ( mMapTool )
1426  {
1427  mMapTool->canvasMoveEvent( e );
1428  }
1429  }
1430 
1431  // show x y on status bar
1432  QPoint xy = e->pos();
1434  emit xyCoordinates( coord );
1435 } // mouseMoveEvent
1436 
1437 
1438 
1441 {
1442  if ( !tool )
1443  return;
1444 
1445  if ( mMapTool )
1446  {
1447  disconnect( mMapTool, SIGNAL( destroyed() ), this, SLOT( mapToolDestroyed() ) );
1448  mMapTool->deactivate();
1449  }
1450 
1451  if ( tool->isTransient() && mMapTool && !mMapTool->isTransient() )
1452  {
1453  // if zoom or pan tool will be active, save old tool
1454  // to bring it back on right click
1455  // (but only if it wasn't also zoom or pan tool)
1456  mLastNonZoomMapTool = mMapTool;
1457  }
1458  else
1459  {
1460  mLastNonZoomMapTool = NULL;
1461  }
1462 
1463  QgsMapTool* oldTool = mMapTool;
1464 
1465  // set new map tool and activate it
1466  mMapTool = tool;
1467  if ( mMapTool )
1468  {
1469  connect( mMapTool, SIGNAL( destroyed() ), this, SLOT( mapToolDestroyed() ) );
1470  mMapTool->activate();
1471  }
1472 
1473  emit mapToolSet( mMapTool );
1474  emit mapToolSet( mMapTool, oldTool );
1475 } // setMapTool
1476 
1478 {
1479  if ( mMapTool && mMapTool == tool )
1480  {
1481  mMapTool->deactivate();
1482  mMapTool = NULL;
1483  emit mapToolSet( NULL );
1484  emit mapToolSet( NULL, mMapTool );
1485  setCursor( Qt::ArrowCursor );
1486  }
1487 
1488  if ( mLastNonZoomMapTool && mLastNonZoomMapTool == tool )
1489  {
1490  mLastNonZoomMapTool = NULL;
1491  }
1492 }
1493 
1495 void QgsMapCanvas::setCanvasColor( const QColor & theColor )
1496 {
1497  // background of map's pixmap
1498  mSettings.setBackgroundColor( theColor );
1499 
1500  // background of the QGraphicsView
1501  QBrush bgBrush( theColor );
1502  setBackgroundBrush( bgBrush );
1503 #if 0
1504  QPalette palette;
1505  palette.setColor( backgroundRole(), theColor );
1506  setPalette( palette );
1507 #endif
1508 
1509  // background of QGraphicsScene
1510  mScene->setBackgroundBrush( bgBrush );
1511 } // setBackgroundColor
1512 
1514 {
1515  return mScene->backgroundBrush().color();
1516 }
1517 
1518 void QgsMapCanvas::setSelectionColor( const QColor& color )
1519 {
1520  mSettings.setSelectionColor( color );
1521 }
1522 
1524 {
1525  return mapSettings().layers().size();
1526 } // layerCount
1527 
1528 
1529 QList<QgsMapLayer*> QgsMapCanvas::layers() const
1530 {
1531  QList<QgsMapLayer*> lst;
1532  foreach ( QString layerID, mapSettings().layers() )
1533  {
1535  if ( layer )
1536  lst.append( layer );
1537  }
1538  return lst;
1539 }
1540 
1541 
1543 {
1544  // called when a layer has changed visibility setting
1545 
1546  refresh();
1547 
1548 } // layerStateChange
1549 
1550 
1551 
1552 void QgsMapCanvas::freeze( bool frz )
1553 {
1554  mFrozen = frz;
1555 } // freeze
1556 
1558 {
1559  return mFrozen;
1560 } // freeze
1561 
1562 
1564 {
1566  return mMap->paintDevice();
1568 }
1569 
1571 {
1572  return mapSettings().mapUnitsPerPixel();
1573 } // mapUnitsPerPixel
1574 
1575 
1577 {
1578  if ( mSettings.mapUnits() == u )
1579  return;
1580 
1581  QgsDebugMsg( "Setting map units to " + QString::number( static_cast<int>( u ) ) );
1582  mSettings.setMapUnits( u );
1583 
1584  updateScale();
1585 
1586  refresh(); // this will force the scale bar to be updated
1587 
1588  emit mapUnitsChanged();
1589 }
1590 
1591 
1593 {
1594  return mapSettings().mapUnits();
1595 }
1596 
1597 
1598 void QgsMapCanvas::setRenderFlag( bool theFlag )
1599 {
1600  mRenderFlag = theFlag;
1601 
1602  if ( mRenderFlag )
1603  {
1604  refresh();
1605  }
1606  else
1607  stopRendering();
1608 }
1609 
1610 void QgsMapCanvas::connectNotify( const char * signal )
1611 {
1612  Q_UNUSED( signal );
1613  QgsDebugMsg( "QgsMapCanvas connected to " + QString( signal ) );
1614 } //connectNotify
1615 
1616 
1618 {
1619  if ( !mSettings.hasCrsTransformEnabled() )
1620  return;
1621 
1622  QString destAuthId = mSettings.destinationCrs().authid();
1623  foreach ( QString layerID, mSettings.layers() )
1624  {
1626  if ( !layer )
1627  continue;
1628 
1629  QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer );
1630  if ( vl && vl->geometryType() == QGis::NoGeometry )
1631  continue;
1632 
1633  // if there are more options, ask the user which datum transform to use
1634  if ( !mSettings.datumTransformStore().hasEntryForLayer( layer ) )
1635  getDatumTransformInfo( layer, layer->crs().authid(), destAuthId );
1636  }
1637 }
1638 
1639 
1640 
1642 {
1643  return mMapTool;
1644 }
1645 
1646 void QgsMapCanvas::panActionEnd( QPoint releasePoint )
1647 {
1648  // move map image and other items to standard position
1649  moveCanvasContents( true ); // true means reset
1650 
1651  // use start and end box points to calculate the extent
1652  QgsPoint start = getCoordinateTransform()->toMapCoordinates( mCanvasProperties->rubberStartPoint );
1653  QgsPoint end = getCoordinateTransform()->toMapCoordinates( releasePoint );
1654 
1655  // modify the center
1656  double dx = end.x() - start.x();
1657  double dy = end.y() - start.y();
1658  QgsPoint c = center();
1659  c.set( c.x() - dx, c.y() - dy );
1660  setCenter( c );
1661 
1662  refresh();
1663 }
1664 
1665 void QgsMapCanvas::panAction( QMouseEvent * e )
1666 {
1667  Q_UNUSED( e );
1668 
1669  // move all map canvas items
1671 }
1672 
1674 {
1675  QPoint pnt( 0, 0 );
1676  if ( !reset )
1677  pnt += mCanvasProperties->mouseLastXY - mCanvasProperties->rubberStartPoint;
1678 
1679  setSceneRect( -pnt.x(), -pnt.y(), viewport()->size().width(), viewport()->size().height() );
1680 }
1681 
1683 {
1684  Q_UNUSED( mapLayer );
1685 }
1686 
1688 {
1689  return mCanvasProperties->mouseLastXY;
1690 }
1691 
1692 void QgsMapCanvas::setPreviewModeEnabled( bool previewEnabled )
1693 {
1694  if ( !mPreviewEffect )
1695  {
1696  return;
1697  }
1698 
1699  mPreviewEffect->setEnabled( previewEnabled );
1700 }
1701 
1703 {
1704  if ( !mPreviewEffect )
1705  {
1706  return false;
1707  }
1708 
1709  return mPreviewEffect->isEnabled();
1710 }
1711 
1713 {
1714  if ( !mPreviewEffect )
1715  {
1716  return;
1717  }
1718 
1719  mPreviewEffect->setMode( mode );
1720 }
1721 
1723 {
1724  if ( !mPreviewEffect )
1725  {
1727  }
1728 
1729  return mPreviewEffect->mode();
1730 }
1731 
1732 void QgsMapCanvas::readProject( const QDomDocument & doc )
1733 {
1734  QDomNodeList nodes = doc.elementsByTagName( "mapcanvas" );
1735  if ( nodes.count() )
1736  {
1737  QDomNode node = nodes.item( 0 );
1738 
1739  QgsMapSettings tmpSettings;
1740  tmpSettings.readXML( node );
1741  setMapUnits( tmpSettings.mapUnits() );
1743  setDestinationCrs( tmpSettings.destinationCrs() );
1744  setExtent( tmpSettings.extent() );
1745  setRotation( tmpSettings.rotation() );
1746  mSettings.datumTransformStore() = tmpSettings.datumTransformStore();
1747 
1748  clearExtentHistory(); // clear the extent history on project load
1749  }
1750  else
1751  {
1752  QgsDebugMsg( "Couldn't read mapcanvas information from project" );
1753  }
1754 }
1755 
1756 void QgsMapCanvas::writeProject( QDomDocument & doc )
1757 {
1758  // create node "mapcanvas" and call mMapRenderer->writeXML()
1759 
1760  QDomNodeList nl = doc.elementsByTagName( "qgis" );
1761  if ( !nl.count() )
1762  {
1763  QgsDebugMsg( "Unable to find qgis element in project file" );
1764  return;
1765  }
1766  QDomNode qgisNode = nl.item( 0 ); // there should only be one, so zeroth element ok
1767 
1768  QDomElement mapcanvasNode = doc.createElement( "mapcanvas" );
1769  qgisNode.appendChild( mapcanvasNode );
1770 
1771  mSettings.writeXML( mapcanvasNode, doc );
1772  // TODO: store only units, extent, projections, dest CRS
1773 }
1774 
1776 void QgsMapCanvas::getDatumTransformInfo( const QgsMapLayer* ml, const QString& srcAuthId, const QString& destAuthId )
1777 {
1778  if ( !ml )
1779  {
1780  return;
1781  }
1782 
1783  //check if default datum transformation available
1784  QSettings s;
1785  QString settingsString = "/Projections/" + srcAuthId + "//" + destAuthId;
1786  QVariant defaultSrcTransform = s.value( settingsString + "_srcTransform" );
1787  QVariant defaultDestTransform = s.value( settingsString + "_destTransform" );
1788  if ( defaultSrcTransform.isValid() && defaultDestTransform.isValid() )
1789  {
1790  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, defaultSrcTransform.toInt(), defaultDestTransform.toInt() );
1791  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, defaultSrcTransform.toInt(), defaultDestTransform.toInt() );
1792  return;
1793  }
1794 
1795  const QgsCoordinateReferenceSystem& srcCRS = QgsCRSCache::instance()->crsByAuthId( srcAuthId );
1796  const QgsCoordinateReferenceSystem& destCRS = QgsCRSCache::instance()->crsByAuthId( destAuthId );
1797 
1798  if ( !s.value( "/Projections/showDatumTransformDialog", false ).toBool() )
1799  {
1800  // just use the default transform
1801  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, -1, -1 );
1802  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, -1, -1 );
1803  return;
1804  }
1805 
1806  //get list of datum transforms
1807  QList< QList< int > > dt = QgsCoordinateTransform::datumTransformations( srcCRS, destCRS );
1808  if ( dt.size() < 2 )
1809  {
1810  return;
1811  }
1812 
1813  //if several possibilities: present dialog
1814  QgsDatumTransformDialog d( ml->name(), dt );
1815  d.setDatumTransformInfo( srcCRS.authid(), destCRS.authid() );
1816  if ( d.exec() == QDialog::Accepted )
1817  {
1818  int srcTransform = -1;
1819  int destTransform = -1;
1820  QList<int> t = d.selectedDatumTransform();
1821  if ( t.size() > 0 )
1822  {
1823  srcTransform = t.at( 0 );
1824  }
1825  if ( t.size() > 1 )
1826  {
1827  destTransform = t.at( 1 );
1828  }
1829  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, srcTransform, destTransform );
1830  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, srcTransform, destTransform );
1831  if ( d.rememberSelection() )
1832  {
1833  s.setValue( settingsString + "_srcTransform", srcTransform );
1834  s.setValue( settingsString + "_destTransform", destTransform );
1835  }
1836  }
1837  else
1838  {
1839  mSettings.datumTransformStore().addEntry( ml->id(), srcAuthId, destAuthId, -1, -1 );
1840  mMapRenderer->addLayerCoordinateTransform( ml->id(), srcAuthId, destAuthId, -1, -1 );
1841  }
1842 }
1843 
1844 void QgsMapCanvas::zoomByFactor( double scaleFactor, const QgsPoint* center )
1845 {
1847  r.scale( scaleFactor, center );
1848  setExtent( r );
1849  refresh();
1850 }
1851 
1853 {
1854  // Find out which layer it was that sent the signal.
1855  QgsMapLayer *layer = qobject_cast<QgsMapLayer *>( sender() );
1856  emit selectionChanged( layer );
1857  refresh();
1858 }
1859 
1860 void QgsMapCanvas::dragEnterEvent( QDragEnterEvent * e )
1861 {
1862  // By default graphics view delegates the drag events to graphics items.
1863  // But we do not want that and by ignoring the drag enter we let the
1864  // parent (e.g. QgisApp) to handle drops of map layers etc.
1865  e->ignore();
1866 }
1867 
1868 void QgsMapCanvas::mapToolDestroyed()
1869 {
1870  QgsDebugMsg( "maptool destroyed" );
1871  mMapTool = 0;
1872 }
1873 
1874 #ifdef HAVE_TOUCH
1875 bool QgsMapCanvas::event( QEvent * e )
1876 {
1877  bool done = false;
1878  if ( e->type() == QEvent::Gesture )
1879  {
1880  // call handler of current map tool
1881  if ( mMapTool )
1882  {
1883  done = mMapTool->gestureEvent( static_cast<QGestureEvent*>( e ) );
1884  }
1885  }
1886  else
1887  {
1888  // pass other events to base class
1889  done = QGraphicsView::event( e );
1890  }
1891  return done;
1892 }
1893 #endif
void unsetMapTool(QgsMapTool *mapTool)
Unset the current map tool or last non zoom tool.
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 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:48
Job implementation that renders everything sequentially using a custom painter.
void setRotation(double degrees)
Set the rotation of the map canvas in clockwise degrees.
const QgsCoordinateReferenceSystem & crsByAuthId(const QString &authid)
Returns the CRS for authid, e.g.
bool isEmpty() const
test if rectangle is empty.
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.
void enableOverviewMode(QgsMapOverviewCanvas *overview)
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
int layerCount() const
return number of layers on the map
A widget that displays an overview map.
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:163
void clearExtentHistory()
void readXML(QDomNode &theNode)
QgsRectangle fullExtent() const
returns current extent of layer set
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.
double yMaximum() const
Get the y maximum value (top side of rectangle)
Definition: qgsrectangle.h:188
#define QgsDebugMsg(str)
Definition: qgslogger.h:33
UnitType
Map units that qgis supports.
Definition: qgis.h:229
void stopRendering()
stop rendering (if there is any right now)
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:138
void mouseReleaseEvent(QMouseEvent *e)
Overridden mouse release event.
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)
static QgsMapLayerRegistry * instance()
Definition: qgssingleton.h:23
#define Q_NOWARN_DEPRECATED_PUSH
Definition: qgis.h:439
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:74
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.
void moveCanvasContents(bool reset=false)
called when panning is in action, reset indicates end of panning
bool isVisible() const
Definition: qgsmapcanvas.h:83
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.
void renderComplete(QPainter *)
Emitted when the canvas has rendered.
void setProjectionsEnabled(bool enabled)
sets whether to use projections for this layer set
~QgsMapCanvas()
Destructor.
const QgsMapToPixel & mapToPixel() const
void keyReleaseEvent(QKeyEvent *e)
Overridden key release event.
QgsMapTool * mapTool()
Returns the currently active tool.
double rotation() const
Return the rotation of the resulting map image Units are clockwise degrees.
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:143
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:148
void setLayers(const QStringList &layers)
Set list of layer IDs for map rendering.
void resizeEvent(QResizeEvent *e)
Overridden resize event.
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:104
double x() const
Definition: qgspoint.h:126
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.
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 mouseDoubleClickEvent(QMouseEvent *e)
Overridden mouse double click event.
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
sets destination coordinate reference system
The QgsMapSettings class contains configuration for rendering of the map.
void setDatumTransformInfo(const QString &srcCRSauthId, const QString &destCRSauthId)
void hasCrsTransformEnabledChanged(bool flag)
Emitted when on-the-fly projection has been turned on/off.
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 paintEvent(QPaintEvent *e)
Overridden paint event.
void setCrsTransformEnabled(bool enabled)
sets whether to use projections for this layer set
QgsMapRenderer * mRenderer
Definition: qgsmapcanvas.h:686
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:34
virtual void keyReleaseEvent(QKeyEvent *e)
Key event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:168
int outputDpi() const
Return DPI used for conversion between real world units (e.g.
Q_DECL_DEPRECATED void showError(QgsMapLayer *mapLayer)
A rectangular graphics item representing the map on the canvas.
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.
double yMinimum() const
Get the y minimum value (bottom side of rectangle)
Definition: qgsrectangle.h:193
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:178
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.
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) ...
void mousePressEvent(QMouseEvent *e)
Overridden mouse press event.
void setMapUnits(QGis::UnitType u)
Set units of map's geographical coordinates - used for scale calculation.
virtual void waitForFinished()
Block until the job has finished.
Job implementation that renders all layers in parallel.
const QgsCoordinateReferenceSystem & destinationCrs() const
returns CRS of destination coordinate reference system
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 setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:168
QgsMapCanvas * mCanvas
Definition: qgsmapcanvas.h:685
void keyReleased(QKeyEvent *e)
Emit key release event.
Q_DECL_DEPRECATED QPaintDevice & paintDevice()
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.
double mapUnitsPerPixel() const
Return the distance in geographical coordinates that equals to one pixel in the map.
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
Definition: qgsmaplayer.cpp:95
void wheelEvent(QWheelEvent *e)
Overridden mouse wheel event.
void destinationCrsChanged()
Emitted when map CRS has changed.
double rotation() const
returns current rotation in clockwise degrees
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.
QGis::UnitType mapUnits() const
Get the current canvas map units.
virtual void start()
Start the rendering job and immediately return.
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:190
QgsMapCanvasMap * map()
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:158
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.
void keyPressed(QKeyEvent *e)
Emit key press event.
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.
void setRotation(double degrees)
sets rotation value in clockwise degrees
QString qgsDoubleToString(const double &a, const int &precision=17)
Definition: qgis.h:317
void setPreviewModeEnabled(bool previewEnabled)
Enables a preview mode for the map canvas.
virtual void start()=0
Start the rendering job and immediately return.
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 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:163
bool isCachingEnabled() const
Check whether images of rendered layers are curerently being cached.
QgsPoint toMapCoordinates(int x, int y) 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.
Job implementation that renders everything sequentially in one thread.
#define Q_NOWARN_DEPRECATED_POP
Definition: qgis.h:440
void setBackgroundColor(const QColor &color)
Set the background color of the map.
QImage contentImage() const
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:84
virtual void canvasReleaseEvent(QMouseEvent *e)
Mouse release event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:153
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 setOutputSize(const QSize &size)
Set the size of the resulting map image.
void setYMaximum(double y)
Set the maximum y value.
Definition: qgsrectangle.h:173
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:362
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.
QgsMapCanvasRendererSync(QgsMapCanvas *canvas, QgsMapRenderer *renderer)
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.
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:185
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.
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
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 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)
void updateOverview()
bool isParallelRenderingEnabled() const
Check whether the layers are rendered in parallel or sequentially.
void connectNotify(const char *signal)
debugging member invoked when a connect() is made to this object
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.
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:658
double width() const
Width of the rectangle.
Definition: qgsrectangle.h:198
virtual QgsLabelingResults * takeLabelingResults()=0
Get pointer to internal labeling engine (in order to get access to the results)
void zoomIn()
Zoom in with fixed factor.
virtual bool isEditable() const
Returns true if the provider is in editing mode.
QGis::UnitType mapUnits() const
Represents a vector layer which manages a vector based data sets.
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.
double xMinimum() const
Get the x minimum value (left side of rectangle)
Definition: qgsrectangle.h:183
static QgsCRSCache * instance()
Definition: qgscrscache.cpp:80
QgsPoint center() const
Center point of the rectangle.
Definition: qgsrectangle.h:208
QgsMapLayer * layer()
Definition: qgsmapcanvas.h:86
void extentsChanged()
Emitted when the extents of the map change.
int renderingTime() const
Find out how log it took to finish the job (in miliseconds)
std::auto_ptr< CanvasProperties > mCanvasProperties
Handle pattern for implementation object.
Definition: qgsmapcanvas.h:555
void mouseMoveEvent(QMouseEvent *e)
Overridden mouse move event.
QgsMapLayer * layer(int index)
return the map layer at position index in the layer stack
Q_DECL_DEPRECATED void updateMap()
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:158
void keyPressEvent(QKeyEvent *e)
Overridden key press event.
double height() const
Height of the rectangle.
Definition: qgsrectangle.h:203
void dragEnterEvent(QDragEnterEvent *e)
Overridden drag enter event.
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 layersChanged()
Emitted when a new set of layers has been received.
QgsRectangle boundingBoxOfSelected()
Returns the bounding box of the selected features.
#define tr(sourceText)
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.