QGIS API Documentation  3.14.0-Pi (9f7028fd23)
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 #include <cmath>
19 
20 #include <QtGlobal>
21 #include <QApplication>
22 #include <QCursor>
23 #include <QDir>
24 #include <QFile>
25 #include <QGraphicsItem>
26 #include <QGraphicsScene>
27 #include <QGraphicsView>
28 #include <QKeyEvent>
29 #include <QPainter>
30 #include <QPaintEvent>
31 #include <QPixmap>
32 #include <QRect>
33 #include <QTextStream>
34 #include <QResizeEvent>
35 #include <QScreen>
36 #include <QString>
37 #include <QStringList>
38 #include <QWheelEvent>
39 #include <QWindow>
40 #include <QMenu>
41 #include <QClipboard>
42 
43 #include "qgis.h"
44 #include "qgssettings.h"
46 #include "qgsapplication.h"
47 #include "qgsexception.h"
49 #include "qgsfeatureiterator.h"
50 #include "qgslogger.h"
51 #include "qgsmapcanvas.h"
52 #include "qgsmapcanvasmap.h"
54 #include "qgsmaplayer.h"
55 #include "qgsmapmouseevent.h"
56 #include "qgsmaptoolpan.h"
57 #include "qgsmaptoolzoom.h"
58 #include "qgsmaptopixel.h"
59 #include "qgsmapoverviewcanvas.h"
60 #include "qgsmaprenderercache.h"
64 #include "qgsmapsettingsutils.h"
65 #include "qgsmessagelog.h"
66 #include "qgsmessageviewer.h"
67 #include "qgspallabeling.h"
68 #include "qgsproject.h"
69 #include "qgsrubberband.h"
70 #include "qgsvectorlayer.h"
71 #include "qgsmapthemecollection.h"
73 #include "qgssvgcache.h"
74 #include "qgsimagecache.h"
76 #include "qgsmimedatautils.h"
77 #include "qgscustomdrophandler.h"
78 #include "qgsreferencedgeometry.h"
79 #include "qgsprojectviewsettings.h"
83 #include "qgstemporalcontroller.h"
84 #include "qgsruntimeprofiler.h"
86 
92 //TODO QGIS 4.0 - remove
94 {
95  public:
96 
100  CanvasProperties() = default;
101 
103  bool mouseButtonDown{ false };
104 
106  QPoint mouseLastXY;
107 
109  QPoint rubberStartPoint;
110 
112  bool panSelectorDown{ false };
113 };
114 
115 
116 
117 QgsMapCanvas::QgsMapCanvas( QWidget *parent )
118  : QGraphicsView( parent )
119  , mCanvasProperties( new CanvasProperties )
120  , mMenu( new QMenu( this ) )
121  , mExpressionContextScope( tr( "Map Canvas" ) )
122 {
123  mScene = new QGraphicsScene();
124  setScene( mScene );
125  setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
126  setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
127  setMouseTracking( true );
128  setFocusPolicy( Qt::StrongFocus );
129 
130  mResizeTimer = new QTimer( this );
131  mResizeTimer->setSingleShot( true );
132  connect( mResizeTimer, &QTimer::timeout, this, &QgsMapCanvas::refresh );
133 
134  mRefreshTimer = new QTimer( this );
135  mRefreshTimer->setSingleShot( true );
136  connect( mRefreshTimer, &QTimer::timeout, this, &QgsMapCanvas::refreshMap );
137 
138  // create map canvas item which will show the map
139  mMap = new QgsMapCanvasMap( this );
140 
141  // project handling
143  this, &QgsMapCanvas::readProject );
146 
147  connect( QgsProject::instance()->mapThemeCollection(), &QgsMapThemeCollection::mapThemeChanged, this, &QgsMapCanvas::mapThemeChanged );
148  connect( QgsProject::instance()->mapThemeCollection(), &QgsMapThemeCollection::mapThemeRenamed, this, &QgsMapCanvas::mapThemeRenamed );
149  connect( QgsProject::instance()->mapThemeCollection(), &QgsMapThemeCollection::mapThemesChanged, this, &QgsMapCanvas::projectThemesChanged );
150 
151  {
152  QgsScopedRuntimeProfile profile( "Map settings initialization" );
153  mSettings.setFlag( QgsMapSettings::DrawEditingInfo );
154  mSettings.setFlag( QgsMapSettings::UseRenderingOptimization );
155  mSettings.setFlag( QgsMapSettings::RenderPartialOutput );
156  mSettings.setEllipsoid( QgsProject::instance()->ellipsoid() );
158  this, [ = ]
159  {
160  mSettings.setEllipsoid( QgsProject::instance()->ellipsoid() );
161  refresh();
162  } );
163  mSettings.setTransformContext( QgsProject::instance()->transformContext() );
165  this, [ = ]
166  {
167  mSettings.setTransformContext( QgsProject::instance()->transformContext() );
168  emit transformContextChanged();
169  refresh();
170  } );
171  }
172 
173  // refresh canvas when a remote svg/image has finished downloading
176  // refresh canvas when project color scheme is changed -- if layers use project colors, they need to be redrawn
178 
179  //segmentation parameters
180  QgsSettings settings;
181  double segmentationTolerance = settings.value( QStringLiteral( "qgis/segmentationTolerance" ), "0.01745" ).toDouble();
182  QgsAbstractGeometry::SegmentationToleranceType toleranceType = settings.enumValue( QStringLiteral( "qgis/segmentationToleranceType" ), QgsAbstractGeometry::MaximumAngle );
183  mSettings.setSegmentationTolerance( segmentationTolerance );
184  mSettings.setSegmentationToleranceType( toleranceType );
185 
186  mWheelZoomFactor = settings.value( QStringLiteral( "qgis/zoom_factor" ), 2 ).toDouble();
187 
188  QSize s = viewport()->size();
189  mSettings.setOutputSize( s );
190  mSettings.setDevicePixelRatio( devicePixelRatio() );
191  setSceneRect( 0, 0, s.width(), s.height() );
192  mScene->setSceneRect( QRectF( 0, 0, s.width(), s.height() ) );
193 
194  moveCanvasContents( true );
195 
196  // keep device pixel ratio up to date on screen or resolution change
197  if ( window()->windowHandle() )
198  {
199  connect( window()->windowHandle(), &QWindow::screenChanged, this, [ = ]( QScreen * ) {mSettings.setDevicePixelRatio( devicePixelRatio() );} );
200  connect( window()->windowHandle()->screen(), &QScreen::physicalDotsPerInchChanged, this, [ = ]( qreal ) {mSettings.setDevicePixelRatio( devicePixelRatio() );} );
201  }
202 
203  connect( &mMapUpdateTimer, &QTimer::timeout, this, &QgsMapCanvas::mapUpdateTimeout );
204  mMapUpdateTimer.setInterval( 250 );
205 
206 #ifdef Q_OS_WIN
207  // Enable touch event on Windows.
208  // Qt on Windows needs to be told it can take touch events or else it ignores them.
209  grabGesture( Qt::PinchGesture );
210  grabGesture( Qt::TapAndHoldGesture );
211  viewport()->setAttribute( Qt::WA_AcceptTouchEvents );
212 #endif
213 
214  mPreviewEffect = new QgsPreviewEffect( this );
215  viewport()->setGraphicsEffect( mPreviewEffect );
216 
217  mZoomCursor = QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn );
218 
219  connect( &mAutoRefreshTimer, &QTimer::timeout, this, &QgsMapCanvas::autoRefreshTriggered );
220 
222 
223  setInteractive( false );
224 
225  // make sure we have the same default in QgsMapSettings and the scene's background brush
226  // (by default map settings has white bg color, scene background brush is black)
227  setCanvasColor( mSettings.backgroundColor() );
228 
229  setTemporalRange( mSettings.temporalRange() );
230 
231  refresh();
232 }
233 
234 
236 {
237  if ( mMapTool )
238  {
239  mMapTool->deactivate();
240  mMapTool = nullptr;
241  }
242  mLastNonZoomMapTool = nullptr;
243 
244  // rendering job may still end up writing into canvas map item
245  // so kill it before deleting canvas items
246  if ( mJob )
247  {
248  whileBlocking( mJob )->cancel();
249  delete mJob;
250  }
251 
252  QList< QgsMapRendererQImageJob * >::const_iterator previewJob = mPreviewJobs.constBegin();
253  for ( ; previewJob != mPreviewJobs.constEnd(); ++previewJob )
254  {
255  if ( *previewJob )
256  {
257  whileBlocking( *previewJob )->cancel();
258  delete *previewJob;
259  }
260  }
261 
262  // delete canvas items prior to deleting the canvas
263  // because they might try to update canvas when it's
264  // already being destructed, ends with segfault
265  qDeleteAll( mScene->items() );
266 
267  mScene->deleteLater(); // crashes in python tests on windows
268 
269  delete mCache;
270  delete mLabelingResults;
271 }
272 
273 void QgsMapCanvas::setMagnificationFactor( double factor, const QgsPointXY *center )
274 {
275  // do not go higher or lower than min max magnification ratio
276  double magnifierMin = QgsGuiUtils::CANVAS_MAGNIFICATION_MIN;
277  double magnifierMax = QgsGuiUtils::CANVAS_MAGNIFICATION_MAX;
278  factor = qBound( magnifierMin, factor, magnifierMax );
279 
280  // the magnifier widget is in integer percent
281  if ( !qgsDoubleNear( factor, mSettings.magnificationFactor(), 0.01 ) )
282  {
283  mSettings.setMagnificationFactor( factor, center );
284  refresh();
285  emit magnificationChanged( factor );
286  }
287 }
288 
290 {
291  return mSettings.magnificationFactor();
292 }
293 
295 {
296  mSettings.setFlag( QgsMapSettings::Antialiasing, flag );
297 } // anti aliasing
298 
300 {
301  mSettings.setFlag( QgsMapSettings::RenderMapTile, flag );
302 }
303 
305 {
306  QList<QgsMapLayer *> layers = mapSettings().layers();
307  if ( index >= 0 && index < layers.size() )
308  return layers[index];
309  else
310  return nullptr;
311 }
312 
314 {
315  if ( mCurrentLayer == layer )
316  return;
317 
318  mCurrentLayer = layer;
319  emit currentLayerChanged( layer );
320 }
321 
322 double QgsMapCanvas::scale() const
323 {
324  return mapSettings().scale();
325 }
326 
328 {
329  return nullptr != mJob;
330 } // isDrawing
331 
332 // return the current coordinate transform based on the extents and
333 // device size
335 {
336  return &mapSettings().mapToPixel();
337 }
338 
339 void QgsMapCanvas::setLayers( const QList<QgsMapLayer *> &layers )
340 {
341  // following a theme => request denied!
342  if ( !mTheme.isEmpty() )
343  return;
344 
345  setLayersPrivate( layers );
346 }
347 
348 void QgsMapCanvas::setLayersPrivate( const QList<QgsMapLayer *> &layers )
349 {
350  QList<QgsMapLayer *> oldLayers = mSettings.layers();
351 
352  // update only if needed
353  if ( layers == oldLayers )
354  return;
355 
356  const auto constOldLayers = oldLayers;
357  for ( QgsMapLayer *layer : constOldLayers )
358  {
359  disconnect( layer, &QgsMapLayer::repaintRequested, this, &QgsMapCanvas::layerRepaintRequested );
360  disconnect( layer, &QgsMapLayer::autoRefreshIntervalChanged, this, &QgsMapCanvas::updateAutoRefreshTimer );
361  if ( QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
362  {
364  }
365  }
366 
367  mSettings.setLayers( layers );
368 
369  const auto constLayers = layers;
370  for ( QgsMapLayer *layer : constLayers )
371  {
372  if ( !layer )
373  continue;
374  connect( layer, &QgsMapLayer::repaintRequested, this, &QgsMapCanvas::layerRepaintRequested );
375  connect( layer, &QgsMapLayer::autoRefreshIntervalChanged, this, &QgsMapCanvas::updateAutoRefreshTimer );
376  if ( QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
377  {
379  }
380  }
381 
382  QgsDebugMsgLevel( QStringLiteral( "Layers have changed, refreshing" ), 2 );
383  emit layersChanged();
384 
385  updateAutoRefreshTimer();
386  refresh();
387 }
388 
389 
391 {
392  return mSettings;
393 }
394 
396 {
397  if ( mSettings.destinationCrs() == crs )
398  return;
399 
400  // try to reproject current extent to the new one
401  QgsRectangle rect;
402  if ( !mSettings.visibleExtent().isEmpty() )
403  {
404  QgsCoordinateTransform transform( mSettings.destinationCrs(), crs, QgsProject::instance() );
405  transform.setBallparkTransformsAreAppropriate( true );
406  try
407  {
408  rect = transform.transformBoundingBox( mSettings.visibleExtent() );
409  }
410  catch ( QgsCsException &e )
411  {
412  Q_UNUSED( e )
413  QgsDebugMsg( QStringLiteral( "Transform error caught: %1" ).arg( e.what() ) );
414  }
415  }
416 
417  if ( !rect.isEmpty() )
418  {
419  setExtent( rect );
420  }
421 
422  mSettings.setDestinationCrs( crs );
423  updateScale();
424 
425  QgsDebugMsgLevel( QStringLiteral( "refreshing after destination CRS changed" ), 2 );
426  refresh();
427 
428  emit destinationCrsChanged();
429 }
430 
432 {
433  if ( mController )
435 
436  mController = controller;
438 }
439 
441 {
442  return mController;
443 }
444 
445 void QgsMapCanvas::setMapSettingsFlags( QgsMapSettings::Flags flags )
446 {
447  mSettings.setFlags( flags );
448  clearCache();
449  refresh();
450 }
451 
453 {
454  return mLabelingResults;
455 }
456 
458 {
459  if ( enabled == isCachingEnabled() )
460  return;
461 
462  if ( mJob && mJob->isActive() )
463  {
464  // wait for the current rendering to finish, before touching the cache
465  mJob->waitForFinished();
466  }
467 
468  if ( enabled )
469  {
470  mCache = new QgsMapRendererCache;
471  }
472  else
473  {
474  delete mCache;
475  mCache = nullptr;
476  }
477 }
478 
480 {
481  return nullptr != mCache;
482 }
483 
485 {
486  if ( mCache )
487  mCache->clear();
488 }
489 
491 {
492  mUseParallelRendering = enabled;
493 }
494 
496 {
497  return mUseParallelRendering;
498 }
499 
500 void QgsMapCanvas::setMapUpdateInterval( int timeMilliseconds )
501 {
502  mMapUpdateTimer.setInterval( timeMilliseconds );
503 }
504 
506 {
507  return mMapUpdateTimer.interval();
508 }
509 
510 
512 {
513  return mCurrentLayer;
514 }
515 
517 {
518  QgsExpressionContextScope *s = new QgsExpressionContextScope( QObject::tr( "Map Canvas" ) );
519  s->setVariable( QStringLiteral( "canvas_cursor_point" ), QgsGeometry::fromPointXY( cursorPoint() ), true );
520 
521  return s;
522 }
523 
525 {
526  if ( !mSettings.hasValidSettings() )
527  {
528  QgsDebugMsgLevel( QStringLiteral( "CANVAS refresh - invalid settings -> nothing to do" ), 2 );
529  return;
530  }
531 
532  if ( !mRenderFlag || mFrozen )
533  {
534  QgsDebugMsgLevel( QStringLiteral( "CANVAS render flag off" ), 2 );
535  return;
536  }
537 
538  if ( mRefreshScheduled )
539  {
540  QgsDebugMsgLevel( QStringLiteral( "CANVAS refresh already scheduled" ), 2 );
541  return;
542  }
543 
544  mRefreshScheduled = true;
545 
546  QgsDebugMsgLevel( QStringLiteral( "CANVAS refresh scheduling" ), 2 );
547 
548  // schedule a refresh
549  mRefreshTimer->start( 1 );
550 }
551 
552 void QgsMapCanvas::refreshMap()
553 {
554  Q_ASSERT( mRefreshScheduled );
555 
556  QgsDebugMsgLevel( QStringLiteral( "CANVAS refresh!" ), 3 );
557 
558  stopRendering(); // if any...
559  stopPreviewJobs();
560 
561  //build the expression context
562  QgsExpressionContext expressionContext;
563  expressionContext << QgsExpressionContextUtils::globalScope()
567  if ( QgsExpressionContextScopeGenerator *generator = dynamic_cast< QgsExpressionContextScopeGenerator * >( mController ) )
568  {
569  expressionContext << generator->createExpressionContextScope();
570  }
571  expressionContext << defaultExpressionContextScope()
572  << new QgsExpressionContextScope( mExpressionContextScope );
573 
574  mSettings.setExpressionContext( expressionContext );
575  mSettings.setPathResolver( QgsProject::instance()->pathResolver() );
576 
577  if ( !mTheme.isEmpty() )
578  {
579  // IMPORTANT: we MUST set the layer style overrides here! (At the time of writing this
580  // comment) retrieving layer styles from the theme collection gives an XML snapshot of the
581  // current state of the style. If we had stored the style overrides earlier (such as in
582  // mapThemeChanged slot) then this xml could be out of date...
583  // TODO: if in future QgsMapThemeCollection::mapThemeStyleOverrides is changed to
584  // just return the style name, we can instead set the overrides in mapThemeChanged and not here
585  mSettings.setLayerStyleOverrides( QgsProject::instance()->mapThemeCollection()->mapThemeStyleOverrides( mTheme ) );
586  }
587 
588  // create the renderer job
589  Q_ASSERT( !mJob );
590  mJobCanceled = false;
591  if ( mUseParallelRendering )
592  mJob = new QgsMapRendererParallelJob( mSettings );
593  else
594  mJob = new QgsMapRendererSequentialJob( mSettings );
595  connect( mJob, &QgsMapRendererJob::finished, this, &QgsMapCanvas::rendererJobFinished );
596  mJob->setCache( mCache );
597 
598  mJob->start();
599 
600  // from now on we can accept refresh requests again
601  // this must be reset only after the job has been started, because
602  // some providers (yes, it's you WCS and AMS!) during preparation
603  // do network requests and start an internal event loop, which may
604  // end up calling refresh() and would schedule another refresh,
605  // deleting the one we have just started.
606  mRefreshScheduled = false;
607 
608  mMapUpdateTimer.start();
609 
610  emit renderStarting();
611 }
612 
613 void QgsMapCanvas::mapThemeChanged( const QString &theme )
614 {
615  if ( theme == mTheme )
616  {
617  // set the canvas layers to match the new layers contained in the map theme
618  // NOTE: we do this when the theme layers change and not when we are refreshing the map
619  // as setLayers() sets up necessary connections to handle changes to the layers
620  setLayersPrivate( QgsProject::instance()->mapThemeCollection()->mapThemeVisibleLayers( mTheme ) );
621  // IMPORTANT: we don't set the layer style overrides here! (At the time of writing this
622  // comment) retrieving layer styles from the theme collection gives an XML snapshot of the
623  // current state of the style. If changes were made to the style then this xml
624  // snapshot goes out of sync...
625  // TODO: if in future QgsMapThemeCollection::mapThemeStyleOverrides is changed to
626  // just return the style name, we can instead set the overrides here and not in refreshMap()
627 
628  clearCache();
629  refresh();
630  }
631 }
632 
633 void QgsMapCanvas::mapThemeRenamed( const QString &theme, const QString &newTheme )
634 {
635  if ( mTheme.isEmpty() || theme != mTheme )
636  {
637  return;
638  }
639 
640  setTheme( newTheme );
641  refresh();
642 }
643 
644 void QgsMapCanvas::rendererJobFinished()
645 {
646  QgsDebugMsgLevel( QStringLiteral( "CANVAS finish! %1" ).arg( !mJobCanceled ), 2 );
647 
648  mMapUpdateTimer.stop();
649 
650  // TODO: would be better to show the errors in message bar
651  const auto constErrors = mJob->errors();
652  for ( const QgsMapRendererJob::Error &error : constErrors )
653  {
654  QgsMapLayer *layer = QgsProject::instance()->mapLayer( error.layerID );
655  emit renderErrorOccurred( error.message, layer );
656  QgsMessageLog::logMessage( error.layerID + " :: " + error.message, tr( "Rendering" ) );
657  }
658 
659  if ( !mJobCanceled )
660  {
661  // take labeling results before emitting renderComplete, so labeling map tools
662  // connected to signal work with correct results
663  if ( !mJob->usedCachedLabels() )
664  {
665  delete mLabelingResults;
666  mLabelingResults = mJob->takeLabelingResults();
667  }
668 
669  QImage img = mJob->renderedImage();
670 
671  // emit renderComplete to get our decorations drawn
672  QPainter p( &img );
673  emit renderComplete( &p );
674 
675  QgsSettings settings;
676  if ( settings.value( QStringLiteral( "Map/logCanvasRefreshEvent" ), false ).toBool() )
677  {
678  QString logMsg = tr( "Canvas refresh: %1 ms" ).arg( mJob->renderingTime() );
679  QgsMessageLog::logMessage( logMsg, tr( "Rendering" ) );
680  }
681 
682  if ( mDrawRenderingStats )
683  {
684  int w = img.width(), h = img.height();
685  QFont fnt = p.font();
686  fnt.setBold( true );
687  p.setFont( fnt );
688  int lh = p.fontMetrics().height() * 2;
689  QRect r( 0, h - lh, w, lh );
690  p.setPen( Qt::NoPen );
691  p.setBrush( QColor( 0, 0, 0, 110 ) );
692  p.drawRect( r );
693  p.setPen( Qt::white );
694  QString msg = QStringLiteral( "%1 :: %2 ms" ).arg( mUseParallelRendering ? QStringLiteral( "PARALLEL" ) : QStringLiteral( "SEQUENTIAL" ) ).arg( mJob->renderingTime() );
695  p.drawText( r, msg, QTextOption( Qt::AlignCenter ) );
696  }
697 
698  p.end();
699 
700  mMap->setContent( img, imageRect( img, mSettings ) );
701 
702  mLastLayerRenderTime.clear();
703  const auto times = mJob->perLayerRenderingTime();
704  for ( auto it = times.constBegin(); it != times.constEnd(); ++it )
705  {
706  mLastLayerRenderTime.insert( it.key()->id(), it.value() );
707  }
708  if ( mUsePreviewJobs && !mRefreshAfterJob )
709  startPreviewJobs();
710  }
711  else
712  {
713  mRefreshAfterJob = false;
714  }
715 
716  // now we are in a slot called from mJob - do not delete it immediately
717  // so the class is still valid when the execution returns to the class
718  mJob->deleteLater();
719  mJob = nullptr;
720 
721  emit mapCanvasRefreshed();
722 
723  if ( mRefreshAfterJob )
724  {
725  mRefreshAfterJob = false;
726  clearTemporalCache();
727  refresh();
728  }
729 }
730 
731 void QgsMapCanvas::previewJobFinished()
732 {
733  QgsMapRendererQImageJob *job = qobject_cast<QgsMapRendererQImageJob *>( sender() );
734  Q_ASSERT( job );
735 
736  if ( mMap )
737  {
738  mMap->addPreviewImage( job->renderedImage(), job->mapSettings().extent() );
739  mPreviewJobs.removeAll( job );
740 
741  int number = job->property( "number" ).toInt();
742  if ( number < 8 )
743  {
744  startPreviewJob( number + 1 );
745  }
746 
747  delete job;
748  }
749 }
750 
751 QgsRectangle QgsMapCanvas::imageRect( const QImage &img, const QgsMapSettings &mapSettings )
752 {
753  // This is a hack to pass QgsMapCanvasItem::setRect what it
754  // expects (encoding of position and size of the item)
755  const QgsMapToPixel &m2p = mapSettings.mapToPixel();
756  QgsPointXY topLeft = m2p.toMapCoordinates( 0, 0 );
757 #ifdef QGISDEBUG
758  // do not assert this, since it might lead to crashes when changing screen while rendering
759  if ( img.devicePixelRatio() != mapSettings.devicePixelRatio() )
760  {
761  QgsLogger::warning( QStringLiteral( "The renderer map has a wrong device pixel ratio" ) );
762  }
763 #endif
764  double res = m2p.mapUnitsPerPixel() / img.devicePixelRatioF();
765  QgsRectangle rect( topLeft.x(), topLeft.y(), topLeft.x() + img.width()*res, topLeft.y() - img.height()*res );
766  return rect;
767 }
768 
770 {
771  return mUsePreviewJobs;
772 }
773 
775 {
776  mUsePreviewJobs = enabled;
777 }
778 
779 void QgsMapCanvas::setCustomDropHandlers( const QVector<QPointer<QgsCustomDropHandler> > &handlers )
780 {
781  mDropHandlers = handlers;
782 }
783 
784 void QgsMapCanvas::clearTemporalCache()
785 {
786  if ( mCache )
787  {
788  const QList<QgsMapLayer *> layerList = mapSettings().layers();
789  for ( QgsMapLayer *layer : layerList )
790  {
792  {
794  continue;
795 
796  mCache->invalidateCacheForLayer( layer );
797  }
798  }
799  }
800 }
801 
802 void QgsMapCanvas::showContextMenu( QgsMapMouseEvent *event )
803 {
804  const QgsPointXY mapPoint = event->originalMapPoint();
805 
806  mMenu->clear();
807 
808  QMenu *copyCoordinateMenu = new QMenu( tr( "Copy Coordinate" ), mMenu );
809  copyCoordinateMenu->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionEditCopy.svg" ) ) );
810 
811  auto addCoordinateFormat = [ = ]( const QString identifier, const QgsCoordinateReferenceSystem & crs )
812  {
813  QgsCoordinateTransform ct( mSettings.destinationCrs(), crs, mSettings.transformContext() );
814  try
815  {
816  const QgsPointXY transformedPoint = ct.transform( mapPoint );
817 
818  // calculate precision based on visible map extent -- if user is zoomed in, we get better precision!
819  int displayPrecision = 0;
820  try
821  {
822  QgsRectangle extentReproj = ct.transformBoundingBox( extent() );
823  const double mapUnitsPerPixel = ( extentReproj.width() / width() + extentReproj.height() / height() ) * 0.5;
824  if ( mapUnitsPerPixel > 10 )
825  displayPrecision = 0;
826  else if ( mapUnitsPerPixel > 1 )
827  displayPrecision = 1;
828  else if ( mapUnitsPerPixel > 0.1 )
829  displayPrecision = 2;
830  else if ( mapUnitsPerPixel > 0.01 )
831  displayPrecision = 3;
832  else if ( mapUnitsPerPixel > 0.001 )
833  displayPrecision = 4;
834  else if ( mapUnitsPerPixel > 0.0001 )
835  displayPrecision = 5;
836  else if ( mapUnitsPerPixel > 0.00001 )
837  displayPrecision = 6;
838  else if ( mapUnitsPerPixel > 0.000001 )
839  displayPrecision = 7;
840  else if ( mapUnitsPerPixel > 0.0000001 )
841  displayPrecision = 8;
842  else
843  displayPrecision = 9;
844  }
845  catch ( QgsCsException & )
846  {
847  displayPrecision = crs.mapUnits() == QgsUnitTypes::DistanceDegrees ? 5 : 3;
848  }
849 
850  QAction *copyCoordinateAction = new QAction( QStringLiteral( "%3 (%1, %2)" ).arg(
851  QString::number( transformedPoint.x(), 'f', displayPrecision ),
852  QString::number( transformedPoint.y(), 'f', displayPrecision ),
853  identifier ), mMenu );
854 
855  connect( copyCoordinateAction, &QAction::triggered, this, [displayPrecision, transformedPoint]
856  {
857  QClipboard *clipboard = QApplication::clipboard();
858 
859  const QString coordinates = QString::number( transformedPoint.x(), 'f', displayPrecision ) + ',' + QString::number( transformedPoint.y(), 'f', displayPrecision );
860 
861  //if we are on x11 system put text into selection ready for middle button pasting
862  if ( clipboard->supportsSelection() )
863  {
864  clipboard->setText( coordinates, QClipboard::Selection );
865  }
866  clipboard->setText( coordinates, QClipboard::Clipboard );
867 
868  } );
869  copyCoordinateMenu->addAction( copyCoordinateAction );
870  }
871  catch ( QgsCsException & )
872  {
873 
874  }
875  };
876 
877  addCoordinateFormat( tr( "Map CRS — %1" ).arg( mSettings.destinationCrs().userFriendlyIdentifier( QgsCoordinateReferenceSystem::ShortString ) ), mSettings.destinationCrs() );
878  if ( mSettings.destinationCrs() != QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) ) )
879  addCoordinateFormat( tr( "WGS84" ), QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) ) );
880 
881  QgsSettings settings;
882  const QString customCrsString = settings.value( QStringLiteral( "qgis/custom_coordinate_crs" ) ).toString();
883  if ( !customCrsString.isEmpty() )
884  {
885  QgsCoordinateReferenceSystem customCrs( customCrsString );
886  if ( customCrs != mSettings.destinationCrs() && customCrs != QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) ) )
887  {
888  addCoordinateFormat( customCrs.userFriendlyIdentifier( QgsCoordinateReferenceSystem::ShortString ), customCrs );
889  }
890  }
891  copyCoordinateMenu->addSeparator();
892  QAction *setCustomCrsAction = new QAction( tr( "Set Custom CRS…" ), mMenu );
893  connect( setCustomCrsAction, &QAction::triggered, this, [ = ]
894  {
895  QgsProjectionSelectionDialog selector( this );
896  selector.setCrs( QgsCoordinateReferenceSystem( customCrsString ) );
897  if ( selector.exec() )
898  {
899  QgsSettings().setValue( QStringLiteral( "qgis/custom_coordinate_crs" ), selector.crs().authid().isEmpty() ? selector.crs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) : selector.crs().authid() );
900  }
901  } );
902  copyCoordinateMenu->addAction( setCustomCrsAction );
903 
904  mMenu->addMenu( copyCoordinateMenu );
905 
906  if ( mMapTool )
907  mMapTool->populateContextMenu( mMenu );
908 
909  mMenu->exec( event->globalPos() );
910 }
911 
912 void QgsMapCanvas::setTemporalRange( const QgsDateTimeRange &dateTimeRange )
913 {
914  if ( temporalRange() == dateTimeRange )
915  return;
916 
917  mSettings.setTemporalRange( dateTimeRange );
918  mSettings.setIsTemporal( dateTimeRange.begin().isValid() || dateTimeRange.end().isValid() );
919 
920  emit temporalRangeChanged();
921 
922  // we need to discard any previously cached images which have temporal properties enabled, so that these will be updated when
923  // the canvas is redrawn
924  if ( !mJob )
925  clearTemporalCache();
926 
927  autoRefreshTriggered();
928 }
929 
930 const QgsDateTimeRange &QgsMapCanvas::temporalRange() const
931 {
932  return mSettings.temporalRange();
933 }
934 
936 {
937  mInteractionBlockers.append( blocker );
938 }
939 
941 {
942  mInteractionBlockers.removeAll( blocker );
943 }
944 
946 {
947  for ( const QgsMapCanvasInteractionBlocker *block : mInteractionBlockers )
948  {
949  if ( block->blockCanvasInteraction( interaction ) )
950  return false;
951  }
952  return true;
953 }
954 
955 void QgsMapCanvas::mapUpdateTimeout()
956 {
957  if ( mJob )
958  {
959  const QImage &img = mJob->renderedImage();
960  mMap->setContent( img, imageRect( img, mSettings ) );
961  }
962 }
963 
965 {
966  if ( mJob )
967  {
968  QgsDebugMsgLevel( QStringLiteral( "CANVAS stop rendering!" ), 2 );
969  mJobCanceled = true;
970  disconnect( mJob, &QgsMapRendererJob::finished, this, &QgsMapCanvas::rendererJobFinished );
971  connect( mJob, &QgsMapRendererQImageJob::finished, mJob, &QgsMapRendererQImageJob::deleteLater );
972  mJob->cancelWithoutBlocking();
973  mJob = nullptr;
974  }
975  stopPreviewJobs();
976 }
977 
978 //the format defaults to "PNG" if not specified
979 void QgsMapCanvas::saveAsImage( const QString &fileName, QPixmap *theQPixmap, const QString &format )
980 {
981  QPainter painter;
982  QImage image;
983 
984  //
985  //check if the optional QPaintDevice was supplied
986  //
987  if ( theQPixmap )
988  {
989  image = theQPixmap->toImage();
990  painter.begin( &image );
991 
992  // render
993  QgsMapRendererCustomPainterJob job( mSettings, &painter );
994  job.start();
995  job.waitForFinished();
996  emit renderComplete( &painter );
997  }
998  else //use the map view
999  {
1000  image = mMap->contentImage().copy();
1001  painter.begin( &image );
1002  }
1003 
1004  // draw annotations
1005  QStyleOptionGraphicsItem option;
1006  option.initFrom( this );
1007  QGraphicsItem *item = nullptr;
1008  QListIterator<QGraphicsItem *> i( items() );
1009  i.toBack();
1010  while ( i.hasPrevious() )
1011  {
1012  item = i.previous();
1013 
1014  if ( !( item && dynamic_cast< QgsMapCanvasAnnotationItem * >( item ) ) )
1015  {
1016  continue;
1017  }
1018 
1019  painter.save();
1020 
1021  QPointF itemScenePos = item->scenePos();
1022  painter.translate( itemScenePos.x(), itemScenePos.y() );
1023 
1024  item->paint( &painter, &option );
1025 
1026  painter.restore();
1027  }
1028 
1029  painter.end();
1030  image.save( fileName, format.toLocal8Bit().data() );
1031 
1032  QFileInfo myInfo = QFileInfo( fileName );
1033 
1034  // build the world file name
1035  QString outputSuffix = myInfo.suffix();
1036  QString myWorldFileName = myInfo.absolutePath() + '/' + myInfo.completeBaseName() + '.'
1037  + outputSuffix.at( 0 ) + outputSuffix.at( myInfo.suffix().size() - 1 ) + 'w';
1038  QFile myWorldFile( myWorldFileName );
1039  if ( !myWorldFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) //don't use QIODevice::Text
1040  {
1041  return;
1042  }
1043  QTextStream myStream( &myWorldFile );
1045 } // saveAsImage
1046 
1047 
1048 
1050 {
1051  return mapSettings().visibleExtent();
1052 } // extent
1053 
1055 {
1056  return mapSettings().fullExtent();
1057 } // extent
1058 
1059 
1060 void QgsMapCanvas::setExtent( const QgsRectangle &r, bool magnified )
1061 {
1062  QgsRectangle current = extent();
1063 
1064  if ( ( r == current ) && magnified )
1065  return;
1066 
1067  if ( r.isEmpty() )
1068  {
1069  if ( !mSettings.hasValidSettings() )
1070  {
1071  // we can't even just move the map center
1072  QgsDebugMsgLevel( QStringLiteral( "Empty extent - ignoring" ), 2 );
1073  return;
1074  }
1075 
1076  // ### QGIS 3: do not allow empty extent - require users to call setCenter() explicitly
1077  QgsDebugMsgLevel( QStringLiteral( "Empty extent - keeping old scale with new center!" ), 2 );
1078  setCenter( r.center() );
1079  }
1080  else
1081  {
1082  mSettings.setExtent( r, magnified );
1083  }
1084  emit extentsChanged();
1085  updateScale();
1086  if ( mLastExtent.size() > 20 )
1087  mLastExtent.removeAt( 0 );
1088 
1089  //clear all extent items after current index
1090  for ( int i = mLastExtent.size() - 1; i > mLastExtentIndex; i-- )
1091  {
1092  mLastExtent.removeAt( i );
1093  }
1094 
1095  mLastExtent.append( extent() );
1096 
1097  // adjust history to no more than 20
1098  if ( mLastExtent.size() > 20 )
1099  {
1100  mLastExtent.removeAt( 0 );
1101  }
1102 
1103  // the last item is the current extent
1104  mLastExtentIndex = mLastExtent.size() - 1;
1105 
1106  // update controls' enabled state
1107  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
1108  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
1109 }
1110 
1112 {
1113  QgsRectangle canvasExtent = extent;
1114  if ( extent.crs() != mapSettings().destinationCrs() )
1115  {
1116  QgsCoordinateTransform ct( extent.crs(), mapSettings().destinationCrs(), QgsProject::instance() );
1117  canvasExtent = ct.transform( extent );
1118 
1119  if ( canvasExtent.isEmpty() )
1120  {
1121  return false;
1122  }
1123  }
1124 
1125  setExtent( canvasExtent, true );
1126  return true;
1127 }
1128 
1130 {
1131  const QgsRectangle r = mapSettings().extent();
1132  const double x = center.x();
1133  const double y = center.y();
1134  const QgsRectangle rect(
1135  x - r.width() / 2.0, y - r.height() / 2.0,
1136  x + r.width() / 2.0, y + r.height() / 2.0
1137  );
1138  if ( ! rect.isEmpty() )
1139  {
1140  setExtent(
1141  rect,
1142  true
1143  );
1144  }
1145 } // setCenter
1146 
1148 {
1150  return r.center();
1151 }
1152 
1153 QgsPointXY QgsMapCanvas::cursorPoint() const
1154 {
1155  return mCursorPoint;
1156 }
1157 
1159 {
1160  return mapSettings().rotation();
1161 } // rotation
1162 
1163 void QgsMapCanvas::setRotation( double degrees )
1164 {
1165  double current = rotation();
1166 
1167  if ( qgsDoubleNear( degrees, current ) )
1168  return;
1169 
1170  mSettings.setRotation( degrees );
1171  emit rotationChanged( degrees );
1172  emit extentsChanged(); // visible extent changes with rotation
1173 } // setRotation
1174 
1175 
1177 {
1178  emit scaleChanged( mapSettings().scale() );
1179 }
1180 
1181 
1183 {
1185  // If the full extent is an empty set, don't do the zoom
1186  if ( !extent.isEmpty() )
1187  {
1188  // Add a 5% margin around the full extent
1189  extent.scale( 1.05 );
1190  setExtent( extent );
1191  }
1192  refresh();
1193 
1194 } // zoomToFullExtent
1195 
1196 
1198 {
1199  if ( mLastExtentIndex > 0 )
1200  {
1201  mLastExtentIndex--;
1202  mSettings.setExtent( mLastExtent[mLastExtentIndex] );
1203  emit extentsChanged();
1204  updateScale();
1205  refresh();
1206  // update controls' enabled state
1207  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
1208  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
1209  }
1210 
1211 } // zoomToPreviousExtent
1212 
1214 {
1215  if ( mLastExtentIndex < mLastExtent.size() - 1 )
1216  {
1217  mLastExtentIndex++;
1218  mSettings.setExtent( mLastExtent[mLastExtentIndex] );
1219  emit extentsChanged();
1220  updateScale();
1221  refresh();
1222  // update controls' enabled state
1223  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
1224  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
1225  }
1226 }// zoomToNextExtent
1227 
1229 {
1230  mLastExtent.clear(); // clear the zoom history list
1231  mLastExtent.append( extent() ) ; // set the current extent in the list
1232  mLastExtentIndex = mLastExtent.size() - 1;
1233  // update controls' enabled state
1234  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
1235  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
1236 }// clearExtentHistory
1237 
1239 {
1240  if ( !layer )
1241  {
1242  // use current layer by default
1243  layer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
1244  }
1245 
1246  if ( !layer || !layer->isSpatial() || layer->selectedFeatureCount() == 0 )
1247  return;
1248 
1249  QgsRectangle rect = layer->boundingBoxOfSelected();
1250  if ( rect.isNull() )
1251  {
1252  emit messageEmitted( tr( "Cannot zoom to selected feature(s)" ), tr( "No extent could be determined." ), Qgis::Warning );
1253  return;
1254  }
1255 
1256  rect = mapSettings().layerExtentToOutputExtent( layer, rect );
1257 
1258  // zoom in if point cannot be distinguished from others
1259  // also check that rect is empty, as it might not in case of multi points
1260  if ( layer->geometryType() == QgsWkbTypes::PointGeometry && rect.isEmpty() )
1261  {
1262  int scaleFactor = 5;
1263  QgsPointXY centerMapCoordinates = rect.center();
1264  QgsPointXY centerLayerCoordinates = mSettings.mapToLayerCoordinates( layer, centerMapCoordinates );
1265  QgsRectangle extentRect = mSettings.mapToLayerCoordinates( layer, extent() ).scaled( 1.0 / scaleFactor, &centerLayerCoordinates );
1267  QgsFeatureIterator fit = layer->getFeatures( req );
1268  QgsFeature f;
1269  QgsPointXY closestPoint;
1270  double closestSquaredDistance = pow( extentRect.width(), 2.0 ) + pow( extentRect.height(), 2.0 );
1271  bool pointFound = false;
1272  while ( fit.nextFeature( f ) )
1273  {
1274  QgsPointXY point = f.geometry().asPoint();
1275  double sqrDist = point.sqrDist( centerLayerCoordinates );
1276  if ( sqrDist > closestSquaredDistance || sqrDist < 4 * std::numeric_limits<double>::epsilon() )
1277  continue;
1278  pointFound = true;
1279  closestPoint = point;
1280  closestSquaredDistance = sqrDist;
1281  }
1282  if ( pointFound )
1283  {
1284  // combine selected point with closest point and scale this rect
1285  rect.combineExtentWith( mSettings.layerToMapCoordinates( layer, closestPoint ) );
1286  rect.scale( scaleFactor, &centerMapCoordinates );
1287  }
1288  }
1289 
1290  zoomToFeatureExtent( rect );
1291 }
1292 
1294 {
1295  // no selected features, only one selected point feature
1296  //or two point features with the same x- or y-coordinates
1297  if ( rect.isEmpty() )
1298  {
1299  // zoom in
1300  QgsPointXY c = rect.center();
1301  rect = extent();
1302  rect.scale( 1.0, &c );
1303  }
1304  //zoom to an area
1305  else
1306  {
1307  // Expand rect to give a bit of space around the selected
1308  // objects so as to keep them clear of the map boundaries
1309  // The same 5% should apply to all margins.
1310  rect.scale( 1.05 );
1311  }
1312 
1313  setExtent( rect );
1314  refresh();
1315 }
1316 
1318 {
1319  if ( !layer )
1320  {
1321  return;
1322  }
1323 
1324  QgsRectangle bbox;
1325  QString errorMsg;
1326  if ( boundingBoxOfFeatureIds( ids, layer, bbox, errorMsg ) )
1327  {
1328  zoomToFeatureExtent( bbox );
1329  }
1330  else
1331  {
1332  emit messageEmitted( tr( "Zoom to feature id failed" ), errorMsg, Qgis::Warning );
1333  }
1334 
1335 }
1336 
1337 void QgsMapCanvas::panToFeatureIds( QgsVectorLayer *layer, const QgsFeatureIds &ids, bool alwaysRecenter )
1338 {
1339  if ( !layer )
1340  {
1341  return;
1342  }
1343 
1344  QgsRectangle bbox;
1345  QString errorMsg;
1346  if ( boundingBoxOfFeatureIds( ids, layer, bbox, errorMsg ) )
1347  {
1348  if ( alwaysRecenter || !mapSettings().extent().contains( bbox ) )
1349  setCenter( bbox.center() );
1350  refresh();
1351  }
1352  else
1353  {
1354  emit messageEmitted( tr( "Pan to feature id failed" ), errorMsg, Qgis::Warning );
1355  }
1356 }
1357 
1358 bool QgsMapCanvas::boundingBoxOfFeatureIds( const QgsFeatureIds &ids, QgsVectorLayer *layer, QgsRectangle &bbox, QString &errorMsg ) const
1359 {
1360  QgsFeatureIterator it = layer->getFeatures( QgsFeatureRequest().setFilterFids( ids ).setNoAttributes() );
1361  bbox.setMinimal();
1362  QgsFeature fet;
1363  int featureCount = 0;
1364  errorMsg.clear();
1365 
1366  while ( it.nextFeature( fet ) )
1367  {
1368  QgsGeometry geom = fet.geometry();
1369  if ( geom.isNull() )
1370  {
1371  errorMsg = tr( "Feature does not have a geometry" );
1372  }
1373  else if ( geom.constGet()->isEmpty() )
1374  {
1375  errorMsg = tr( "Feature geometry is empty" );
1376  }
1377  if ( !errorMsg.isEmpty() )
1378  {
1379  return false;
1380  }
1382  bbox.combineExtentWith( r );
1383  featureCount++;
1384  }
1385 
1386  if ( featureCount != ids.count() )
1387  {
1388  errorMsg = tr( "Feature not found" );
1389  return false;
1390  }
1391 
1392  return true;
1393 }
1394 
1396 {
1397  if ( !layer )
1398  {
1399  // use current layer by default
1400  layer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
1401  }
1402 
1403  if ( !layer || !layer->isSpatial() || layer->selectedFeatureCount() == 0 )
1404  return;
1405 
1406  QgsRectangle rect = layer->boundingBoxOfSelected();
1407  if ( rect.isNull() )
1408  {
1409  emit messageEmitted( tr( "Cannot pan to selected feature(s)" ), tr( "No extent could be determined." ), Qgis::Warning );
1410  return;
1411  }
1412 
1413  rect = mapSettings().layerExtentToOutputExtent( layer, rect );
1414  setCenter( rect.center() );
1415  refresh();
1416 }
1417 
1419  const QColor &color1, const QColor &color2,
1420  int flashes, int duration )
1421 {
1422  if ( !layer )
1423  {
1424  return;
1425  }
1426 
1427  QList< QgsGeometry > geoms;
1428 
1429  QgsFeatureIterator it = layer->getFeatures( QgsFeatureRequest().setFilterFids( ids ).setNoAttributes() );
1430  QgsFeature fet;
1431  while ( it.nextFeature( fet ) )
1432  {
1433  if ( !fet.hasGeometry() )
1434  continue;
1435  geoms << fet.geometry();
1436  }
1437 
1438  flashGeometries( geoms, layer->crs(), color1, color2, flashes, duration );
1439 }
1440 
1441 void QgsMapCanvas::flashGeometries( const QList<QgsGeometry> &geometries, const QgsCoordinateReferenceSystem &crs, const QColor &color1, const QColor &color2, int flashes, int duration )
1442 {
1443  if ( geometries.isEmpty() )
1444  return;
1445 
1446  QgsWkbTypes::GeometryType geomType = QgsWkbTypes::geometryType( geometries.at( 0 ).wkbType() );
1447  QgsRubberBand *rb = new QgsRubberBand( this, geomType );
1448  for ( const QgsGeometry &geom : geometries )
1449  rb->addGeometry( geom, crs );
1450 
1451  if ( geomType == QgsWkbTypes::LineGeometry || geomType == QgsWkbTypes::PointGeometry )
1452  {
1453  rb->setWidth( 2 );
1454  rb->setSecondaryStrokeColor( QColor( 255, 255, 255 ) );
1455  }
1456  if ( geomType == QgsWkbTypes::PointGeometry )
1458 
1459  QColor startColor = color1;
1460  if ( !startColor.isValid() )
1461  {
1462  if ( geomType == QgsWkbTypes::PolygonGeometry )
1463  {
1464  startColor = rb->fillColor();
1465  }
1466  else
1467  {
1468  startColor = rb->strokeColor();
1469  }
1470  startColor.setAlpha( 255 );
1471  }
1472  QColor endColor = color2;
1473  if ( !endColor.isValid() )
1474  {
1475  endColor = startColor;
1476  endColor.setAlpha( 0 );
1477  }
1478 
1479 
1480  QVariantAnimation *animation = new QVariantAnimation( this );
1481  connect( animation, &QVariantAnimation::finished, this, [animation, rb]
1482  {
1483  animation->deleteLater();
1484  delete rb;
1485  } );
1486  connect( animation, &QPropertyAnimation::valueChanged, this, [rb, geomType]( const QVariant & value )
1487  {
1488  QColor c = value.value<QColor>();
1489  if ( geomType == QgsWkbTypes::PolygonGeometry )
1490  {
1491  rb->setFillColor( c );
1492  }
1493  else
1494  {
1495  rb->setStrokeColor( c );
1496  QColor c = rb->secondaryStrokeColor();
1497  c.setAlpha( c.alpha() );
1498  rb->setSecondaryStrokeColor( c );
1499  }
1500  rb->update();
1501  } );
1502 
1503  animation->setDuration( duration * flashes );
1504  animation->setStartValue( endColor );
1505  double midStep = 0.2 / flashes;
1506  for ( int i = 0; i < flashes; ++i )
1507  {
1508  double start = static_cast< double >( i ) / flashes;
1509  animation->setKeyValueAt( start + midStep, startColor );
1510  double end = static_cast< double >( i + 1 ) / flashes;
1511  if ( !qgsDoubleNear( end, 1.0 ) )
1512  animation->setKeyValueAt( end, endColor );
1513  }
1514  animation->setEndValue( endColor );
1515  animation->start();
1516 }
1517 
1518 void QgsMapCanvas::keyPressEvent( QKeyEvent *e )
1519 {
1520  if ( mCanvasProperties->mouseButtonDown || mCanvasProperties->panSelectorDown )
1521  {
1522  emit keyPressed( e );
1523  return;
1524  }
1525 
1526  if ( ! mCanvasProperties->mouseButtonDown )
1527  {
1528  // Don't want to interfer with mouse events
1529 
1530  QgsRectangle currentExtent = mapSettings().visibleExtent();
1531  double dx = std::fabs( currentExtent.width() / 4 );
1532  double dy = std::fabs( currentExtent.height() / 4 );
1533 
1534  switch ( e->key() )
1535  {
1536  case Qt::Key_Left:
1537  QgsDebugMsgLevel( QStringLiteral( "Pan left" ), 2 );
1538  setCenter( center() - QgsVector( dx, 0 ).rotateBy( rotation() * M_PI / 180.0 ) );
1539  refresh();
1540  break;
1541 
1542  case Qt::Key_Right:
1543  QgsDebugMsgLevel( QStringLiteral( "Pan right" ), 2 );
1544  setCenter( center() + QgsVector( dx, 0 ).rotateBy( rotation() * M_PI / 180.0 ) );
1545  refresh();
1546  break;
1547 
1548  case Qt::Key_Up:
1549  QgsDebugMsgLevel( QStringLiteral( "Pan up" ), 2 );
1550  setCenter( center() + QgsVector( 0, dy ).rotateBy( rotation() * M_PI / 180.0 ) );
1551  refresh();
1552  break;
1553 
1554  case Qt::Key_Down:
1555  QgsDebugMsgLevel( QStringLiteral( "Pan down" ), 2 );
1556  setCenter( center() - QgsVector( 0, dy ).rotateBy( rotation() * M_PI / 180.0 ) );
1557  refresh();
1558  break;
1559 
1560 
1561 
1562  case Qt::Key_Space:
1563  QgsDebugMsgLevel( QStringLiteral( "Pressing pan selector" ), 2 );
1564 
1565  //mCanvasProperties->dragging = true;
1566  if ( ! e->isAutoRepeat() )
1567  {
1568  QApplication::setOverrideCursor( Qt::ClosedHandCursor );
1569  mCanvasProperties->panSelectorDown = true;
1570  panActionStart( mCanvasProperties->mouseLastXY );
1571  }
1572  break;
1573 
1574  case Qt::Key_PageUp:
1575  QgsDebugMsgLevel( QStringLiteral( "Zoom in" ), 2 );
1576  zoomIn();
1577  break;
1578 
1579  case Qt::Key_PageDown:
1580  QgsDebugMsgLevel( QStringLiteral( "Zoom out" ), 2 );
1581  zoomOut();
1582  break;
1583 
1584 #if 0
1585  case Qt::Key_P:
1586  mUseParallelRendering = !mUseParallelRendering;
1587  refresh();
1588  break;
1589 
1590  case Qt::Key_S:
1591  mDrawRenderingStats = !mDrawRenderingStats;
1592  refresh();
1593  break;
1594 #endif
1595 
1596  default:
1597  // Pass it on
1598  if ( mMapTool )
1599  {
1600  mMapTool->keyPressEvent( e );
1601  }
1602  else e->ignore();
1603 
1604  QgsDebugMsgLevel( "Ignoring key: " + QString::number( e->key() ), 2 );
1605  }
1606  }
1607 
1608  emit keyPressed( e );
1609 
1610 } //keyPressEvent()
1611 
1612 void QgsMapCanvas::keyReleaseEvent( QKeyEvent *e )
1613 {
1614  QgsDebugMsgLevel( QStringLiteral( "keyRelease event" ), 2 );
1615 
1616  switch ( e->key() )
1617  {
1618  case Qt::Key_Space:
1619  if ( !e->isAutoRepeat() && mCanvasProperties->panSelectorDown )
1620  {
1621  QgsDebugMsgLevel( QStringLiteral( "Releasing pan selector" ), 2 );
1622  QApplication::restoreOverrideCursor();
1623  mCanvasProperties->panSelectorDown = false;
1624  panActionEnd( mCanvasProperties->mouseLastXY );
1625  }
1626  break;
1627 
1628  default:
1629  // Pass it on
1630  if ( mMapTool )
1631  {
1632  mMapTool->keyReleaseEvent( e );
1633  }
1634  else e->ignore();
1635 
1636  QgsDebugMsgLevel( "Ignoring key release: " + QString::number( e->key() ), 2 );
1637  }
1638 
1639  emit keyReleased( e );
1640 
1641 } //keyReleaseEvent()
1642 
1643 
1645 {
1646  // call handler of current map tool
1647  if ( mMapTool )
1648  {
1649  std::unique_ptr<QgsMapMouseEvent> me( new QgsMapMouseEvent( this, e ) );
1650  mMapTool->canvasDoubleClickEvent( me.get() );
1651  }
1652 }// mouseDoubleClickEvent
1653 
1654 
1655 void QgsMapCanvas::beginZoomRect( QPoint pos )
1656 {
1657  mZoomRect.setRect( 0, 0, 0, 0 );
1658  QApplication::setOverrideCursor( mZoomCursor );
1659  mZoomDragging = true;
1660  mZoomRubberBand.reset( new QgsRubberBand( this, QgsWkbTypes::PolygonGeometry ) );
1661  QColor color( Qt::blue );
1662  color.setAlpha( 63 );
1663  mZoomRubberBand->setColor( color );
1664  mZoomRect.setTopLeft( pos );
1665 }
1666 
1667 void QgsMapCanvas::endZoomRect( QPoint pos )
1668 {
1669  mZoomDragging = false;
1670  mZoomRubberBand.reset( nullptr );
1671  QApplication::restoreOverrideCursor();
1672 
1673  // store the rectangle
1674  mZoomRect.setRight( pos.x() );
1675  mZoomRect.setBottom( pos.y() );
1676 
1677  if ( mZoomRect.width() < 5 && mZoomRect.height() < 5 )
1678  {
1679  //probably a mistake - would result in huge zoom!
1680  return;
1681  }
1682 
1683  //account for bottom right -> top left dragging
1684  mZoomRect = mZoomRect.normalized();
1685 
1686  // set center and zoom
1687  const QSize &zoomRectSize = mZoomRect.size();
1688  const QSize &canvasSize = mSettings.outputSize();
1689  double sfx = static_cast< double >( zoomRectSize.width() ) / canvasSize.width();
1690  double sfy = static_cast< double >( zoomRectSize.height() ) / canvasSize.height();
1691  double sf = std::max( sfx, sfy );
1692 
1693  QgsPointXY c = mSettings.mapToPixel().toMapCoordinates( mZoomRect.center() );
1694 
1695  zoomByFactor( sf, &c );
1696  refresh();
1697 }
1698 
1699 void QgsMapCanvas::mousePressEvent( QMouseEvent *e )
1700 {
1701  //use middle mouse button for panning, map tools won't receive any events in that case
1702  if ( e->button() == Qt::MidButton )
1703  {
1704  mCanvasProperties->panSelectorDown = true;
1705  panActionStart( mCanvasProperties->mouseLastXY );
1706  }
1707  else
1708  {
1709  // call handler of current map tool
1710  if ( mMapTool )
1711  {
1712  if ( mMapTool->flags() & QgsMapTool::AllowZoomRect && e->button() == Qt::LeftButton
1713  && e->modifiers() & Qt::ShiftModifier )
1714  {
1715  beginZoomRect( e->pos() );
1716  return;
1717  }
1718  else if ( mMapTool->flags() & QgsMapTool::ShowContextMenu && e->button() == Qt::RightButton )
1719  {
1720  std::unique_ptr<QgsMapMouseEvent> me( new QgsMapMouseEvent( this, e ) );
1721  showContextMenu( me.get() );
1722  return;
1723  }
1724  else
1725  {
1726  std::unique_ptr<QgsMapMouseEvent> me( new QgsMapMouseEvent( this, e ) );
1727  mMapTool->canvasPressEvent( me.get() );
1728  }
1729  }
1730  }
1731 
1732  if ( mCanvasProperties->panSelectorDown )
1733  {
1734  return;
1735  }
1736 
1737  mCanvasProperties->mouseButtonDown = true;
1738  mCanvasProperties->rubberStartPoint = e->pos();
1739 }
1740 
1741 void QgsMapCanvas::mouseReleaseEvent( QMouseEvent *e )
1742 {
1743  //use middle mouse button for panning, map tools won't receive any events in that case
1744  if ( e->button() == Qt::MidButton )
1745  {
1746  mCanvasProperties->panSelectorDown = false;
1747  panActionEnd( mCanvasProperties->mouseLastXY );
1748  }
1749  else if ( e->button() == Qt::BackButton )
1750  {
1752  return;
1753  }
1754  else if ( e->button() == Qt::ForwardButton )
1755  {
1756  zoomToNextExtent();
1757  return;
1758  }
1759  else
1760  {
1761  if ( mZoomDragging && e->button() == Qt::LeftButton )
1762  {
1763  endZoomRect( e->pos() );
1764  return;
1765  }
1766 
1767  // call handler of current map tool
1768  if ( mMapTool )
1769  {
1770  // right button was pressed in zoom tool? return to previous non zoom tool
1771  if ( e->button() == Qt::RightButton && mMapTool->flags() & QgsMapTool::Transient )
1772  {
1773  QgsDebugMsgLevel( QStringLiteral( "Right click in map tool zoom or pan, last tool is %1." ).arg(
1774  mLastNonZoomMapTool ? QStringLiteral( "not null" ) : QStringLiteral( "null" ) ), 2 );
1775 
1776  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
1777 
1778  // change to older non-zoom tool
1779  if ( mLastNonZoomMapTool
1780  && ( !( mLastNonZoomMapTool->flags() & QgsMapTool::EditTool )
1781  || ( vlayer && vlayer->isEditable() ) ) )
1782  {
1783  QgsMapTool *t = mLastNonZoomMapTool;
1784  mLastNonZoomMapTool = nullptr;
1785  setMapTool( t );
1786  }
1787  return;
1788  }
1789  std::unique_ptr<QgsMapMouseEvent> me( new QgsMapMouseEvent( this, e ) );
1790  mMapTool->canvasReleaseEvent( me.get() );
1791  }
1792  }
1793 
1794 
1795  mCanvasProperties->mouseButtonDown = false;
1796 
1797  if ( mCanvasProperties->panSelectorDown )
1798  return;
1799 
1800 }
1801 
1802 void QgsMapCanvas::resizeEvent( QResizeEvent *e )
1803 {
1804  QGraphicsView::resizeEvent( e );
1805  mResizeTimer->start( 500 ); // in charge of refreshing canvas
1806 
1807  double oldScale = mSettings.scale();
1808  QSize lastSize = viewport()->size();
1809  mSettings.setOutputSize( lastSize );
1810 
1811  mScene->setSceneRect( QRectF( 0, 0, lastSize.width(), lastSize.height() ) );
1812 
1813  moveCanvasContents( true );
1814 
1815  if ( mScaleLocked )
1816  {
1817  double scaleFactor = oldScale / mSettings.scale();
1818  QgsRectangle r = mSettings.extent();
1819  QgsPointXY center = r.center();
1820  r.scale( scaleFactor, &center );
1821  mSettings.setExtent( r );
1822  }
1823  else
1824  {
1825  updateScale();
1826  }
1827 
1828  emit extentsChanged();
1829 }
1830 
1831 void QgsMapCanvas::paintEvent( QPaintEvent *e )
1832 {
1833  // no custom event handling anymore
1834 
1835  QGraphicsView::paintEvent( e );
1836 } // paintEvent
1837 
1839 {
1840  const QList<QGraphicsItem *> items = mScene->items();
1841  for ( QGraphicsItem *gi : items )
1842  {
1843  QgsMapCanvasItem *item = dynamic_cast<QgsMapCanvasItem *>( gi );
1844 
1845  if ( item )
1846  {
1847  item->updatePosition();
1848  }
1849  }
1850 }
1851 
1852 
1853 void QgsMapCanvas::wheelEvent( QWheelEvent *e )
1854 {
1855  // Zoom the map canvas in response to a mouse wheel event. Moving the
1856  // wheel forward (away) from the user zooms in
1857 
1858  QgsDebugMsgLevel( "Wheel event delta " + QString::number( e->delta() ), 2 );
1859 
1860  if ( mMapTool )
1861  {
1862  mMapTool->wheelEvent( e );
1863  if ( e->isAccepted() )
1864  return;
1865  }
1866 
1867  if ( e->delta() == 0 )
1868  {
1869  e->accept();
1870  return;
1871  }
1872 
1873  double zoomFactor = e->angleDelta().y() > 0 ? 1. / zoomInFactor() : zoomOutFactor();
1874 
1875  // "Normal" mouse have an angle delta of 120, precision mouses provide data faster, in smaller steps
1876  zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 120.0 * std::fabs( e->angleDelta().y() );
1877 
1878  if ( e->modifiers() & Qt::ControlModifier )
1879  {
1880  //holding ctrl while wheel zooming results in a finer zoom
1881  zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 20.0;
1882  }
1883 
1884  double signedWheelFactor = e->angleDelta().y() > 0 ? 1 / zoomFactor : zoomFactor;
1885 
1886  // zoom map to mouse cursor by scaling
1887  QgsPointXY oldCenter = center();
1888  QgsPointXY mousePos( getCoordinateTransform()->toMapCoordinates( e->x(), e->y() ) );
1889  QgsPointXY newCenter( mousePos.x() + ( ( oldCenter.x() - mousePos.x() ) * signedWheelFactor ),
1890  mousePos.y() + ( ( oldCenter.y() - mousePos.y() ) * signedWheelFactor ) );
1891 
1892  zoomByFactor( signedWheelFactor, &newCenter );
1893  e->accept();
1894 }
1895 
1896 void QgsMapCanvas::setWheelFactor( double factor )
1897 {
1898  mWheelZoomFactor = factor;
1899 }
1900 
1902 {
1903  // magnification is alreday handled in zoomByFactor
1904  zoomByFactor( zoomInFactor() );
1905 }
1906 
1908 {
1909  // magnification is alreday handled in zoomByFactor
1910  zoomByFactor( zoomOutFactor() );
1911 }
1912 
1913 void QgsMapCanvas::zoomScale( double newScale, bool ignoreScaleLock )
1914 {
1915  zoomByFactor( newScale / scale(), nullptr, ignoreScaleLock );
1916 }
1917 
1918 void QgsMapCanvas::zoomWithCenter( int x, int y, bool zoomIn )
1919 {
1920  double scaleFactor = ( zoomIn ? zoomInFactor() : zoomOutFactor() );
1921 
1922  // transform the mouse pos to map coordinates
1924 
1925  if ( mScaleLocked )
1926  {
1928  }
1929  else
1930  {
1932  r.scale( scaleFactor, &center );
1933  setExtent( r, true );
1934  refresh();
1935  }
1936 }
1937 
1938 void QgsMapCanvas::setScaleLocked( bool isLocked )
1939 {
1940  mScaleLocked = isLocked;
1941 }
1942 
1943 void QgsMapCanvas::mouseMoveEvent( QMouseEvent *e )
1944 {
1945  mCanvasProperties->mouseLastXY = e->pos();
1946 
1947  if ( mCanvasProperties->panSelectorDown )
1948  {
1949  panAction( e );
1950  }
1951  else if ( mZoomDragging )
1952  {
1953  mZoomRect.setBottomRight( e->pos() );
1954  mZoomRubberBand->setToCanvasRectangle( mZoomRect );
1955  mZoomRubberBand->show();
1956  }
1957  else
1958  {
1959  // call handler of current map tool
1960  if ( mMapTool )
1961  {
1962  std::unique_ptr<QgsMapMouseEvent> me( new QgsMapMouseEvent( this, e ) );
1963  mMapTool->canvasMoveEvent( me.get() );
1964  }
1965  }
1966 
1967  // show x y on status bar (if we are mid pan operation, then the cursor point hasn't changed!)
1968  if ( !panOperationInProgress() )
1969  {
1970  mCursorPoint = getCoordinateTransform()->toMapCoordinates( mCanvasProperties->mouseLastXY );
1971  emit xyCoordinates( mCursorPoint );
1972  }
1973 }
1974 
1975 void QgsMapCanvas::setMapTool( QgsMapTool *tool, bool clean )
1976 {
1977  if ( !tool )
1978  return;
1979 
1980  if ( mMapTool )
1981  {
1982  if ( clean )
1983  mMapTool->clean();
1984 
1985  disconnect( mMapTool, &QObject::destroyed, this, &QgsMapCanvas::mapToolDestroyed );
1986  mMapTool->deactivate();
1987  }
1988 
1989  if ( ( tool->flags() & QgsMapTool::Transient )
1990  && mMapTool && !( mMapTool->flags() & QgsMapTool::Transient ) )
1991  {
1992  // if zoom or pan tool will be active, save old tool
1993  // to bring it back on right click
1994  // (but only if it wasn't also zoom or pan tool)
1995  mLastNonZoomMapTool = mMapTool;
1996  }
1997  else
1998  {
1999  mLastNonZoomMapTool = nullptr;
2000  }
2001 
2002  QgsMapTool *oldTool = mMapTool;
2003 
2004  // set new map tool and activate it
2005  mMapTool = tool;
2006  emit mapToolSet( mMapTool, oldTool );
2007  if ( mMapTool )
2008  {
2009  connect( mMapTool, &QObject::destroyed, this, &QgsMapCanvas::mapToolDestroyed );
2010  mMapTool->activate();
2011  }
2012 
2013 } // setMapTool
2014 
2016 {
2017  if ( mMapTool && mMapTool == tool )
2018  {
2019  disconnect( mMapTool, &QObject::destroyed, this, &QgsMapCanvas::mapToolDestroyed );
2020  QgsMapTool *oldTool = mMapTool;
2021  mMapTool = nullptr;
2022  oldTool->deactivate();
2023  emit mapToolSet( nullptr, oldTool );
2024  setCursor( Qt::ArrowCursor );
2025  }
2026 
2027  if ( mLastNonZoomMapTool && mLastNonZoomMapTool == tool )
2028  {
2029  mLastNonZoomMapTool = nullptr;
2030  }
2031 }
2032 
2033 void QgsMapCanvas::setCanvasColor( const QColor &color )
2034 {
2035  if ( canvasColor() == color )
2036  return;
2037 
2038  // background of map's pixmap
2039  mSettings.setBackgroundColor( color );
2040 
2041  // background of the QGraphicsView
2042  QBrush bgBrush( color );
2043  setBackgroundBrush( bgBrush );
2044 #if 0
2045  QPalette palette;
2046  palette.setColor( backgroundRole(), color );
2047  setPalette( palette );
2048 #endif
2049 
2050  // background of QGraphicsScene
2051  mScene->setBackgroundBrush( bgBrush );
2052 
2053  refresh();
2054 
2055  emit canvasColorChanged();
2056 }
2057 
2059 {
2060  return mScene->backgroundBrush().color();
2061 }
2062 
2063 void QgsMapCanvas::setSelectionColor( const QColor &color )
2064 {
2065  if ( mSettings.selectionColor() == color )
2066  return;
2067 
2068  mSettings.setSelectionColor( color );
2069 
2070  if ( mCache )
2071  {
2072  bool hasSelectedFeatures = false;
2073  const auto layers = mSettings.layers();
2074  for ( QgsMapLayer *layer : layers )
2075  {
2076  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
2077  if ( vlayer && vlayer->selectedFeatureCount() )
2078  {
2079  hasSelectedFeatures = true;
2080  break;
2081  }
2082  }
2083 
2084  if ( hasSelectedFeatures )
2085  {
2086  mCache->clear();
2087  refresh();
2088  }
2089  }
2090 }
2091 
2093 {
2094  return mSettings.selectionColor();
2095 }
2096 
2098 {
2099  return mapSettings().layers().size();
2100 } // layerCount
2101 
2102 
2103 QList<QgsMapLayer *> QgsMapCanvas::layers() const
2104 {
2105  return mapSettings().layers();
2106 }
2107 
2109 {
2110  // called when a layer has changed visibility setting
2111  refresh();
2112 }
2113 
2114 void QgsMapCanvas::freeze( bool frozen )
2115 {
2116  mFrozen = frozen;
2117 }
2118 
2120 {
2121  return mFrozen;
2122 }
2123 
2125 {
2126  return mapSettings().mapUnitsPerPixel();
2127 }
2128 
2130 {
2131  return mapSettings().mapUnits();
2132 }
2133 
2134 QMap<QString, QString> QgsMapCanvas::layerStyleOverrides() const
2135 {
2136  return mSettings.layerStyleOverrides();
2137 }
2138 
2139 void QgsMapCanvas::setLayerStyleOverrides( const QMap<QString, QString> &overrides )
2140 {
2141  if ( overrides == mSettings.layerStyleOverrides() )
2142  return;
2143 
2144  mSettings.setLayerStyleOverrides( overrides );
2145  clearCache();
2147 }
2148 
2149 void QgsMapCanvas::setTheme( const QString &theme )
2150 {
2151  if ( mTheme == theme )
2152  return;
2153 
2154  clearCache();
2155  if ( theme.isEmpty() || !QgsProject::instance()->mapThemeCollection()->hasMapTheme( theme ) )
2156  {
2157  mTheme.clear();
2158  mSettings.setLayerStyleOverrides( QMap< QString, QString>() );
2159  setLayers( QgsProject::instance()->mapThemeCollection()->masterVisibleLayers() );
2160  emit themeChanged( QString() );
2161  }
2162  else
2163  {
2164  mTheme = theme;
2165  setLayersPrivate( QgsProject::instance()->mapThemeCollection()->mapThemeVisibleLayers( mTheme ) );
2166  emit themeChanged( theme );
2167  }
2168 }
2169 
2171 {
2172  mRenderFlag = flag;
2173 
2174  if ( mRenderFlag )
2175  {
2176  refresh();
2177  }
2178  else
2179  stopRendering();
2180 }
2181 
2182 #if 0
2183 void QgsMapCanvas::connectNotify( const char *signal )
2184 {
2185  Q_UNUSED( signal )
2186  QgsDebugMsg( "QgsMapCanvas connected to " + QString( signal ) );
2187 } //connectNotify
2188 #endif
2189 
2190 void QgsMapCanvas::layerRepaintRequested( bool deferred )
2191 {
2192  if ( !deferred )
2193  refresh();
2194 }
2195 
2196 void QgsMapCanvas::autoRefreshTriggered()
2197 {
2198  if ( mJob )
2199  {
2200  // canvas is currently being redrawn, so we defer the last requested
2201  // auto refresh until current rendering job finishes
2202  mRefreshAfterJob = true;
2203  return;
2204  }
2205 
2206  refresh();
2207 }
2208 
2209 void QgsMapCanvas::updateAutoRefreshTimer()
2210 {
2211  // min auto refresh interval stores the smallest interval between layer auto refreshes. We automatically
2212  // trigger a map refresh on this minimum interval
2213  int minAutoRefreshInterval = -1;
2214  const auto layers = mSettings.layers();
2215  for ( QgsMapLayer *layer : layers )
2216  {
2218  minAutoRefreshInterval = minAutoRefreshInterval > 0 ? std::min( layer->autoRefreshInterval(), minAutoRefreshInterval ) : layer->autoRefreshInterval();
2219  }
2220 
2221  if ( minAutoRefreshInterval > 0 )
2222  {
2223  mAutoRefreshTimer.setInterval( minAutoRefreshInterval );
2224  mAutoRefreshTimer.start();
2225  }
2226  else
2227  {
2228  mAutoRefreshTimer.stop();
2229  }
2230 }
2231 
2232 void QgsMapCanvas::projectThemesChanged()
2233 {
2234  if ( mTheme.isEmpty() )
2235  return;
2236 
2237  if ( !QgsProject::instance()->mapThemeCollection()->hasMapTheme( mTheme ) )
2238  {
2239  // theme has been removed - stop following
2240  setTheme( QString() );
2241  }
2242 
2243 }
2244 
2246 {
2247  return mMapTool;
2248 }
2249 
2250 void QgsMapCanvas::panActionEnd( QPoint releasePoint )
2251 {
2252  // move map image and other items to standard position
2253  moveCanvasContents( true ); // true means reset
2254 
2255  // use start and end box points to calculate the extent
2256  QgsPointXY start = getCoordinateTransform()->toMapCoordinates( mCanvasProperties->rubberStartPoint );
2257  QgsPointXY end = getCoordinateTransform()->toMapCoordinates( releasePoint );
2258 
2259  // modify the center
2260  double dx = end.x() - start.x();
2261  double dy = end.y() - start.y();
2262  QgsPointXY c = center();
2263  c.set( c.x() - dx, c.y() - dy );
2264  setCenter( c );
2265 
2266  refresh();
2267 }
2268 
2269 void QgsMapCanvas::panActionStart( QPoint releasePoint )
2270 {
2271  mCanvasProperties->rubberStartPoint = releasePoint;
2272 
2273  mDa = QgsDistanceArea();
2274  mDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
2275  mDa.setSourceCrs( mapSettings().destinationCrs(), QgsProject::instance()->transformContext() );
2276 }
2277 
2278 void QgsMapCanvas::panAction( QMouseEvent *e )
2279 {
2280  Q_UNUSED( e )
2281 
2282  QgsPointXY currentMapPoint = getCoordinateTransform()->toMapCoordinates( e->pos() );
2283  QgsPointXY startMapPoint = getCoordinateTransform()->toMapCoordinates( mCanvasProperties->rubberStartPoint );
2284  emit panDistanceBearingChanged( mDa.measureLine( currentMapPoint, startMapPoint ), mDa.lengthUnits(), mDa.bearing( currentMapPoint, startMapPoint ) * 180 / M_PI );
2285 
2286  // move all map canvas items
2288 }
2289 
2291 {
2292  QPoint pnt( 0, 0 );
2293  if ( !reset )
2294  pnt += mCanvasProperties->mouseLastXY - mCanvasProperties->rubberStartPoint;
2295 
2296  setSceneRect( -pnt.x(), -pnt.y(), viewport()->size().width(), viewport()->size().height() );
2297 }
2298 
2299 void QgsMapCanvas::dropEvent( QDropEvent *event )
2300 {
2301  if ( QgsMimeDataUtils::isUriList( event->mimeData() ) )
2302  {
2304  bool allHandled = true;
2305  for ( const QgsMimeDataUtils::Uri &uri : lst )
2306  {
2307  bool handled = false;
2308  for ( QgsCustomDropHandler *handler : qgis::as_const( mDropHandlers ) )
2309  {
2310  if ( handler && handler->customUriProviderKey() == uri.providerKey )
2311  {
2312  if ( handler->handleCustomUriCanvasDrop( uri, this ) )
2313  {
2314  handled = true;
2315  break;
2316  }
2317  }
2318  }
2319  if ( !handled )
2320  allHandled = false;
2321  }
2322  if ( allHandled )
2323  event->accept();
2324  else
2325  event->ignore();
2326  }
2327  else
2328  {
2329  event->ignore();
2330  }
2331 }
2332 
2334 {
2335  return mCanvasProperties->mouseLastXY;
2336 }
2337 
2338 void QgsMapCanvas::setPreviewModeEnabled( bool previewEnabled )
2339 {
2340  if ( !mPreviewEffect )
2341  {
2342  return;
2343  }
2344 
2345  mPreviewEffect->setEnabled( previewEnabled );
2346 }
2347 
2349 {
2350  if ( !mPreviewEffect )
2351  {
2352  return false;
2353  }
2354 
2355  return mPreviewEffect->isEnabled();
2356 }
2357 
2359 {
2360  if ( !mPreviewEffect )
2361  {
2362  return;
2363  }
2364 
2365  mPreviewEffect->setMode( mode );
2366 }
2367 
2369 {
2370  if ( !mPreviewEffect )
2371  {
2373  }
2374 
2375  return mPreviewEffect->mode();
2376 }
2377 
2379 {
2380  if ( !mSnappingUtils )
2381  {
2382  // associate a dummy instance, but better than null pointer
2383  QgsMapCanvas *c = const_cast<QgsMapCanvas *>( this );
2384  c->mSnappingUtils = new QgsMapCanvasSnappingUtils( c, c );
2385  }
2386  return mSnappingUtils;
2387 }
2388 
2390 {
2391  mSnappingUtils = utils;
2392 }
2393 
2394 void QgsMapCanvas::readProject( const QDomDocument &doc )
2395 {
2396  QgsProject *project = qobject_cast< QgsProject * >( sender() );
2397 
2398  QDomNodeList nodes = doc.elementsByTagName( QStringLiteral( "mapcanvas" ) );
2399  if ( nodes.count() )
2400  {
2401  QDomNode node = nodes.item( 0 );
2402 
2403  // Search the specific MapCanvas node using the name
2404  if ( nodes.count() > 1 )
2405  {
2406  for ( int i = 0; i < nodes.size(); ++i )
2407  {
2408  QDomElement elementNode = nodes.at( i ).toElement();
2409 
2410  if ( elementNode.hasAttribute( QStringLiteral( "name" ) ) && elementNode.attribute( QStringLiteral( "name" ) ) == objectName() )
2411  {
2412  node = nodes.at( i );
2413  break;
2414  }
2415  }
2416  }
2417 
2418  QgsMapSettings tmpSettings;
2419  tmpSettings.readXml( node );
2420  if ( objectName() != QStringLiteral( "theMapCanvas" ) )
2421  {
2422  // never manually set the crs for the main canvas - this is instead connected to the project CRS
2423  setDestinationCrs( tmpSettings.destinationCrs() );
2424  }
2425  setExtent( tmpSettings.extent() );
2426  setRotation( tmpSettings.rotation() );
2428 
2429  clearExtentHistory(); // clear the extent history on project load
2430 
2431  QDomElement elem = node.toElement();
2432  if ( elem.hasAttribute( QStringLiteral( "theme" ) ) )
2433  {
2434  if ( QgsProject::instance()->mapThemeCollection()->hasMapTheme( elem.attribute( QStringLiteral( "theme" ) ) ) )
2435  {
2436  setTheme( elem.attribute( QStringLiteral( "theme" ) ) );
2437  }
2438  }
2439  setAnnotationsVisible( elem.attribute( QStringLiteral( "annotationsVisible" ), QStringLiteral( "1" ) ).toInt() );
2440 
2441  // restore canvas expression context
2442  const QDomNodeList scopeElements = elem.elementsByTagName( QStringLiteral( "expressionContextScope" ) );
2443  if ( scopeElements.size() > 0 )
2444  {
2445  const QDomElement scopeElement = scopeElements.at( 0 ).toElement();
2446  mExpressionContextScope.readXml( scopeElement, QgsReadWriteContext() );
2447  }
2448  }
2449  else
2450  {
2451  QgsDebugMsg( QStringLiteral( "Couldn't read mapcanvas information from project" ) );
2452  if ( !project->viewSettings()->defaultViewExtent().isNull() )
2453  {
2455  clearExtentHistory(); // clear the extent history on project load
2456  }
2457  }
2458 }
2459 
2460 void QgsMapCanvas::writeProject( QDomDocument &doc )
2461 {
2462  // create node "mapcanvas" and call mMapRenderer->writeXml()
2463 
2464  QDomNodeList nl = doc.elementsByTagName( QStringLiteral( "qgis" ) );
2465  if ( !nl.count() )
2466  {
2467  QgsDebugMsg( QStringLiteral( "Unable to find qgis element in project file" ) );
2468  return;
2469  }
2470  QDomNode qgisNode = nl.item( 0 ); // there should only be one, so zeroth element OK
2471 
2472  QDomElement mapcanvasNode = doc.createElement( QStringLiteral( "mapcanvas" ) );
2473  mapcanvasNode.setAttribute( QStringLiteral( "name" ), objectName() );
2474  if ( !mTheme.isEmpty() )
2475  mapcanvasNode.setAttribute( QStringLiteral( "theme" ), mTheme );
2476  mapcanvasNode.setAttribute( QStringLiteral( "annotationsVisible" ), mAnnotationsVisible );
2477  qgisNode.appendChild( mapcanvasNode );
2478 
2479  mSettings.writeXml( mapcanvasNode, doc );
2480 
2481  // store canvas expression context
2482  QDomElement scopeElement = doc.createElement( QStringLiteral( "expressionContextScope" ) );
2483  QgsExpressionContextScope tmpScope( mExpressionContextScope );
2484  tmpScope.removeVariable( QStringLiteral( "atlas_featurenumber" ) );
2485  tmpScope.removeVariable( QStringLiteral( "atlas_pagename" ) );
2486  tmpScope.removeVariable( QStringLiteral( "atlas_feature" ) );
2487  tmpScope.removeVariable( QStringLiteral( "atlas_featureid" ) );
2488  tmpScope.removeVariable( QStringLiteral( "atlas_geometry" ) );
2489  tmpScope.writeXml( scopeElement, doc, QgsReadWriteContext() );
2490  mapcanvasNode.appendChild( scopeElement );
2491 
2492  // TODO: store only units, extent, projections, dest CRS
2493 }
2494 
2495 void QgsMapCanvas::zoomByFactor( double scaleFactor, const QgsPointXY *center, bool ignoreScaleLock )
2496 {
2497  if ( mScaleLocked && !ignoreScaleLock )
2498  {
2499  // zoom map to mouse cursor by magnifying
2501  }
2502  else
2503  {
2505  r.scale( scaleFactor, center );
2506  setExtent( r, true );
2507  refresh();
2508  }
2509 }
2510 
2512 {
2513  // Find out which layer it was that sent the signal.
2514  QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( sender() );
2515  if ( layer )
2516  {
2517  emit selectionChanged( layer );
2518  refresh();
2519  }
2520 }
2521 
2522 void QgsMapCanvas::dragEnterEvent( QDragEnterEvent *event )
2523 {
2524  // By default graphics view delegates the drag events to graphics items.
2525  // But we do not want that and by ignoring the drag enter we let the
2526  // parent (e.g. QgisApp) to handle drops of map layers etc.
2527 
2528  // so we ONLY accept the event if we know in advance that a custom drop handler
2529  // wants it
2530 
2531  if ( QgsMimeDataUtils::isUriList( event->mimeData() ) )
2532  {
2534  bool allHandled = true;
2535  for ( const QgsMimeDataUtils::Uri &uri : lst )
2536  {
2537  bool handled = false;
2538  for ( QgsCustomDropHandler *handler : qgis::as_const( mDropHandlers ) )
2539  {
2540  if ( handler->canHandleCustomUriCanvasDrop( uri, this ) )
2541  {
2542  handled = true;
2543  break;
2544  }
2545  }
2546  if ( !handled )
2547  allHandled = false;
2548  }
2549  if ( allHandled )
2550  event->accept();
2551  else
2552  event->ignore();
2553  }
2554  else
2555  {
2556  event->ignore();
2557  }
2558 }
2559 
2560 void QgsMapCanvas::mapToolDestroyed()
2561 {
2562  QgsDebugMsgLevel( QStringLiteral( "maptool destroyed" ), 2 );
2563  mMapTool = nullptr;
2564 }
2565 
2566 bool QgsMapCanvas::event( QEvent *e )
2567 {
2568  if ( !QTouchDevice::devices().empty() )
2569  {
2570  if ( e->type() == QEvent::Gesture )
2571  {
2572  if ( QTapAndHoldGesture *tapAndHoldGesture = qobject_cast< QTapAndHoldGesture * >( static_cast<QGestureEvent *>( e )->gesture( Qt::TapAndHoldGesture ) ) )
2573  {
2574  QPointF pos = tapAndHoldGesture->position();
2575  pos = mapFromGlobal( QPoint( pos.x(), pos.y() ) );
2576  QgsPointXY mapPoint = getCoordinateTransform()->toMapCoordinates( pos.x(), pos.y() );
2577  emit tapAndHoldGestureOccurred( mapPoint, tapAndHoldGesture );
2578  }
2579 
2580  // call handler of current map tool
2581  if ( mMapTool )
2582  {
2583  return mMapTool->gestureEvent( static_cast<QGestureEvent *>( e ) );
2584  }
2585  }
2586  }
2587 
2588  // pass other events to base class
2589  return QGraphicsView::event( e );
2590 }
2591 
2593 {
2594  // reload all layers in canvas
2595  const QList<QgsMapLayer *> layers = mapSettings().layers();
2596  for ( QgsMapLayer *layer : layers )
2597  {
2598  layer->reload();
2599  }
2600 
2601  redrawAllLayers();
2602 }
2603 
2605 {
2606  // clear the cache
2607  clearCache();
2608 
2609  // and then refresh
2610  refresh();
2611 }
2612 
2614 {
2615  while ( mRefreshScheduled || mJob )
2616  {
2617  QgsApplication::processEvents();
2618  }
2619 }
2620 
2622 {
2623  mSettings.setSegmentationTolerance( tolerance );
2624 }
2625 
2627 {
2628  mSettings.setSegmentationToleranceType( type );
2629 }
2630 
2631 QList<QgsMapCanvasAnnotationItem *> QgsMapCanvas::annotationItems() const
2632 {
2633  QList<QgsMapCanvasAnnotationItem *> annotationItemList;
2634  const QList<QGraphicsItem *> items = mScene->items();
2635  for ( QGraphicsItem *gi : items )
2636  {
2637  QgsMapCanvasAnnotationItem *aItem = dynamic_cast< QgsMapCanvasAnnotationItem *>( gi );
2638  if ( aItem )
2639  {
2640  annotationItemList.push_back( aItem );
2641  }
2642  }
2643 
2644  return annotationItemList;
2645 }
2646 
2648 {
2649  mAnnotationsVisible = show;
2650  const QList<QgsMapCanvasAnnotationItem *> items = annotationItems();
2651  for ( QgsMapCanvasAnnotationItem *item : items )
2652  {
2653  item->setVisible( show );
2654  }
2655 }
2656 
2658 {
2659  mSettings.setLabelingEngineSettings( settings );
2660 }
2661 
2663 {
2664  return mSettings.labelingEngineSettings();
2665 }
2666 
2667 void QgsMapCanvas::startPreviewJobs()
2668 {
2669  stopPreviewJobs(); //just in case still running
2670 
2671  //canvas preview jobs aren't compatible with rotation
2672  // TODO fix this
2673  if ( !qgsDoubleNear( mSettings.rotation(), 0.0 ) )
2674  return;
2675 
2676  schedulePreviewJob( 0 );
2677 }
2678 
2679 void QgsMapCanvas::startPreviewJob( int number )
2680 {
2681  QgsRectangle mapRect = mSettings.visibleExtent();
2682 
2683  if ( number == 4 )
2684  number += 1;
2685 
2686  int j = number / 3;
2687  int i = number % 3;
2688 
2689  //copy settings, only update extent
2690  QgsMapSettings jobSettings = mSettings;
2691 
2692  double dx = ( i - 1 ) * mapRect.width();
2693  double dy = ( 1 - j ) * mapRect.height();
2694  QgsRectangle jobExtent = mapRect;
2695 
2696  jobExtent.setXMaximum( jobExtent.xMaximum() + dx );
2697  jobExtent.setXMinimum( jobExtent.xMinimum() + dx );
2698  jobExtent.setYMaximum( jobExtent.yMaximum() + dy );
2699  jobExtent.setYMinimum( jobExtent.yMinimum() + dy );
2700 
2701  jobSettings.setExtent( jobExtent );
2702  jobSettings.setFlag( QgsMapSettings::DrawLabeling, false );
2703  jobSettings.setFlag( QgsMapSettings::RenderPreviewJob, true );
2704 
2705  // truncate preview layers to fast layers
2706  const QList<QgsMapLayer *> layers = jobSettings.layers();
2707  QList< QgsMapLayer * > previewLayers;
2709  context.maxRenderingTimeMs = MAXIMUM_LAYER_PREVIEW_TIME_MS;
2710  for ( QgsMapLayer *layer : layers )
2711  {
2712  context.lastRenderingTimeMs = mLastLayerRenderTime.value( layer->id(), 0 );
2713  QgsDataProvider *provider = layer->dataProvider();
2714  if ( provider && !provider->renderInPreview( context ) )
2715  {
2716  QgsDebugMsgLevel( QStringLiteral( "Layer %1 not rendered because it does not match the renderInPreview criterion %2" ).arg( layer->id() ).arg( mLastLayerRenderTime.value( layer->id() ) ), 3 );
2717  continue;
2718  }
2719 
2720  previewLayers << layer;
2721  }
2722  jobSettings.setLayers( previewLayers );
2723 
2724  QgsMapRendererQImageJob *job = new QgsMapRendererSequentialJob( jobSettings );
2725  job->setProperty( "number", number );
2726  mPreviewJobs.append( job );
2727  connect( job, &QgsMapRendererJob::finished, this, &QgsMapCanvas::previewJobFinished );
2728  job->start();
2729 }
2730 
2731 void QgsMapCanvas::stopPreviewJobs()
2732 {
2733  mPreviewTimer.stop();
2734  const auto previewJobs = mPreviewJobs;
2735  for ( auto previewJob : previewJobs )
2736  {
2737  if ( previewJob )
2738  {
2739  disconnect( previewJob, &QgsMapRendererJob::finished, this, &QgsMapCanvas::previewJobFinished );
2740  connect( previewJob, &QgsMapRendererQImageJob::finished, previewJob, &QgsMapRendererQImageJob::deleteLater );
2741  previewJob->cancelWithoutBlocking();
2742  }
2743  }
2744  mPreviewJobs.clear();
2745 }
2746 
2747 void QgsMapCanvas::schedulePreviewJob( int number )
2748 {
2749  mPreviewTimer.setSingleShot( true );
2750  mPreviewTimer.setInterval( PREVIEW_JOB_DELAY_MS );
2751  disconnect( mPreviewTimerConnection );
2752  mPreviewTimerConnection = connect( &mPreviewTimer, &QTimer::timeout, this, [ = ]()
2753  {
2754  startPreviewJob( number );
2755  } );
2756  mPreviewTimer.start();
2757 }
2758 
2759 bool QgsMapCanvas::panOperationInProgress()
2760 {
2761  if ( mCanvasProperties->panSelectorDown )
2762  return true;
2763 
2764  if ( QgsMapToolPan *panTool = qobject_cast< QgsMapToolPan *>( mMapTool ) )
2765  {
2766  if ( panTool->isDragging() )
2767  return true;
2768  }
2769 
2770  return false;
2771 }
2772 
2773 int QgsMapCanvas::nextZoomLevel( const QList<double> &resolutions, bool zoomIn ) const
2774 {
2775  int resolutionLevel = -1;
2776  double currentResolution = mapUnitsPerPixel();
2777 
2778  for ( int i = 0, n = resolutions.size(); i < n; ++i )
2779  {
2780  if ( qgsDoubleNear( resolutions[i], currentResolution, 0.0001 ) )
2781  {
2782  resolutionLevel = zoomIn ? ( i - 1 ) : ( i + 1 );
2783  break;
2784  }
2785  else if ( currentResolution <= resolutions[i] )
2786  {
2787  resolutionLevel = zoomIn ? ( i - 1 ) : i;
2788  break;
2789  }
2790  }
2791  return ( resolutionLevel < 0 || resolutionLevel >= resolutions.size() ) ? -1 : resolutionLevel;
2792 }
2793 
2794 double QgsMapCanvas::zoomInFactor() const
2795 {
2796  if ( !mZoomResolutions.isEmpty() )
2797  {
2798  int zoomLevel = nextZoomLevel( mZoomResolutions, true );
2799  if ( zoomLevel != -1 )
2800  {
2801  return mZoomResolutions.at( zoomLevel ) / mapUnitsPerPixel();
2802  }
2803  }
2804  return 1 / mWheelZoomFactor;
2805 }
2806 
2807 double QgsMapCanvas::zoomOutFactor() const
2808 {
2809  if ( !mZoomResolutions.isEmpty() )
2810  {
2811  int zoomLevel = nextZoomLevel( mZoomResolutions, false );
2812  if ( zoomLevel != -1 )
2813  {
2814  return mZoomResolutions.at( zoomLevel ) / mapUnitsPerPixel();
2815  }
2816  }
2817  return mWheelZoomFactor;
2818 }
QgsMapCanvas::CanvasProperties::rubberStartPoint
QPoint rubberStartPoint
Beginning point of a rubber band.
Definition: qgsmapcanvas.cpp:122
QgsGeometry::fromPointXY
static QgsGeometry fromPointXY(const QgsPointXY &point)
Creates a new geometry from a QgsPointXY object.
Definition: qgsgeometry.cpp:164
QgsMapCanvas::renderStarting
void renderStarting()
Emitted when the canvas is about to be rendered.
QgsMapCanvas::mouseDoubleClickEvent
void mouseDoubleClickEvent(QMouseEvent *e) override
Definition: qgsmapcanvas.cpp:1644
QgsAbstractGeometry::MaximumAngle
@ MaximumAngle
Maximum angle between generating radii (lines from arc center to output vertices)
Definition: qgsabstractgeometry.h:118
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:369
QgsMapLayer::crs
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:88
QgsMapTool::flags
virtual Flags flags() const
Returns the flags for the map tool.
Definition: qgsmaptool.h:104
QgsMapSettings::labelingEngineSettings
const QgsLabelingEngineSettings & labelingEngineSettings() const
Returns the global configuration of the labeling engine.
Definition: qgsmapsettings.h:535
QgsMapCanvas::renderErrorOccurred
void renderErrorOccurred(const QString &error, QgsMapLayer *layer)
Emitted whenever an error is encountered during a map render operation.
QgsMapCanvas::panToSelected
void panToSelected(QgsVectorLayer *layer=nullptr)
Pan to the selected features of current (vector) layer keeping same extent.
Definition: qgsmapcanvas.cpp:1395
QgsMapCanvas::currentLayerChanged
void currentLayerChanged(QgsMapLayer *layer)
Emitted when the current layer is changed.
QgsMapTool::keyReleaseEvent
virtual void keyReleaseEvent(QKeyEvent *e)
Key event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:187
QgsMapSettings::setDestinationCrs
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
sets destination coordinate reference system
Definition: qgsmapsettings.cpp:309
QgsMapCanvas::dropEvent
void dropEvent(QDropEvent *event) override
Definition: qgsmapcanvas.cpp:2299
qgsexpressioncontextutils.h
QgsMapCanvas::waitWhileRendering
void waitWhileRendering()
Blocks until the rendering job has finished.
Definition: qgsmapcanvas.cpp:2613
QgsMapCanvas::zoomToPreviousExtent
void zoomToPreviousExtent()
Zoom to the previous extent (view)
Definition: qgsmapcanvas.cpp:1197
QgsTemporalProperty::flags
virtual QgsTemporalProperty::Flags flags() const
Returns flags associated to the temporal property.
Definition: qgstemporalproperty.h:74
qgssvgcache.h
QgsMapLayer::hasAutoRefreshEnabled
bool hasAutoRefreshEnabled() const
Returns true if auto refresh is enabled for the layer.
Definition: qgsmaplayer.cpp:681
QgsMapCanvasInteractionBlocker
Definition: qgsmapcanvasinteractionblocker.h:29
QgsMapCanvasAnnotationItem
Definition: qgsmapcanvasannotationitem.h:39
QgsMapRendererJob::usedCachedLabels
virtual bool usedCachedLabels() const =0
Returns true if the render job was able to use a cached labeling solution.
QgsPointXY::y
double y
Definition: qgspointxy.h:48
QgsMapRendererJob::Error
Definition: qgsmaprendererjob.h:250
qgspallabeling.h
QgsMapCanvas::extent
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
Definition: qgsmapcanvas.cpp:1049
QgsMapCanvas::CanvasProperties::mouseLastXY
QPoint mouseLastXY
Last seen point of the mouse.
Definition: qgsmapcanvas.cpp:119
QgsMapCanvas::moveCanvasContents
void moveCanvasContents(bool reset=false)
called when panning is in action, reset indicates end of panning
Definition: qgsmapcanvas.cpp:2290
QgsMapThemeCollection::mapThemeRenamed
void mapThemeRenamed(const QString &name, const QString &newName)
Emitted when a map theme within the collection is renamed.
QgsMapSettings::mapToLayerCoordinates
QgsPointXY mapToLayerCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from output CRS to layer's CRS
Definition: qgsmapsettings.cpp:516
qgsruntimeprofiler.h
QgsMapCanvas::setTheme
void setTheme(const QString &theme)
Sets a map theme to show in the canvas.
Definition: qgsmapcanvas.cpp:2149
QgsProject::viewSettings
const QgsProjectViewSettings * viewSettings() const
Returns the project's view settings, which contains settings and properties relating to how a QgsProj...
Definition: qgsproject.cpp:2986
QgsMapCanvas::mapToolSet
void mapToolSet(QgsMapTool *newTool, QgsMapTool *oldTool)
Emit map tool changed with the old tool.
QgsMapRendererJob::mapSettings
const QgsMapSettings & mapSettings() const
Returns map settings with which this job was started.
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name)
Helper to get a theme icon.
Definition: qgsapplication.cpp:605
QgsMapCanvas::refresh
void refresh()
Repaints the canvas map.
Definition: qgsmapcanvas.cpp:524
QgsMapSettings::setFlag
void setFlag(Flag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
Definition: qgsmapsettings.cpp:341
QgsMapLayer::autoRefreshInterval
int autoRefreshInterval
Definition: qgsmaplayer.h:86
QgsExpressionContextScope::setVariable
void setVariable(const QString &name, const QVariant &value, bool isStatic=false)
Convenience method for setting a variable in the context scope by name name and value.
Definition: qgsexpressioncontext.cpp:78
QgsMapTool::canvasDoubleClickEvent
virtual void canvasDoubleClickEvent(QgsMapMouseEvent *e)
Mouse double-click event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:162
QgsMapCanvas::setWheelFactor
void setWheelFactor(double factor)
Sets wheel zoom factor (should be greater than 1)
Definition: qgsmapcanvas.cpp:1896
QgsMapCanvas::isDrawing
bool isDrawing()
Find out whether rendering is in progress.
Definition: qgsmapcanvas.cpp:327
QgsMapToPixel::mapUnitsPerPixel
double mapUnitsPerPixel() const
Returns current map units per pixel.
Definition: qgsmaptopixel.cpp:128
QgsMapSettings::readXml
void readXml(QDomNode &node)
Definition: qgsmapsettings.cpp:610
QgsRubberBand::ICON_CIRCLE
@ ICON_CIRCLE
A circle is used to highlight points (○)
Definition: qgsrubberband.h:100
QgsRectangle::combineExtentWith
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
Definition: qgsrectangle.h:359
QgsSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Definition: qgssettings.cpp:174
QgsMapRendererCustomPainterJob::waitForFinished
void waitForFinished() override
Block until the job has finished.
Definition: qgsmaprenderercustompainterjob.cpp:169
QgsExpressionContextUtils::globalScope
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Definition: qgsexpressioncontextutils.cpp:33
QgsMapTool::populateContextMenu
virtual void populateContextMenu(QMenu *menu)
Allows the tool to populate and customize the given menu, prior to showing it in response to a right-...
Definition: qgsmaptool.cpp:231
QgsReadWriteContext
Definition: qgsreadwritecontext.h:34
QgsMapCanvas::destinationCrsChanged
void destinationCrsChanged()
Emitted when map CRS has changed.
QgsDataProvider
Definition: qgsdataprovider.h:41
QgsMapSettings::outputSize
QSize outputSize() const
Returns the size of the resulting map image.
Definition: qgsmapsettings.cpp:234
QgsMapCanvas::zoomScale
void zoomScale(double scale, bool ignoreScaleLock=false)
Zooms the canvas to a specific scale.
Definition: qgsmapcanvas.cpp:1913
qgsmapcanvas.h
QgsMapCanvas::xyCoordinates
void xyCoordinates(const QgsPointXY &p)
Emits current mouse position.
QgsMapSettings::setRotation
void setRotation(double rotation)
Sets the rotation of the resulting map image, in degrees clockwise.
Definition: qgsmapsettings.cpp:106
QgsMapCanvas::mapTool
QgsMapTool * mapTool()
Returns the currently active tool.
Definition: qgsmapcanvas.cpp:2245
qgsmapthemecollection.h
QgsMapCanvas::zoomByFactor
void zoomByFactor(double scaleFactor, const QgsPointXY *center=nullptr, bool ignoreScaleLock=false)
Zoom with the factor supplied.
Definition: qgsmapcanvas.cpp:2495
QgsMapRendererJob::isActive
virtual bool isActive() const =0
Tell whether the rendering job is currently running in background.
QgsMapCanvas::zoomOut
void zoomOut()
Zoom out with fixed factor.
Definition: qgsmapcanvas.cpp:1907
QgsCoordinateReferenceSystem::userFriendlyIdentifier
QString userFriendlyIdentifier(IdentifierType type=MediumString) const
Returns a user friendly identifier for the CRS.
Definition: qgscoordinatereferencesystem.cpp:1316
QgsMapCanvas::zoomLastStatusChanged
void zoomLastStatusChanged(bool)
Emitted when zoom last status changed.
QgsMapCanvas::mouseLastXY
QPoint mouseLastXY()
returns last position of mouse cursor
Definition: qgsmapcanvas.cpp:2333
QgsReferencedRectangle
Definition: qgsreferencedgeometry.h:72
QgsRectangle::setXMinimum
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:130
QgsMapCanvas::mouseMoveEvent
void mouseMoveEvent(QMouseEvent *e) override
Definition: qgsmapcanvas.cpp:1943
QgsDebugMsgLevel
#define QgsDebugMsgLevel(str, level)
Definition: qgslogger.h:39
QgsGuiUtils::CANVAS_MAGNIFICATION_MIN
constexpr double CANVAS_MAGNIFICATION_MIN
Minimum magnification level allowed in map canvases.
Definition: qgsguiutils.h:61
qgsmaptopixel.h
QgsCoordinateReferenceSystem::WKT_PREFERRED
@ WKT_PREFERRED
Preferred format, matching the most recent WKT ISO standard. Currently an alias to WKT2_2019,...
Definition: qgscoordinatereferencesystem.h:678
QgsMapCanvas::mapSettings
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
Definition: qgsmapcanvas.cpp:390
QgsMapCanvas::redrawAllLayers
void redrawAllLayers()
Clears all cached images and redraws all layers.
Definition: qgsmapcanvas.cpp:2604
QgsRubberBand
Definition: qgsrubberband.h:49
QgsPointXY::sqrDist
double sqrDist(double x, double y) const
Returns the squared distance between this point a specified x, y coordinate.
Definition: qgspointxy.h:175
QgsMapSettings::devicePixelRatio
float devicePixelRatio() const
Returns device pixel ratio Common values are 1 for normal-dpi displays and 2 for high-dpi "retina" di...
Definition: qgsmapsettings.cpp:246
QgsExpressionContextScope::readXml
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads scope variables from an XML element.
Definition: qgsexpressioncontext.cpp:200
QgsMapRendererQImageJob::renderedImage
virtual QImage renderedImage()=0
Gets a preview/resulting image.
qgscoordinatetransformcontext.h
crs
const QgsCoordinateReferenceSystem & crs
Definition: qgswfsgetfeature.cpp:105
QgsMapCanvas::CanvasProperties::mouseButtonDown
bool mouseButtonDown
Flag to indicate status of mouse button.
Definition: qgsmapcanvas.cpp:116
QgsApplication::getThemeCursor
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
Definition: qgsapplication.cpp:635
QgsTemporalRangeObject::setIsTemporal
void setIsTemporal(bool enabled)
Sets whether the temporal range is enabled (i.e.
Definition: qgstemporalrangeobject.cpp:25
QgsMapCanvas::flashGeometries
void flashGeometries(const QList< QgsGeometry > &geometries, const QgsCoordinateReferenceSystem &crs=QgsCoordinateReferenceSystem(), const QColor &startColor=QColor(255, 0, 0, 255), const QColor &endColor=QColor(255, 0, 0, 0), int flashes=3, int duration=500)
Causes a set of geometries to flash within the canvas.
Definition: qgsmapcanvas.cpp:1441
QgsRectangle::xMaximum
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
Qgis::Warning
@ Warning
Definition: qgis.h:104
QgsRubberBand::strokeColor
QColor strokeColor
Definition: qgsrubberband.h:68
QgsMapCanvas::mouseReleaseEvent
void mouseReleaseEvent(QMouseEvent *e) override
Definition: qgsmapcanvas.cpp:1741
QgsMapThemeCollection::mapThemeChanged
void mapThemeChanged(const QString &theme)
Emitted when a map theme changes definition.
QgsMapCanvas::temporalRangeChanged
void temporalRangeChanged()
Emitted when the map canvas temporal range changes.
QgsProjectionSelectionDialog
Definition: qgsprojectionselectiondialog.h:51
qgsfeatureiterator.h
QgsMapRendererCache::clear
void clear()
Invalidates the cache contents, clearing all cached images.
Definition: qgsmaprenderercache.cpp:26
QgsMapSettings::hasValidSettings
bool hasValidSettings() const
Check whether the map settings are valid and can be used for rendering.
Definition: qgsmapsettings.cpp:365
QgsMapCanvas
Definition: qgsmapcanvas.h:83
QgsMapCanvas::panActionEnd
void panActionEnd(QPoint releasePoint)
Ends pan action and redraws the canvas.
Definition: qgsmapcanvas.cpp:2250
QgsMapCanvas::setMagnificationFactor
void setMagnificationFactor(double factor, const QgsPointXY *center=nullptr)
Sets the factor of magnification to apply to the map canvas.
Definition: qgsmapcanvas.cpp:273
QgsMapSettings::fullExtent
QgsRectangle fullExtent() const
returns current extent of layer set
Definition: qgsmapsettings.cpp:551
QgsMapTool::deactivate
virtual void deactivate()
called when map tool is being deactivated
Definition: qgsmaptool.cpp:99
QgsMapSettings::setSegmentationToleranceType
void setSegmentationToleranceType(QgsAbstractGeometry::SegmentationToleranceType type)
Sets segmentation tolerance type (maximum angle or maximum difference between curve and approximation...
Definition: qgsmapsettings.h:508
QgsMapSettings::writeXml
void writeXml(QDomNode &node, QDomDocument &doc)
Definition: qgsmapsettings.cpp:645
QgsMapCanvas::center
QgsPointXY center() const
Gets map center, in geographical coordinates.
Definition: qgsmapcanvas.cpp:1147
QgsLabelingResults
Definition: qgspallabeling.h:1224
QgsExpressionContextScope::writeXml
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Writes scope variables to an XML element.
Definition: qgsexpressioncontext.cpp:212
qgsmapcanvasannotationitem.h
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
QgsProject::transformContext
QgsCoordinateTransformContext transformContext
Definition: qgsproject.h:99
QgsTemporalRangeObject::temporalRange
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
Definition: qgstemporalrangeobject.cpp:43
QgsMapCanvas::fullExtent
QgsRectangle fullExtent() const
Returns the combined extent for all layers on the map canvas.
Definition: qgsmapcanvas.cpp:1054
QgsMapSettings::mapUnitsPerPixel
double mapUnitsPerPixel() const
Returns the distance in geographical coordinates that equals to one pixel in the map.
Definition: qgsmapsettings.cpp:390
QgsMapCanvas::~QgsMapCanvas
~QgsMapCanvas() override
Definition: qgsmapcanvas.cpp:235
QgsMapCanvas::setRotation
void setRotation(double degrees)
Set the rotation of the map canvas in clockwise degrees.
Definition: qgsmapcanvas.cpp:1163
qgis.h
QgsExpressionContextUtils::mapSettingsScope
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
Definition: qgsexpressioncontextutils.cpp:356
qgsmaprenderercustompainterjob.h
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:458
QgsMapSettings::layerExtentToOutputExtent
QgsRectangle layerExtentToOutputExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from layer's CRS to output CRS
Definition: qgsmapsettings.cpp:432
QgsRubberBand::setStrokeColor
void setStrokeColor(const QColor &color)
Sets the stroke color for the rubberband.
Definition: qgsrubberband.cpp:60
QgsMapCanvas::scale
double scale() const
Returns the last reported scale of the canvas.
Definition: qgsmapcanvas.cpp:322
QgsMapTool::Transient
@ Transient
Definition: qgsmaptool.h:91
QgsMapCanvas::rotationChanged
void rotationChanged(double)
Emitted when the rotation of the map changes.
QgsProject::readProject
void readProject(const QDomDocument &)
Emitted when a project is being read.
QgsMapCanvas::zoomWithCenter
void zoomWithCenter(int x, int y, bool zoomIn)
Zooms in/out with a given center.
Definition: qgsmapcanvas.cpp:1918
QgsMapSettings::magnificationFactor
double magnificationFactor() const
Returns the magnification factor.
Definition: qgsmapsettings.cpp:69
QgsRubberBand::setFillColor
void setFillColor(const QColor &color)
Sets the fill color for the rubberband.
Definition: qgsrubberband.cpp:52
QgsMapSettings::layerStyleOverrides
QMap< QString, QString > layerStyleOverrides() const
Gets map of map layer style overrides (key: layer ID, value: style name) where a different style shou...
Definition: qgsmapsettings.cpp:299
QgsSettings
Definition: qgssettings.h:61
QgsMapCanvas::writeProject
void writeProject(QDomDocument &)
called to write map canvas settings to project
Definition: qgsmapcanvas.cpp:2460
QgsMapCanvas::selectionChangedSlot
void selectionChangedSlot()
Receives signal about selection change, and pass it on with layer info.
Definition: qgsmapcanvas.cpp:2511
QgsMapCanvas::panAction
void panAction(QMouseEvent *event)
Called when mouse is moving and pan is activated.
Definition: qgsmapcanvas.cpp:2278
QgsMapLayer::reload
virtual void reload()
Synchronises with changes in the datasource.
Definition: qgsmaplayer.h:471
QgsExpressionContextScopeGenerator
Definition: qgsexpressioncontextscopegenerator.h:28
QgsMapCanvas::clearCache
void clearCache()
Make sure to remove any rendered images from cache (does nothing if cache is not enabled)
Definition: qgsmapcanvas.cpp:484
QgsMapSettings::RenderPartialOutput
@ RenderPartialOutput
Whether to make extra effort to update map image with partially rendered layers (better for interacti...
Definition: qgsmapsettings.h:311
QgsRubberBand::fillColor
QColor fillColor
Definition: qgsrubberband.h:67
QgsMapCanvas::CanvasProperties::panSelectorDown
bool panSelectorDown
Flag to indicate the pan selector key is held down by user.
Definition: qgsmapcanvas.cpp:125
QgsMapCanvas::mapUnits
QgsUnitTypes::DistanceUnit mapUnits() const
Convenience function for returning the current canvas map units.
Definition: qgsmapcanvas.cpp:2129
QgsAbstractGeometry::SegmentationToleranceType
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
Definition: qgsabstractgeometry.h:112
qgsmimedatautils.h
QgsMimeDataUtils::UriList
QList< QgsMimeDataUtils::Uri > UriList
Definition: qgsmimedatautils.h:156
QgsMapCanvas::dragEnterEvent
void dragEnterEvent(QDragEnterEvent *e) override
Definition: qgsmapcanvas.cpp:2522
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
qgsmaprenderercache.h
QgsUnitTypes::DistanceUnit
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:67
QgsMapCanvas::paintEvent
void paintEvent(QPaintEvent *e) override
Definition: qgsmapcanvas.cpp:1831
QgsProject::mapLayer
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
Definition: qgsproject.cpp:3124
QgsMapToPixel::toMapCoordinates
QgsPointXY toMapCoordinates(int x, int y) const
Transform device coordinates to map (world) coordinates.
Definition: qgsmaptopixel.cpp:108
QgsRubberBand::secondaryStrokeColor
QColor secondaryStrokeColor
Definition: qgsrubberband.h:70
QgsCoordinateTransform::transform
QgsPointXY transform(const QgsPointXY &point, TransformDirection direction=ForwardTransform) const SIP_THROW(QgsCsException)
Transform the point from the source CRS to the destination CRS.
Definition: qgscoordinatetransform.cpp:239
QgsMapCanvas::freeze
void freeze(bool frozen=true)
Freeze/thaw the map canvas.
Definition: qgsmapcanvas.cpp:2114
QgsMapTool::clean
virtual void clean()
convenient method to clean members
Definition: qgsmaptool.cpp:109
QgsMapTool::keyPressEvent
virtual void keyPressEvent(QKeyEvent *e)
Key event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:182
QgsMapCanvas::layers
QList< QgsMapLayer * > layers() const
Returns the list of layers shown within the map canvas.
Definition: qgsmapcanvas.cpp:2103
QgsMapCanvas::wheelEvent
void wheelEvent(QWheelEvent *e) override
Definition: qgsmapcanvas.cpp:1853
QgsMapCanvas::QgsMapCanvas
QgsMapCanvas(QWidget *parent=nullptr)
Constructor.
Definition: qgsmapcanvas.cpp:117
QgsMapSettings::setSegmentationTolerance
void setSegmentationTolerance(double tolerance)
Sets the segmentation tolerance applied when rendering curved geometries.
Definition: qgsmapsettings.h:501
QgsRectangle
Definition: qgsrectangle.h:41
QgsMapCanvas::setSegmentationToleranceType
void setSegmentationToleranceType(QgsAbstractGeometry::SegmentationToleranceType type)
Sets segmentation tolerance type (maximum angle or maximum difference between curve and approximation...
Definition: qgsmapcanvas.cpp:2626
QgsMapRendererCache
Definition: qgsmaprenderercache.h:42
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:143
QgsMapRendererCustomPainterJob::start
void start() override
Start the rendering job and immediately return.
Definition: qgsmaprenderercustompainterjob.cpp:75
QgsMapCanvas::setMapSettingsFlags
void setMapSettingsFlags(QgsMapSettings::Flags flags)
Resets the flags for the canvas' map settings.
Definition: qgsmapcanvas.cpp:445
QgsCoordinateTransform::transformBoundingBox
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, TransformDirection direction=ForwardTransform, bool handle180Crossover=false) const SIP_THROW(QgsCsException)
Transforms a rectangle from the source CRS to the destination CRS.
Definition: qgscoordinatetransform.cpp:511
QgsVectorLayer::isEditable
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
Definition: qgsvectorlayer.cpp:3586
QgsProject
Definition: qgsproject.h:92
QgsPreviewEffect::PreviewGrayscale
@ PreviewGrayscale
Definition: qgsprevieweffect.h:64
QgsGuiUtils::CANVAS_MAGNIFICATION_MAX
constexpr double CANVAS_MAGNIFICATION_MAX
Maximum magnification level allowed in map canvases.
Definition: qgsguiutils.h:69
QgsMapCanvas::snappingUtils
QgsSnappingUtils * snappingUtils() const
Returns snapping utility class that is associated with map canvas.
Definition: qgsmapcanvas.cpp:2378
QgsMapCanvas::setPreviewJobsEnabled
void setPreviewJobsEnabled(bool enabled)
Sets whether canvas map preview jobs (low priority render jobs which render portions of the view just...
Definition: qgsmapcanvas.cpp:774
QgsMapCanvas::allowInteraction
bool allowInteraction(QgsMapCanvasInteractionBlocker::Interaction interaction) const
Returns true if the specified interaction is currently permitted on the canvas.
Definition: qgsmapcanvas.cpp:945
qgsrubberband.h
QgsMapCanvas::scaleChanged
void scaleChanged(double)
Emitted when the scale of the map changes.
QgsMapSettings::extent
QgsRectangle extent() const
Returns geographical coordinates of the rectangle that should be rendered.
Definition: qgsmapsettings.cpp:74
QgsProject::writeProject
void writeProject(QDomDocument &)
Emitted when the project is being written.
QgsMapSettings::DrawLabeling
@ DrawLabeling
Enable drawing of labels on top of the map.
Definition: qgsmapsettings.h:306
QgsMapCanvas::isParallelRenderingEnabled
bool isParallelRenderingEnabled() const
Check whether the layers are rendered in parallel or sequentially.
Definition: qgsmapcanvas.cpp:495
QgsMapRendererJob::renderingTime
int renderingTime() const
Returns the total time it took to finish the job (in milliseconds).
Definition: qgsmaprendererjob.h:277
QgsMapCanvas::labelingResults
const QgsLabelingResults * labelingResults() const
Gets access to the labeling results (may be nullptr)
Definition: qgsmapcanvas.cpp:452
qgsapplication.h
qgsprojectionselectiondialog.h
QgsMapTool
Definition: qgsmaptool.h:63
QgsFeatureRequest::setFilterRect
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
Definition: qgsfeaturerequest.cpp:97
QgsMapCanvasSnappingUtils
Definition: qgsmapcanvassnappingutils.h:33
QgsMapCanvas::setCurrentLayer
void setCurrentLayer(QgsMapLayer *layer)
Definition: qgsmapcanvas.cpp:313
qgsmaptoolzoom.h
QgsMapRendererJob::errors
Errors errors() const
List of errors that happened during the rendering job - available when the rendering has been finishe...
QgsMapRendererParallelJob
Definition: qgsmaprendererparalleljob.h:32
QgsMapCanvasItem::updatePosition
virtual void updatePosition()
called on changed extent or resize event to update position of the item
Definition: qgsmapcanvasitem.cpp:135
QgsMapCanvas::rotation
double rotation() const
Gets the current map canvas rotation in clockwise degrees.
Definition: qgsmapcanvas.cpp:1158
QgsRectangle::scale
void scale(double scaleFactor, const QgsPointXY *c=nullptr)
Scale the rectangle around its center point.
Definition: qgsrectangle.h:235
qgstemporalcontroller.h
QgsDistanceArea::setEllipsoid
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Definition: qgsdistancearea.cpp:66
QgsMapCanvas::zoomIn
void zoomIn()
Zoom in with fixed factor.
Definition: qgsmapcanvas.cpp:1901
QgsMapCanvas::readProject
void readProject(const QDomDocument &)
called to read map canvas settings from project
Definition: qgsmapcanvas.cpp:2394
QgsFeatureRequest
Definition: qgsfeaturerequest.h:75
qgsmaplayertemporalproperties.h
qgsvectorlayertemporalproperties.h
QgsExpressionContextUtils::projectScope
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
Definition: qgsexpressioncontextutils.cpp:221
qgsmaptoolpan.h
QgsPreviewEffect::PreviewMode
PreviewMode
Definition: qgsprevieweffect.h:49
QgsMapCanvas::enableAntiAliasing
void enableAntiAliasing(bool flag)
used to determine if anti-aliasing is enabled or not
Definition: qgsmapcanvas.cpp:294
QgsCsException
Definition: qgsexception.h:65
QgsMapSettings::setBackgroundColor
void setBackgroundColor(const QColor &color)
Sets the background color of the map.
Definition: qgsmapsettings.h:290
QgsMapCanvas::setTemporalController
void setTemporalController(QgsTemporalController *controller)
Sets the temporal controller, tQgsMapCanvasInteractionBlockerhis controller will be used to update th...
Definition: qgsmapcanvas.cpp:431
QgsMapCanvasItem
Definition: qgsmapcanvasitem.h:33
QgsProjectViewSettings::defaultViewExtent
QgsReferencedRectangle defaultViewExtent() const
Returns the default view extent, which should be used as the initial map extent when this project is ...
Definition: qgsprojectviewsettings.cpp:37
QgsMapCanvas::setPreviewMode
void setPreviewMode(QgsPreviewEffect::PreviewMode mode)
Sets a preview mode for the map canvas.
Definition: qgsmapcanvas.cpp:2358
QgsMapRendererJob::perLayerRenderingTime
QHash< QgsMapLayer *, int > perLayerRenderingTime() const
Returns the render time (in ms) per layer.
QgsMapLayer::dataProvider
virtual QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
Definition: qgsmaplayer.cpp:169
QgsMapCanvas::layerCount
int layerCount() const
Returns number of layers on the map.
Definition: qgsmapcanvas.cpp:2097
QgsMapSettings::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
Definition: qgsmapsettings.cpp:400
QgsMapSettings::rotation
double rotation() const
Returns the rotation of the resulting map image, in degrees clockwise.
Definition: qgsmapsettings.cpp:101
QgsMapRendererJob::waitForFinished
virtual void waitForFinished()=0
Block until the job has finished.
qgsmapsettingsutils.h
QgsMapCanvas::layerStyleOverrides
QMap< QString, QString > layerStyleOverrides() const
Returns the stored overrides of styles for layers.
Definition: qgsmapcanvas.cpp:2134
QgsTemporalProperty::isActive
bool isActive() const
Returns true if the temporal property is active.
Definition: qgstemporalproperty.cpp:36
QgsUnitTypes::DistanceDegrees
@ DistanceDegrees
Degrees, for planar geographic CRS distance measurements.
Definition: qgsunittypes.h:75
QgsDistanceArea::bearing
double bearing(const QgsPointXY &p1, const QgsPointXY &p2) const
Computes the bearing (in radians) between two points.
Definition: qgsdistancearea.cpp:842
QgsCoordinateTransform::setBallparkTransformsAreAppropriate
void setBallparkTransformsAreAppropriate(bool appropriate)
Sets whether approximate "ballpark" results are appropriate for this coordinate transform.
Definition: qgscoordinatetransform.cpp:919
whileBlocking
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:262
QgsMapCanvas::canvasColor
QColor canvasColor() const
Read property of QColor bgColor.
Definition: qgsmapcanvas.cpp:2058
QgsLabelingEngineSettings
Definition: qgslabelingenginesettings.h:30
QgsVectorLayer::selectionChanged
void selectionChanged(const QgsFeatureIds &selected, const QgsFeatureIds &deselected, bool clearAndSelect)
Emitted when selection was changed.
QgsMapCanvas::zoomToSelected
void zoomToSelected(QgsVectorLayer *layer=nullptr)
Zoom to the extent of the selected features of provided (vector) layer.
Definition: qgsmapcanvas.cpp:1238
QgsMapCanvasInteractionBlocker::Interaction
Interaction
Available interactions to block.
Definition: qgsmapcanvasinteractionblocker.h:36
qgsDoubleNear
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition: qgis.h:315
QgsMapCanvas::layersChanged
void layersChanged()
Emitted when a new set of layers has been received.
QgsMapLayer::repaintRequested
void repaintRequested(bool deferredUpdate=false)
By emitting this signal the layer tells that either appearance or content have been changed and any v...
QgsMapCanvas::layer
QgsMapLayer * layer(int index)
Returns the map layer at position index in the layer stack.
Definition: qgsmapcanvas.cpp:304
QgsMapRendererJob::setCache
void setCache(QgsMapRendererCache *cache)
Assign a cache to be used for reading and storing rendered images of individual layers.
QgsMapTool::gestureEvent
virtual bool gestureEvent(QGestureEvent *e)
gesture event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:192
QgsMapSettings::mapUnits
QgsUnitTypes::DistanceUnit mapUnits() const
Gets units of map's geographical coordinates - used for scale calculation.
Definition: qgsmapsettings.cpp:359
QgsMapSettings::setMagnificationFactor
void setMagnificationFactor(double factor, const QgsPointXY *center=nullptr)
Set the magnification factor.
Definition: qgsmapsettings.cpp:48
QgsMapCanvas::keyReleaseEvent
void keyReleaseEvent(QKeyEvent *e) override
Definition: qgsmapcanvas.cpp:1612
QgsException::what
QString what() const
Definition: qgsexception.h:48
qgsmaplayer.h
qgsmessageviewer.h
QgsDistanceArea::measureLine
double measureLine(const QVector< QgsPointXY > &points) const
Measures the length of a line with multiple segments.
Definition: qgsdistancearea.cpp:273
QgsProject::projectColorsChanged
void projectColorsChanged()
Emitted whenever the project's color scheme has been changed.
QgsMapCanvas::extentsChanged
void extentsChanged()
Emitted when the extents of the map change.
QgsMapCanvas::setSegmentationTolerance
void setSegmentationTolerance(double tolerance)
Sets the segmentation tolerance applied when rendering curved geometries.
Definition: qgsmapcanvas.cpp:2621
QgsMapThemeCollection::mapThemesChanged
void mapThemesChanged()
Emitted when map themes within the collection are changed.
QgsMapCanvas::updateCanvasItemPositions
void updateCanvasItemPositions()
called on resize or changed extent to notify canvas items to change their rectangle
Definition: qgsmapcanvas.cpp:1838
QgsMapSettings::Antialiasing
@ Antialiasing
Enable anti-aliasing for map rendering.
Definition: qgsmapsettings.h:302
QgsTemporalController
Definition: qgstemporalcontroller.h:35
QgsDistanceArea::lengthUnits
QgsUnitTypes::DistanceUnit lengthUnits() const
Returns the units of distance for length calculations made by this object.
Definition: qgsdistancearea.cpp:789
QgsApplication::imageCache
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
Definition: qgsapplication.cpp:2134
QgsMapLayer::temporalProperties
virtual QgsMapLayerTemporalProperties * temporalProperties()
Returns the layer's temporal properties.
Definition: qgsmaplayer.h:1194
QgsMapRendererSequentialJob
Definition: qgsmaprenderersequentialjob.h:33
QgsDataProvider::PreviewContext
Stores settings related to the context in which a preview job runs.
Definition: qgsdataprovider.h:508
QgsMapCanvas::setTemporalRange
void setTemporalRange(const QgsDateTimeRange &range)
Set datetime range for the map canvas.
Definition: qgsmapcanvas.cpp:912
QgsMapCanvas::mCanvasProperties
std::unique_ptr< CanvasProperties > mCanvasProperties
Handle pattern for implementation object.
Definition: qgsmapcanvas.h:1047
QgsMapSettings::setSelectionColor
void setSelectionColor(const QColor &color)
Sets color that is used for drawing of selected vector features.
Definition: qgsmapsettings.h:295
QgsWkbTypes::geometryType
static GeometryType geometryType(Type type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:937
QgsMapCanvas::updateScale
void updateScale()
Emits signal scaleChanged to update scale in main window.
Definition: qgsmapcanvas.cpp:1176
QgsMapCanvas::theme
QString theme
Definition: qgsmapcanvas.h:96
QgsRectangle::setXMaximum
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:135
QgsLogger::warning
static void warning(const QString &msg)
Goes to qWarning.
Definition: qgslogger.cpp:122
QgsMapCanvas::setDestinationCrs
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
sets destination coordinate reference system
Definition: qgsmapcanvas.cpp:395
QgsMapCanvas::setCanvasColor
void setCanvasColor(const QColor &_newVal)
Write property of QColor bgColor.
Definition: qgsmapcanvas.cpp:2033
QgsMapCanvas::setCenter
void setCenter(const QgsPointXY &center)
Set the center of the map canvas, in geographical coordinates.
Definition: qgsmapcanvas.cpp:1129
QgsMapSettings::setFlags
void setFlags(QgsMapSettings::Flags flags)
Sets combination of flags that will be used for rendering.
Definition: qgsmapsettings.cpp:336
QgsMapCanvas::resizeEvent
void resizeEvent(QResizeEvent *e) override
Definition: qgsmapcanvas.cpp:1802
QgsMapLayer::id
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
Definition: qgsmaplayer.cpp:148
QgsMapCanvas::labelingEngineSettings
const QgsLabelingEngineSettings & labelingEngineSettings() const
Returns global labeling engine settings from the internal map settings.
Definition: qgsmapcanvas.cpp:2662
QgsMapCanvas::enableMapTileRendering
void enableMapTileRendering(bool flag)
sets map tile rendering flag
Definition: qgsmapcanvas.cpp:299
QgsMapCanvas::zoomToFullExtent
void zoomToFullExtent()
Zoom to the full extent of all layers.
Definition: qgsmapcanvas.cpp:1182
QgsMapCanvas::selectionColor
QColor selectionColor() const
Returns color for selected features.
Definition: qgsmapcanvas.cpp:2092
QgsMapToolPan
Definition: qgsmaptoolpan.h:32
QgsGeometry::isNull
bool isNull
Definition: qgsgeometry.h:125
QgsMapSettings::scale
double scale() const
Returns the calculated map scale.
Definition: qgsmapsettings.cpp:395
QgsMapCanvas::layerStyleOverridesChanged
void layerStyleOverridesChanged()
Emitted when the configuration of overridden layer styles changes.
QgsSettings::setValue
void setValue(const QString &key, const QVariant &value, QgsSettings::Section section=QgsSettings::NoSection)
Sets the value of setting key to value.
Definition: qgssettings.cpp:289
QgsProject::mapThemeCollection
QgsMapThemeCollection mapThemeCollection
Definition: qgsproject.h:101
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:128
QgsDataProvider::PreviewContext::maxRenderingTimeMs
double maxRenderingTimeMs
Default maximum allowable render time, in ms.
Definition: qgsdataprovider.h:514
QgsMapCanvas::zoomToNextExtent
void zoomToNextExtent()
Zoom to the next extent (view)
Definition: qgsmapcanvas.cpp:1213
QgsMapCanvas::setReferencedExtent
bool setReferencedExtent(const QgsReferencedRectangle &extent) SIP_THROW(QgsCsException)
Sets the canvas to the specified extent.
Definition: qgsmapcanvas.cpp:1111
QgsMapRendererJob::start
virtual void start()=0
Start the rendering job and immediately return.
QgsMapCanvas::refreshAllLayers
void refreshAllLayers()
Reload all layers (including refreshing layer properties from their data sources),...
Definition: qgsmapcanvas.cpp:2592
QgsDistanceArea::setSourceCrs
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
Definition: qgsdistancearea.cpp:60
QgsMapCanvas::setExtent
void setExtent(const QgsRectangle &r, bool magnified=false)
Sets the extent of the map canvas to the specified rectangle.
Definition: qgsmapcanvas.cpp:1060
QgsMapSettings::RenderMapTile
@ RenderMapTile
Draw map such that there are no problems between adjacent tiles.
Definition: qgsmapsettings.h:310
QgsProject::transformContextChanged
void transformContextChanged()
Emitted when the project transformContext() is changed.
QgsMapCanvas::setMapTool
void setMapTool(QgsMapTool *mapTool, bool clean=false)
Sets the map tool currently being used on the canvas.
Definition: qgsmapcanvas.cpp:1975
QgsMapCanvas::previewMode
QgsPreviewEffect::PreviewMode previewMode() const
Returns the current preview mode for the map canvas.
Definition: qgsmapcanvas.cpp:2368
QgsMapCanvas::getCoordinateTransform
const QgsMapToPixel * getCoordinateTransform()
Gets the current coordinate transform.
Definition: qgsmapcanvas.cpp:334
QgsMimeDataUtils::Uri
Definition: qgsmimedatautils.h:40
QgsFeatureRequest::setNoAttributes
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
Definition: qgsfeaturerequest.cpp:197
QgsMapCanvas::setParallelRenderingEnabled
void setParallelRenderingEnabled(bool enabled)
Set whether the layers are rendered in parallel or sequentially.
Definition: qgsmapcanvas.cpp:490
QgsMapCanvas::panToFeatureIds
void panToFeatureIds(QgsVectorLayer *layer, const QgsFeatureIds &ids, bool alwaysRecenter=true)
Centers canvas extent to feature ids.
Definition: qgsmapcanvas.cpp:1337
QgsAbstractGeometry::isEmpty
virtual bool isEmpty() const
Returns true if the geometry is empty.
Definition: qgsabstractgeometry.cpp:298
QgsFeatureIds
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:34
QgsMapTool::activate
virtual void activate()
called when set as currently active map tool
Definition: qgsmaptool.cpp:83
QgsMapCanvas::keyPressEvent
void keyPressEvent(QKeyEvent *e) override
Definition: qgsmapcanvas.cpp:1518
QgsMapCanvas::zoomToFeatureExtent
void zoomToFeatureExtent(QgsRectangle &rect)
Zooms to feature extent.
Definition: qgsmapcanvas.cpp:1293
QgsMapCanvas::saveAsImage
void saveAsImage(const QString &fileName, QPixmap *QPixmap=nullptr, const QString &="PNG")
Save the contents of the map canvas to disk as an image.
Definition: qgsmapcanvas.cpp:979
QgsCoordinateReferenceSystem
Definition: qgscoordinatereferencesystem.h:206
QgsDataProvider::renderInPreview
virtual bool renderInPreview(const QgsDataProvider::PreviewContext &context)
Returns whether the layer must be rendered in preview jobs.
Definition: qgsdataprovider.cpp:69
QgsSnappingUtils
Definition: qgssnappingutils.h:49
QgsMapSettings::selectionColor
QColor selectionColor() const
Gets color that is used for drawing of selected vector features.
Definition: qgsmapsettings.h:297
QgsMapSettingsUtils::worldFileContent
static QString worldFileContent(const QgsMapSettings &mapSettings)
Creates the content of a world file.
Definition: qgsmapsettingsutils.cpp:128
QgsMapCanvas::setRenderFlag
void setRenderFlag(bool flag)
Sets whether a user has disabled canvas renders via the GUI.
Definition: qgsmapcanvas.cpp:2170
QgsMapCanvas::mapUpdateInterval
int mapUpdateInterval() const
Find out how often map preview should be updated while it is being rendered (in milliseconds)
Definition: qgsmapcanvas.cpp:505
QgsRectangle::yMaximum
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
QgsMapSettings::RenderPreviewJob
@ RenderPreviewJob
Render is a 'canvas preview' render, and shortcuts should be taken to ensure fast rendering.
Definition: qgsmapsettings.h:312
QgsExpressionContextScope
Single scope for storing variables and functions for use within a QgsExpressionContext....
Definition: qgsexpressioncontext.h:111
QgsApplication::svgCache
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
Definition: qgsapplication.cpp:2129
QgsMapSettings::setLabelingEngineSettings
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets the global configuration of the labeling engine.
Definition: qgsmapsettings.h:522
QgsMapSettings::setLayers
void setLayers(const QList< QgsMapLayer * > &layers)
Set list of layers for map rendering.
Definition: qgsmapsettings.cpp:286
QgsMapCanvas::setScaleLocked
void setScaleLocked(bool isLocked)
Lock the scale, so zooming can be performed using magnication.
Definition: qgsmapcanvas.cpp:1938
QgsMapCanvas::flashFeatureIds
void flashFeatureIds(QgsVectorLayer *layer, const QgsFeatureIds &ids, const QColor &startColor=QColor(255, 0, 0, 255), const QColor &endColor=QColor(255, 0, 0, 0), int flashes=3, int duration=500)
Causes a set of features with matching ids from a vector layer to flash within the canvas.
Definition: qgsmapcanvas.cpp:1418
qgsvectorlayer.h
QgsPointXY
Definition: qgspointxy.h:43
QgsMapSettings::destinationCrs
QgsCoordinateReferenceSystem destinationCrs() const
returns CRS of destination coordinate reference system
Definition: qgsmapsettings.cpp:317
qgsmaprenderersequentialjob.h
QgsMapRendererCustomPainterJob
Definition: qgsmaprenderercustompainterjob.h:63
qgsmapcanvassnappingutils.h
QgsCoordinateReferenceSystem::ShortString
@ ShortString
A heavily abbreviated string, for use when a compact representation is required.
Definition: qgscoordinatereferencesystem.h:630
QgsGeometry::asPoint
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
Definition: qgsgeometry.cpp:1559
QgsMapCanvas::removeInteractionBlocker
void removeInteractionBlocker(QgsMapCanvasInteractionBlocker *blocker)
Removes an interaction blocker from the canvas.
Definition: qgsmapcanvas.cpp:940
QgsMapTool::canvasPressEvent
virtual void canvasPressEvent(QgsMapMouseEvent *e)
Mouse press event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:167
QgsMapCanvas::setMapUpdateInterval
void setMapUpdateInterval(int timeMilliseconds)
Set how often map preview should be updated while it is being rendered (in milliseconds)
Definition: qgsmapcanvas.cpp:500
QgsMapSettings::setExpressionContext
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
Definition: qgsmapsettings.h:385
qgsreferencedgeometry.h
QgsMapCanvas::keyReleased
void keyReleased(QKeyEvent *e)
Emit key release event.
qgsprojectviewsettings.h
QgsMapCanvas::temporalRange
const QgsDateTimeRange & temporalRange() const
Returns map canvas datetime range.
Definition: qgsmapcanvas.cpp:930
QgsMapMouseEvent
Definition: qgsmapmouseevent.h:35
QgsMapCanvas::clearExtentHistory
void clearExtentHistory()
Definition: qgsmapcanvas.cpp:1228
QgsMapTool::canvasMoveEvent
virtual void canvasMoveEvent(QgsMapMouseEvent *e)
Mouse move event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:157
QgsWkbTypes::LineGeometry
@ LineGeometry
Definition: qgswkbtypes.h:142
QgsMapSettings::UseRenderingOptimization
@ UseRenderingOptimization
Enable vector simplification and other rendering optimizations.
Definition: qgsmapsettings.h:307
QgsMapRendererQImageJob
Definition: qgsmaprendererjob.h:435
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:141
QgsTemporalController::updateTemporalRange
void updateTemporalRange(const QgsDateTimeRange &range)
Signals that a temporal range has changed and needs to be updated in all connected objects.
QgsMapCanvas::event
bool event(QEvent *e) override
Definition: qgsmapcanvas.cpp:2566
QgsCoordinateReferenceSystem::mapUnits
QgsUnitTypes::DistanceUnit mapUnits
Definition: qgscoordinatereferencesystem.h:210
QgsRubberBand::setWidth
void setWidth(int width)
Sets the width of the line.
Definition: qgsrubberband.cpp:70
QgsMapCanvas::setAnnotationsVisible
void setAnnotationsVisible(bool visible)
Sets whether annotations are visible in the canvas.
Definition: qgsmapcanvas.cpp:2647
QgsRectangle::center
QgsPointXY center() const
Returns the center point of the rectangle.
Definition: qgsrectangle.h:230
QgsMapCanvas::canvasColorChanged
void canvasColorChanged()
Emitted when canvas background color changes.
QgsMimeDataUtils::decodeUriList
static UriList decodeUriList(const QMimeData *data)
Definition: qgsmimedatautils.cpp:210
QgsWkbTypes::GeometryType
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:139
QgsMapSettings::testFlag
bool testFlag(Flag flag) const
Check whether a particular flag is enabled.
Definition: qgsmapsettings.cpp:354
QgsMapCanvas::tapAndHoldGestureOccurred
void tapAndHoldGestureOccurred(const QgsPointXY &mapPoint, QTapAndHoldGesture *gesture)
Emitted whenever a tap and hold gesture occurs at the specified map point.
QgsMapCanvas::setCustomDropHandlers
void setCustomDropHandlers(const QVector< QPointer< QgsCustomDropHandler >> &handlers)
Sets a list of custom drop handlers to use when drop events occur on the canvas.
Definition: qgsmapcanvas.cpp:779
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:373
QgsMapCanvas::themeChanged
void themeChanged(const QString &theme)
Emitted when the canvas has been assigned a different map theme.
c
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
Definition: porting_processing.dox:1
QgsGeometry
Definition: qgsgeometry.h:122
QgsMapCanvas::previewJobsEnabled
bool previewJobsEnabled
Definition: qgsmapcanvas.h:97
QgsMapToPixel
Definition: qgsmaptopixel.h:37
QgsMapSettings::setLayerStyleOverrides
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...
Definition: qgsmapsettings.cpp:304
QgsVectorLayer
Definition: qgsvectorlayer.h:385
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:197
qgsimagecache.h
QgsMapCanvas::isCachingEnabled
bool isCachingEnabled() const
Check whether images of rendered layers are curerently being cached.
Definition: qgsmapcanvas.cpp:479
QgsMapCanvas::selectionChanged
void selectionChanged(QgsVectorLayer *layer)
Emitted when selection in any layer gets changed.
QgsMapSettings::DrawEditingInfo
@ DrawEditingInfo
Enable drawing of vertex markers for layers in editing mode.
Definition: qgsmapsettings.h:303
QgsFeatureRequest::setLimit
QgsFeatureRequest & setLimit(long limit)
Set the maximum number of features to request.
Definition: qgsfeaturerequest.cpp:178
QgsMapTool::canvasReleaseEvent
virtual void canvasReleaseEvent(QgsMapMouseEvent *e)
Mouse release event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:172
QgsMapLayer
Definition: qgsmaplayer.h:81
QgsMapCanvas::isFrozen
bool isFrozen() const
Returns true if canvas is frozen.
Definition: qgsmapcanvas.cpp:2119
QgsVector
Definition: qgsvector.h:29
QgsRubberBand::addGeometry
void addGeometry(const QgsGeometry &geometry, QgsVectorLayer *layer)
Adds the geometry of an existing feature to a rubberband This is useful for multi feature highlightin...
Definition: qgsrubberband.cpp:279
QgsMapCanvas::magnificationChanged
void magnificationChanged(double)
Emitted when the scale of the map changes.
QgsPointXY::x
double x
Definition: qgspointxy.h:47
QgsCustomDropHandler
Definition: qgscustomdrophandler.h:47
qgsmapoverviewcanvas.h
QgsScopedRuntimeProfile
Definition: qgsruntimeprofiler.h:115
qgssettings.h
QgsRectangle::height
double height() const
Returns the height of the rectangle.
Definition: qgsrectangle.h:209
QgsMessageLog::logMessage
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Definition: qgsmessagelog.cpp:27
QgsProject::ellipsoidChanged
void ellipsoidChanged(const QString &ellipsoid)
Emitted when the project ellipsoid is changed.
QgsMapRendererJob::cancelWithoutBlocking
virtual void cancelWithoutBlocking()=0
Triggers cancellation of the rendering job without blocking.
QgsMapCanvas::previewModeEnabled
bool previewModeEnabled() const
Returns whether a preview mode is enabled for the map canvas.
Definition: qgsmapcanvas.cpp:2348
QgsMapCanvas::setPreviewModeEnabled
void setPreviewModeEnabled(bool previewEnabled)
Enables a preview mode for the map canvas.
Definition: qgsmapcanvas.cpp:2338
QgsMapCanvas::panDistanceBearingChanged
void panDistanceBearingChanged(double distance, QgsUnitTypes::DistanceUnit unit, double bearing)
Emitted whenever the distance or bearing of an in-progress panning operation is changed.
QgsMapCanvas::defaultExpressionContextScope
QgsExpressionContextScope * defaultExpressionContextScope()
Creates a new scope which contains default variables and functions relating to the map canvas.
Definition: qgsmapcanvas.cpp:516
QgsRectangle::yMinimum
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
QgsRubberBand::setIcon
void setIcon(IconType icon)
Sets the icon type to highlight point geometries.
Definition: qgsrubberband.cpp:75
QgsMapCanvas::keyPressed
void keyPressed(QKeyEvent *e)
Emit key press event.
QgsMapCanvas::unsetMapTool
void unsetMapTool(QgsMapTool *mapTool)
Unset the current map tool or last non zoom tool.
Definition: qgsmapcanvas.cpp:2015
qgsdatumtransformdialog.h
QgsMapCanvas::mousePressEvent
void mousePressEvent(QMouseEvent *e) override
Definition: qgsmapcanvas.cpp:1699
QgsExpressionContextUtils::atlasScope
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
Definition: qgsexpressioncontextutils.cpp:570
QgsMapCanvas::renderComplete
void renderComplete(QPainter *)
Emitted when the canvas has rendered.
QgsMapCanvas::CanvasProperties
Definition: qgsmapcanvas.cpp:93
qgscustomdrophandler.h
QgsMapSettings::layers
QList< QgsMapLayer * > layers() const
Gets list of layers for map rendering The layers are stored in the reverse order of how they are rend...
Definition: qgsmapsettings.cpp:281
QgsTemporalRangeObject::setTemporalRange
void setTemporalRange(const QgsDateTimeRange &range)
Sets the temporal range for the object.
Definition: qgstemporalrangeobject.cpp:35
QgsGeometry::boundingBox
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Definition: qgsgeometry.cpp:962
QgsDistanceArea
Definition: qgsdistancearea.h:49
QgsMapTool::wheelEvent
virtual void wheelEvent(QWheelEvent *e)
Mouse wheel event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:177
QgsPreviewEffect::setMode
void setMode(PreviewMode mode)
Sets the mode for the preview effect, which controls how the effect modifies a widgets appearance.
Definition: qgsprevieweffect.cpp:30
qgsrasterlayertemporalproperties.h
qgsexception.h
QgsMapCanvas::messageEmitted
void messageEmitted(const QString &title, const QString &message, Qgis::MessageLevel=Qgis::Info)
emit a message (usually to be displayed in a message bar)
QgsFeature
Definition: qgsfeature.h:55
QgsMapCanvas::magnificationFactor
double magnificationFactor() const
Returns the magnification factor.
Definition: qgsmapcanvas.cpp:289
QgsPreviewEffect
Definition: qgsprevieweffect.h:31
QgsMapRendererJob::takeLabelingResults
virtual QgsLabelingResults * takeLabelingResults()=0
Gets pointer to internal labeling engine (in order to get access to the results).
QgsMapCanvas::currentLayer
QgsMapLayer * currentLayer()
returns current layer (set by legend widget)
Definition: qgsmapcanvas.cpp:511
QgsMapCanvas::setSnappingUtils
void setSnappingUtils(QgsSnappingUtils *utils)
Assign an instance of snapping utils to the map canvas.
Definition: qgsmapcanvas.cpp:2389
QgsMapThemeCollection::hasMapTheme
bool hasMapTheme(const QString &name) const
Returns whether a map theme with a matching name exists.
Definition: qgsmapthemecollection.cpp:258
QgsDataProvider::PreviewContext::lastRenderingTimeMs
double lastRenderingTimeMs
Previous rendering time for the layer, in ms.
Definition: qgsdataprovider.h:511
QgsMapCanvas::zoomToFeatureIds
void zoomToFeatureIds(QgsVectorLayer *layer, const QgsFeatureIds &ids)
Set canvas extent to the bounding box of a set of features.
Definition: qgsmapcanvas.cpp:1317
QgsImageCache::remoteImageFetched
void remoteImageFetched(const QString &url)
Emitted when the cache has finished retrieving an image file from a remote url.
QgsMapTool::AllowZoomRect
@ AllowZoomRect
Allow zooming by rectangle (by holding shift and dragging) while the tool is active.
Definition: qgsmaptool.h:95
QgsMapCanvas::zoomNextStatusChanged
void zoomNextStatusChanged(bool)
Emitted when zoom next status changed.
QgsVectorLayer::selectedFeatureCount
int selectedFeatureCount() const
Returns the number of features that are selected in this layer.
Definition: qgsvectorlayer.cpp:3428
qgsmaprendererparalleljob.h
QgsRectangle::setMinimal
void setMinimal()
Set a rectangle so that min corner is at max and max corner is at min.
Definition: qgsrectangle.h:151
QgsSettings::enumValue
T enumValue(const QString &key, const T &defaultValue, const Section section=NoSection)
Returns the setting value for a setting based on an enum.
Definition: qgssettings.h:252
QgsMapLayer::isSpatial
virtual bool isSpatial() const
Returns true if the layer is considered a spatial layer, ie it has some form of geometry associated w...
Definition: qgsmaplayer.cpp:1740
QgsMapCanvas::setLayers
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers that should be shown in the canvas.
Definition: qgsmapcanvas.cpp:339
QgsMapSettings::setOutputSize
void setOutputSize(QSize size)
Sets the size of the resulting map image.
Definition: qgsmapsettings.cpp:239
QgsMapCanvas::installInteractionBlocker
void installInteractionBlocker(QgsMapCanvasInteractionBlocker *blocker)
Installs an interaction blocker onto the canvas, which may prevent certain map canvas interactions fr...
Definition: qgsmapcanvas.cpp:935
qgslogger.h
QgsMapCanvas::panActionStart
void panActionStart(QPoint releasePoint)
Starts a pan action.
Definition: qgsmapcanvas.cpp:2269
qgsmapcanvasmap.h
QgsMapCanvas::mapUnitsPerPixel
double mapUnitsPerPixel() const
Returns the mapUnitsPerPixel (map units per pixel) for the canvas.
Definition: qgsmapcanvas.cpp:2124
QgsMapSettings::setPathResolver
void setPathResolver(const QgsPathResolver &resolver)
Sets the path resolver for conversion between relative and absolute paths during rendering operations...
Definition: qgsmapsettings.h:431
QgsMapSettings
Definition: qgsmapsettings.h:86
QgsMapSettings::visibleExtent
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes takes output image size into accou...
Definition: qgsmapsettings.cpp:370
QgsMapRendererCache::invalidateCacheForLayer
void invalidateCacheForLayer(QgsMapLayer *layer)
Invalidates cached images which relate to the specified map layer.
Definition: qgsmaprenderercache.cpp:155
QgsCoordinateTransform
Definition: qgscoordinatetransform.h:52
qgsmapmouseevent.h
QgsMapCanvas::CanvasProperties::CanvasProperties
CanvasProperties()=default
Constructor for CanvasProperties.
QgsMapCanvas::annotationItems
QList< QgsMapCanvasAnnotationItem * > annotationItems() const
Returns a list of all annotation items in the canvas.
Definition: qgsmapcanvas.cpp:2631
QgsFeatureIterator
Definition: qgsfeatureiterator.h:263
QgsMapSettings::layerToMapCoordinates
QgsPointXY layerToMapCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from layer's CRS to output CRS
Definition: qgsmapsettings.cpp:482
QgsMapSettings::setExtent
void setExtent(const QgsRectangle &rect, bool magnified=true)
Set coordinates of the rectangle which should be rendered.
Definition: qgsmapsettings.cpp:79
QgsRubberBand::setSecondaryStrokeColor
void setSecondaryStrokeColor(const QColor &color)
Sets a secondary stroke color for the rubberband which will be drawn under the main stroke color.
Definition: qgsrubberband.cpp:65
QgsRectangle::isEmpty
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:437
QgsMapTool::EditTool
@ EditTool
Map tool is an edit tool, which can only be used when layer is editable.
Definition: qgsmaptool.h:94
QgsMapTool::ShowContextMenu
@ ShowContextMenu
Show a context menu when right-clicking with the tool (since QGIS 3.14). See populateContextMenu().
Definition: qgsmaptool.h:96
QgsMapSettings::mapToPixel
const QgsMapToPixel & mapToPixel() const
Definition: qgsmapsettings.h:433
QgsRectangle::isNull
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:447
QgsTemporalProperty::FlagDontInvalidateCachedRendersWhenRangeChanges
@ FlagDontInvalidateCachedRendersWhenRangeChanges
Any cached rendering will not be invalidated when temporal range context is modified.
Definition: qgstemporalproperty.h:46
qgsproject.h
QgsRectangle::width
double width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:202
QgsRectangle::setYMinimum
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:140
QgsMapCanvas::setLayerStyleOverrides
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Sets the stored overrides of styles for rendering layers.
Definition: qgsmapcanvas.cpp:2139
QgsMapLayer::autoRefreshIntervalChanged
void autoRefreshIntervalChanged(int interval)
Emitted when the auto refresh interval changes.
QgsRectangle::setYMaximum
void setYMaximum(double y)
Set the maximum y value.
Definition: qgsrectangle.h:145
QgsRectangle::xMinimum
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
QgsMimeDataUtils::isUriList
static bool isUriList(const QMimeData *data)
Definition: qgsmimedatautils.cpp:196
QgsPreviewEffect::mode
PreviewMode mode() const
Returns the mode used for the preview effect.
Definition: qgsprevieweffect.h:73
QgsMapCanvas::setCachingEnabled
void setCachingEnabled(bool enabled)
Set whether to cache images of rendered layers.
Definition: qgsmapcanvas.cpp:457
QgsMapCanvas::setLabelingEngineSettings
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets global labeling engine settings in the internal map settings.
Definition: qgsmapcanvas.cpp:2657
QgsMapCanvas::temporalController
const QgsTemporalController * temporalController() const
Gets access to the temporal controller that will be used to update the canvas temporal range.
Definition: qgsmapcanvas.cpp:440
qgsmessagelog.h
QgsMapRendererJob::finished
void finished()
emitted when asynchronous rendering is finished (or canceled).
QgsMapCanvas::mapCanvasRefreshed
void mapCanvasRefreshed()
Emitted when canvas finished a refresh request.
QgsMapCanvas::setSelectionColor
void setSelectionColor(const QColor &color)
Set color of selected vector features.
Definition: qgsmapcanvas.cpp:2063
QgsMapCanvas::layerStateChange
void layerStateChange()
This slot is connected to the visibility change of one or more layers.
Definition: qgsmapcanvas.cpp:2108
QgsMapCanvas::stopRendering
void stopRendering()
stop rendering (if there is any right now)
Definition: qgsmapcanvas.cpp:964
QgsSvgCache::remoteSvgFetched
void remoteSvgFetched(const QString &url)
Emitted when the cache has finished retrieving an SVG file from a remote url.
QgsExpressionContextScope::removeVariable
bool removeVariable(const QString &name)
Removes a variable from the context scope, if found.
Definition: qgsexpressioncontext.cpp:98