QGIS API Documentation  3.26.3-Buenos Aires (65e4edfdad)
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 #include <QVariantAnimation>
43 #include <QPropertyAnimation>
44 
45 #include "qgis.h"
46 #include "qgssettings.h"
48 #include "qgsapplication.h"
49 #include "qgsexception.h"
51 #include "qgsfeatureiterator.h"
52 #include "qgslogger.h"
53 #include "qgsmapcanvas.h"
54 #include "qgsmapcanvasmap.h"
56 #include "qgsmaplayer.h"
57 #include "qgsmapmouseevent.h"
58 #include "qgsmaptoolpan.h"
59 #include "qgsmaptoolzoom.h"
60 #include "qgsmaptopixel.h"
61 #include "qgsmapoverviewcanvas.h"
62 #include "qgsmaprenderercache.h"
64 #include "qgsmaprendererjob.h"
67 #include "qgsmapsettingsutils.h"
68 #include "qgsmessagelog.h"
69 #include "qgsmessageviewer.h"
70 #include "qgspallabeling.h"
71 #include "qgsproject.h"
72 #include "qgsrubberband.h"
73 #include "qgsvectorlayer.h"
74 #include "qgsmapthemecollection.h"
77 #include "qgssvgcache.h"
78 #include "qgsimagecache.h"
80 #include "qgsmimedatautils.h"
81 #include "qgscustomdrophandler.h"
82 #include "qgsreferencedgeometry.h"
83 #include "qgsprojectviewsettings.h"
87 #include "qgstemporalcontroller.h"
88 #include "qgsruntimeprofiler.h"
90 #include "qgsannotationlayer.h"
93 #include "qgslabelingresults.h"
94 #include "qgsmaplayerutils.h"
95 #include "qgssettingsregistrygui.h"
96 #include "qgsrendereditemresults.h"
98 #include "qgssymbollayerutils.h"
99 
105 //TODO QGIS 4.0 - remove
107 {
108  public:
109 
113  CanvasProperties() = default;
114 
116  bool mouseButtonDown{ false };
117 
119  QPoint mouseLastXY;
120 
122  QPoint rubberStartPoint;
123 
125  bool panSelectorDown{ false };
126 };
127 
128 
129 
130 QgsMapCanvas::QgsMapCanvas( QWidget *parent )
131  : QGraphicsView( parent )
132  , mCanvasProperties( new CanvasProperties )
133  , mExpressionContextScope( tr( "Map Canvas" ) )
134 {
135  mScene = new QGraphicsScene();
136  setScene( mScene );
137  setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
138  setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
139  setMouseTracking( true );
140  setFocusPolicy( Qt::StrongFocus );
141 
142  mResizeTimer = new QTimer( this );
143  mResizeTimer->setSingleShot( true );
144  connect( mResizeTimer, &QTimer::timeout, this, &QgsMapCanvas::refresh );
145 
146  mRefreshTimer = new QTimer( this );
147  mRefreshTimer->setSingleShot( true );
148  connect( mRefreshTimer, &QTimer::timeout, this, &QgsMapCanvas::refreshMap );
149 
150  // create map canvas item which will show the map
151  mMap = new QgsMapCanvasMap( this );
152 
153  // project handling
155  this, &QgsMapCanvas::readProject );
158 
159  connect( QgsProject::instance()->mainAnnotationLayer(), &QgsMapLayer::repaintRequested, this, &QgsMapCanvas::layerRepaintRequested );
160  connect( QgsProject::instance()->mapThemeCollection(), &QgsMapThemeCollection::mapThemeChanged, this, &QgsMapCanvas::mapThemeChanged );
161  connect( QgsProject::instance()->mapThemeCollection(), &QgsMapThemeCollection::mapThemeRenamed, this, &QgsMapCanvas::mapThemeRenamed );
162  connect( QgsProject::instance()->mapThemeCollection(), &QgsMapThemeCollection::mapThemesChanged, this, &QgsMapCanvas::projectThemesChanged );
163 
164  {
165  QgsScopedRuntimeProfile profile( "Map settings initialization" );
166  mSettings.setFlag( Qgis::MapSettingsFlag::DrawEditingInfo );
168  mSettings.setFlag( Qgis::MapSettingsFlag::RenderPartialOutput );
169  mSettings.setEllipsoid( QgsProject::instance()->ellipsoid() );
171  this, [ = ]
172  {
173  mSettings.setEllipsoid( QgsProject::instance()->ellipsoid() );
174  refresh();
175  } );
176  mSettings.setTransformContext( QgsProject::instance()->transformContext() );
178  this, [ = ]
179  {
180  mSettings.setTransformContext( QgsProject::instance()->transformContext() );
181  emit transformContextChanged();
182  refresh();
183  } );
184 
186  {
187  QgsCoordinateReferenceSystem crs = mSettings.destinationCrs();
189  if ( mSettings.destinationCrs() != crs )
190  {
191  // user crs has changed definition, refresh the map
192  setDestinationCrs( crs );
193  }
194  } );
195  }
196 
197  // refresh canvas when a remote svg/image has finished downloading
200  // refresh canvas when project color scheme is changed -- if layers use project colors, they need to be redrawn
202 
203  //segmentation parameters
204  QgsSettings settings;
205  double segmentationTolerance = settings.value( QStringLiteral( "qgis/segmentationTolerance" ), "0.01745" ).toDouble();
206  QgsAbstractGeometry::SegmentationToleranceType toleranceType = settings.enumValue( QStringLiteral( "qgis/segmentationToleranceType" ), QgsAbstractGeometry::MaximumAngle );
207  mSettings.setSegmentationTolerance( segmentationTolerance );
208  mSettings.setSegmentationToleranceType( toleranceType );
209 
210  mWheelZoomFactor = settings.value( QStringLiteral( "qgis/zoom_factor" ), 2 ).toDouble();
211 
212  QSize s = viewport()->size();
213  mSettings.setOutputSize( s );
214 
215  mSettings.setRendererUsage( Qgis::RendererUsage::View );
216 
217  setSceneRect( 0, 0, s.width(), s.height() );
218  mScene->setSceneRect( QRectF( 0, 0, s.width(), s.height() ) );
219 
220  moveCanvasContents( true );
221 
222  connect( &mMapUpdateTimer, &QTimer::timeout, this, &QgsMapCanvas::mapUpdateTimeout );
223  mMapUpdateTimer.setInterval( 250 );
224 
225 #ifdef Q_OS_WIN
226  // Enable touch event on Windows.
227  // Qt on Windows needs to be told it can take touch events or else it ignores them.
228  grabGesture( Qt::PinchGesture );
229  grabGesture( Qt::TapAndHoldGesture );
230  viewport()->setAttribute( Qt::WA_AcceptTouchEvents );
231 #endif
232 
233  mPreviewEffect = new QgsPreviewEffect( this );
234  viewport()->setGraphicsEffect( mPreviewEffect );
235 
236  mZoomCursor = QgsApplication::getThemeCursor( QgsApplication::Cursor::ZoomIn );
237 
238  connect( &mAutoRefreshTimer, &QTimer::timeout, this, &QgsMapCanvas::autoRefreshTriggered );
239 
241 
242  setInteractive( false );
243 
244  // make sure we have the same default in QgsMapSettings and the scene's background brush
245  // (by default map settings has white bg color, scene background brush is black)
246  setCanvasColor( mSettings.backgroundColor() );
247 
248  setTemporalRange( mSettings.temporalRange() );
249  refresh();
250 }
251 
252 
254 {
255  if ( mMapTool )
256  {
257  mMapTool->deactivate();
258  mMapTool = nullptr;
259  }
260  mLastNonZoomMapTool = nullptr;
261 
262  cancelJobs();
263 
264  // delete canvas items prior to deleting the canvas
265  // because they might try to update canvas when it's
266  // already being destructed, ends with segfault
267  qDeleteAll( mScene->items() );
268 
269  mScene->deleteLater(); // crashes in python tests on windows
270 
271  delete mCache;
272 }
273 
274 
276 {
277  // rendering job may still end up writing into canvas map item
278  // so kill it before deleting canvas items
279  if ( mJob )
280  {
281  whileBlocking( mJob )->cancel();
282  delete mJob;
283  mJob = nullptr;
284  }
285 
286  for ( auto previewJob = mPreviewJobs.constBegin(); previewJob != mPreviewJobs.constEnd(); ++previewJob )
287  {
288  if ( *previewJob )
289  {
290  whileBlocking( *previewJob )->cancel();
291  delete *previewJob;
292  }
293  }
294  mPreviewJobs.clear();
295 }
296 
297 void QgsMapCanvas::setMagnificationFactor( double factor, const QgsPointXY *center )
298 {
299  // do not go higher or lower than min max magnification ratio
300  double magnifierMin = QgsGuiUtils::CANVAS_MAGNIFICATION_MIN;
301  double magnifierMax = QgsGuiUtils::CANVAS_MAGNIFICATION_MAX;
302  factor = std::clamp( factor, magnifierMin, magnifierMax );
303 
304  // the magnifier widget is in integer percent
305  if ( !qgsDoubleNear( factor, mSettings.magnificationFactor(), 0.01 ) )
306  {
307  mSettings.setMagnificationFactor( factor, center );
308  refresh();
309  emit magnificationChanged( factor );
310  }
311 }
312 
314 {
315  return mSettings.magnificationFactor();
316 }
317 
319 {
320  mSettings.setFlag( Qgis::MapSettingsFlag::Antialiasing, flag );
322 }
323 
325 {
326  return mSettings.testFlag( Qgis::MapSettingsFlag::Antialiasing );
327 }
328 
330 {
332 }
333 
335 {
336  QList<QgsMapLayer *> layers = mapSettings().layers();
337  if ( index >= 0 && index < layers.size() )
338  return layers[index];
339  else
340  return nullptr;
341 }
342 
343 QgsMapLayer *QgsMapCanvas::layer( const QString &id )
344 {
345  // first check for layers from canvas map settings
346  const QList<QgsMapLayer *> layers = mapSettings().layers();
347  for ( QgsMapLayer *layer : layers )
348  {
349  if ( layer && layer->id() == id )
350  return layer;
351  }
352 
353  // else fallback to searching project layers
354  // TODO: allow a specific project to be associated with a canvas!
355  return QgsProject::instance()->mapLayer( id );
356 }
357 
359 {
360  if ( mCurrentLayer == layer )
361  return;
362 
363  mCurrentLayer = layer;
364  emit currentLayerChanged( layer );
365 }
366 
367 double QgsMapCanvas::scale() const
368 {
369  return mapSettings().scale();
370 }
371 
373 {
374  return nullptr != mJob;
375 } // isDrawing
376 
377 // return the current coordinate transform based on the extents and
378 // device size
380 {
381  return &mapSettings().mapToPixel();
382 }
383 
384 void QgsMapCanvas::setLayers( const QList<QgsMapLayer *> &layers )
385 {
386  // following a theme => request denied!
387  if ( !mTheme.isEmpty() )
388  return;
389 
390  setLayersPrivate( layers );
391 }
392 
393 void QgsMapCanvas::setLayersPrivate( const QList<QgsMapLayer *> &layers )
394 {
395  QList<QgsMapLayer *> oldLayers = mSettings.layers();
396 
397  // update only if needed
398  if ( layers == oldLayers )
399  return;
400 
401  const auto constOldLayers = oldLayers;
402  for ( QgsMapLayer *layer : constOldLayers )
403  {
404  disconnect( layer, &QgsMapLayer::repaintRequested, this, &QgsMapCanvas::layerRepaintRequested );
405  disconnect( layer, &QgsMapLayer::autoRefreshIntervalChanged, this, &QgsMapCanvas::updateAutoRefreshTimer );
406  if ( QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
407  {
409  disconnect( vlayer, &QgsVectorLayer::rendererChanged, this, &QgsMapCanvas::updateAutoRefreshTimer );
410  }
411  }
412 
413  mSettings.setLayers( layers );
414 
415  const auto constLayers = layers;
416  for ( QgsMapLayer *layer : constLayers )
417  {
418  if ( !layer )
419  continue;
420  connect( layer, &QgsMapLayer::repaintRequested, this, &QgsMapCanvas::layerRepaintRequested );
421  connect( layer, &QgsMapLayer::autoRefreshIntervalChanged, this, &QgsMapCanvas::updateAutoRefreshTimer );
422  if ( QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer ) )
423  {
425  connect( vlayer, &QgsVectorLayer::rendererChanged, this, &QgsMapCanvas::updateAutoRefreshTimer );
426  }
427  }
428 
429  QgsDebugMsgLevel( QStringLiteral( "Layers have changed, refreshing" ), 2 );
430  emit layersChanged();
431 
432  updateAutoRefreshTimer();
433  refresh();
434 }
435 
436 
438 {
439  return mSettings;
440 }
441 
443 {
444  if ( mSettings.destinationCrs() == crs )
445  return;
446 
447  // try to reproject current extent to the new one
448  QgsRectangle rect;
449  if ( !mSettings.visibleExtent().isEmpty() )
450  {
451  const QgsCoordinateTransform transform( mSettings.destinationCrs(), crs, QgsProject::instance(),
454  try
455  {
456  rect = transform.transformBoundingBox( mSettings.visibleExtent() );
457  }
458  catch ( QgsCsException &e )
459  {
460  Q_UNUSED( e )
461  QgsDebugMsg( QStringLiteral( "Transform error caught: %1" ).arg( e.what() ) );
462  }
463  }
464 
465  if ( !rect.isEmpty() )
466  {
467  // we will be manually calling updateCanvasItemPositions() later, AFTER setting the updating the mSettings destination CRS, and we don't
468  // want to do that twice!
469  mBlockItemPositionUpdates++;
470  setExtent( rect );
471  mBlockItemPositionUpdates--;
472  }
473 
474  mSettings.setDestinationCrs( crs );
475  updateScale();
477 
478  QgsDebugMsgLevel( QStringLiteral( "refreshing after destination CRS changed" ), 2 );
479  refresh();
480 
481  emit destinationCrsChanged();
482 }
483 
485 {
486  if ( mController )
488  if ( QgsTemporalNavigationObject *temporalNavigationObject = qobject_cast< QgsTemporalNavigationObject * >( mController ) )
489  {
490  disconnect( temporalNavigationObject, &QgsTemporalNavigationObject::navigationModeChanged, this, &QgsMapCanvas::temporalControllerModeChanged );
491 
492  // clear any existing animation settings from map settings. We don't do this on every render, as a 3rd party plugin
493  // might be in control of these!
494  mSettings.setFrameRate( -1 );
495  mSettings.setCurrentFrame( -1 );
496  }
497 
498  mController = controller;
500  if ( QgsTemporalNavigationObject *temporalNavigationObject = qobject_cast< QgsTemporalNavigationObject * >( mController ) )
501  connect( temporalNavigationObject, &QgsTemporalNavigationObject::navigationModeChanged, this, &QgsMapCanvas::temporalControllerModeChanged );
502 }
503 
504 void QgsMapCanvas::temporalControllerModeChanged()
505 {
506  if ( QgsTemporalNavigationObject *temporalNavigationObject = qobject_cast< QgsTemporalNavigationObject * >( mController ) )
507  {
508  switch ( temporalNavigationObject->navigationMode() )
509  {
511  mSettings.setFrameRate( temporalNavigationObject->framesPerSecond() );
512  mSettings.setCurrentFrame( temporalNavigationObject->currentFrameNumber() );
513  break;
514 
517  // clear any existing animation settings from map settings. We don't do this on every render, as a 3rd party plugin
518  // might be in control of these!
519  mSettings.setFrameRate( -1 );
520  mSettings.setCurrentFrame( -1 );
521  break;
522  }
523  }
524 }
525 
527 {
528  return mController;
529 }
530 
531 void QgsMapCanvas::setMapSettingsFlags( Qgis::MapSettingsFlags flags )
532 {
533  mSettings.setFlags( flags );
534  clearCache();
535  refresh();
536 }
537 
538 const QgsLabelingResults *QgsMapCanvas::labelingResults( bool allowOutdatedResults ) const
539 {
540  if ( !allowOutdatedResults && mLabelingResultsOutdated )
541  return nullptr;
542 
543  return mLabelingResults.get();
544 }
545 
546 const QgsRenderedItemResults *QgsMapCanvas::renderedItemResults( bool allowOutdatedResults ) const
547 {
548  if ( !allowOutdatedResults && mRenderedItemResultsOutdated )
549  return nullptr;
550 
551  return mRenderedItemResults.get();
552 }
553 
555 {
556  if ( enabled == isCachingEnabled() )
557  return;
558 
559  if ( mJob && mJob->isActive() )
560  {
561  // wait for the current rendering to finish, before touching the cache
562  mJob->waitForFinished();
563  }
564 
565  if ( enabled )
566  {
567  mCache = new QgsMapRendererCache;
568  }
569  else
570  {
571  delete mCache;
572  mCache = nullptr;
573  }
574  mPreviousRenderedItemResults.reset();
575 }
576 
578 {
579  return nullptr != mCache;
580 }
581 
583 {
584  if ( mCache )
585  mCache->clear();
586 
587  if ( mPreviousRenderedItemResults )
588  mPreviousRenderedItemResults.reset();
589  if ( mRenderedItemResults )
590  mRenderedItemResults.reset();
591 }
592 
594 {
595  mUseParallelRendering = enabled;
596 }
597 
599 {
600  return mUseParallelRendering;
601 }
602 
603 void QgsMapCanvas::setMapUpdateInterval( int timeMilliseconds )
604 {
605  mMapUpdateTimer.setInterval( timeMilliseconds );
606 }
607 
609 {
610  return mMapUpdateTimer.interval();
611 }
612 
613 
615 {
616  return mCurrentLayer;
617 }
618 
620 {
621  QgsExpressionContextScope *s = new QgsExpressionContextScope( QObject::tr( "Map Canvas" ) );
622  s->setVariable( QStringLiteral( "canvas_cursor_point" ), QgsGeometry::fromPointXY( cursorPoint() ), true );
623  return s;
624 }
625 
627 {
628  //build the expression context
629  QgsExpressionContext expressionContext;
630  expressionContext << QgsExpressionContextUtils::globalScope()
634  if ( QgsExpressionContextScopeGenerator *generator = dynamic_cast< QgsExpressionContextScopeGenerator * >( mController ) )
635  {
636  expressionContext << generator->createExpressionContextScope();
637  }
638  expressionContext << defaultExpressionContextScope()
639  << new QgsExpressionContextScope( mExpressionContextScope );
640  return expressionContext;
641 }
642 
644 {
645  if ( !mSettings.hasValidSettings() )
646  {
647  QgsDebugMsgLevel( QStringLiteral( "CANVAS refresh - invalid settings -> nothing to do" ), 2 );
648  return;
649  }
650 
651  if ( !mRenderFlag || mFrozen )
652  {
653  QgsDebugMsgLevel( QStringLiteral( "CANVAS render flag off" ), 2 );
654  return;
655  }
656 
657  if ( mRefreshScheduled )
658  {
659  QgsDebugMsgLevel( QStringLiteral( "CANVAS refresh already scheduled" ), 2 );
660  return;
661  }
662 
663  mRefreshScheduled = true;
664 
665  QgsDebugMsgLevel( QStringLiteral( "CANVAS refresh scheduling" ), 2 );
666 
667  // schedule a refresh
668  mRefreshTimer->start( 1 );
669 
670  mLabelingResultsOutdated = true;
671  mRenderedItemResultsOutdated = true;
672 }
673 
674 void QgsMapCanvas::refreshMap()
675 {
676  Q_ASSERT( mRefreshScheduled );
677 
678  QgsDebugMsgLevel( QStringLiteral( "CANVAS refresh!" ), 3 );
679 
680  stopRendering(); // if any...
681  stopPreviewJobs();
682 
684 
685  // if using the temporal controller in animation mode, get the frame settings from that
686  if ( QgsTemporalNavigationObject *temporalNavigationObject = dynamic_cast < QgsTemporalNavigationObject * >( mController ) )
687  {
688  switch ( temporalNavigationObject->navigationMode() )
689  {
691  mSettings.setFrameRate( temporalNavigationObject->framesPerSecond() );
692  mSettings.setCurrentFrame( temporalNavigationObject->currentFrameNumber() );
693  break;
694 
697  break;
698  }
699  }
700 
701  mSettings.setPathResolver( QgsProject::instance()->pathResolver() );
702 
703  if ( !mTheme.isEmpty() )
704  {
705  // IMPORTANT: we MUST set the layer style overrides here! (At the time of writing this
706  // comment) retrieving layer styles from the theme collection gives an XML snapshot of the
707  // current state of the style. If we had stored the style overrides earlier (such as in
708  // mapThemeChanged slot) then this xml could be out of date...
709  // TODO: if in future QgsMapThemeCollection::mapThemeStyleOverrides is changed to
710  // just return the style name, we can instead set the overrides in mapThemeChanged and not here
711  mSettings.setLayerStyleOverrides( QgsProject::instance()->mapThemeCollection()->mapThemeStyleOverrides( mTheme ) );
712  }
713 
714  // render main annotation layer above all other layers
715  QgsMapSettings renderSettings = mSettings;
716  QList<QgsMapLayer *> allLayers = renderSettings.layers();
717  allLayers.insert( 0, QgsProject::instance()->mainAnnotationLayer() );
718  renderSettings.setLayers( allLayers );
719 
720  // create the renderer job
721  Q_ASSERT( !mJob );
722  mJobCanceled = false;
723  if ( mUseParallelRendering )
724  mJob = new QgsMapRendererParallelJob( renderSettings );
725  else
726  mJob = new QgsMapRendererSequentialJob( renderSettings );
727 
728  connect( mJob, &QgsMapRendererJob::finished, this, &QgsMapCanvas::rendererJobFinished );
729  mJob->setCache( mCache );
730  mJob->setLayerRenderingTimeHints( mLastLayerRenderTime );
731 
732  mJob->start();
733 
734  // from now on we can accept refresh requests again
735  // this must be reset only after the job has been started, because
736  // some providers (yes, it's you WCS and AMS!) during preparation
737  // do network requests and start an internal event loop, which may
738  // end up calling refresh() and would schedule another refresh,
739  // deleting the one we have just started.
740  mRefreshScheduled = false;
741 
742  mMapUpdateTimer.start();
743 
744  emit renderStarting();
745 }
746 
747 void QgsMapCanvas::mapThemeChanged( const QString &theme )
748 {
749  if ( theme == mTheme )
750  {
751  // set the canvas layers to match the new layers contained in the map theme
752  // NOTE: we do this when the theme layers change and not when we are refreshing the map
753  // as setLayers() sets up necessary connections to handle changes to the layers
754  setLayersPrivate( QgsProject::instance()->mapThemeCollection()->mapThemeVisibleLayers( mTheme ) );
755  // IMPORTANT: we don't set the layer style overrides here! (At the time of writing this
756  // comment) retrieving layer styles from the theme collection gives an XML snapshot of the
757  // current state of the style. If changes were made to the style then this xml
758  // snapshot goes out of sync...
759  // TODO: if in future QgsMapThemeCollection::mapThemeStyleOverrides is changed to
760  // just return the style name, we can instead set the overrides here and not in refreshMap()
761 
762  clearCache();
763  refresh();
764  }
765 }
766 
767 void QgsMapCanvas::mapThemeRenamed( const QString &theme, const QString &newTheme )
768 {
769  if ( mTheme.isEmpty() || theme != mTheme )
770  {
771  return;
772  }
773 
774  setTheme( newTheme );
775  refresh();
776 }
777 
778 void QgsMapCanvas::rendererJobFinished()
779 {
780  QgsDebugMsgLevel( QStringLiteral( "CANVAS finish! %1" ).arg( !mJobCanceled ), 2 );
781 
782  mMapUpdateTimer.stop();
783 
784  notifyRendererErrors( mJob->errors() );
785 
786  if ( !mJobCanceled )
787  {
788  // take labeling results before emitting renderComplete, so labeling map tools
789  // connected to signal work with correct results
790  if ( !mJob->usedCachedLabels() )
791  {
792  mLabelingResults.reset( mJob->takeLabelingResults() );
793  }
794  mLabelingResultsOutdated = false;
795 
796  std::unique_ptr< QgsRenderedItemResults > renderedItemResults( mJob->takeRenderedItemResults() );
797  // if a layer was redrawn from the cached version, we should copy any existing rendered item results from that layer
798  if ( mRenderedItemResults )
799  {
800  renderedItemResults->transferResults( mRenderedItemResults.get(), mJob->layersRedrawnFromCache() );
801  }
802  if ( mPreviousRenderedItemResults )
803  {
804  // also transfer any results from previous renders which happened before this
805  renderedItemResults->transferResults( mPreviousRenderedItemResults.get(), mJob->layersRedrawnFromCache() );
806  }
807 
808  if ( mCache && !mPreviousRenderedItemResults )
809  mPreviousRenderedItemResults = std::make_unique< QgsRenderedItemResults >( mJob->mapSettings().extent() );
810 
811  if ( mRenderedItemResults && mPreviousRenderedItemResults )
812  {
813  // for other layers which ARE present in the most recent rendered item results BUT were not part of this render, we
814  // store the results in a temporary store in case they are later switched back on and the layer's image is taken
815  // from the cache
816  mPreviousRenderedItemResults->transferResults( mRenderedItemResults.get() );
817  }
818  if ( mPreviousRenderedItemResults )
819  {
820  mPreviousRenderedItemResults->eraseResultsFromLayers( mJob->mapSettings().layerIds() );
821  }
822 
823  mRenderedItemResults = std::move( renderedItemResults );
824  mRenderedItemResultsOutdated = false;
825 
826  QImage img = mJob->renderedImage();
827 
828  // emit renderComplete to get our decorations drawn
829  QPainter p( &img );
830  emit renderComplete( &p );
831 
833  {
834  QString logMsg = tr( "Canvas refresh: %1 ms" ).arg( mJob->renderingTime() );
835  QgsMessageLog::logMessage( logMsg, tr( "Rendering" ) );
836  }
837 
838  if ( mDrawRenderingStats )
839  {
840  int w = img.width(), h = img.height();
841  QFont fnt = p.font();
842  fnt.setBold( true );
843  p.setFont( fnt );
844  int lh = p.fontMetrics().height() * 2;
845  QRect r( 0, h - lh, w, lh );
846  p.setPen( Qt::NoPen );
847  p.setBrush( QColor( 0, 0, 0, 110 ) );
848  p.drawRect( r );
849  p.setPen( Qt::white );
850  QString msg = QStringLiteral( "%1 :: %2 ms" ).arg( mUseParallelRendering ? QStringLiteral( "PARALLEL" ) : QStringLiteral( "SEQUENTIAL" ) ).arg( mJob->renderingTime() );
851  p.drawText( r, msg, QTextOption( Qt::AlignCenter ) );
852  }
853 
854  p.end();
855 
856  mMap->setContent( img, imageRect( img, mSettings ) );
857 
858  mLastLayerRenderTime.clear();
859  const auto times = mJob->perLayerRenderingTime();
860  for ( auto it = times.constBegin(); it != times.constEnd(); ++it )
861  {
862  mLastLayerRenderTime.insert( it.key()->id(), it.value() );
863  }
864  if ( mUsePreviewJobs && !mRefreshAfterJob )
865  startPreviewJobs();
866  }
867  else
868  {
869  mRefreshAfterJob = false;
870  }
871 
872  // now we are in a slot called from mJob - do not delete it immediately
873  // so the class is still valid when the execution returns to the class
874  mJob->deleteLater();
875  mJob = nullptr;
876 
877  emit mapCanvasRefreshed();
878 
879  if ( mRefreshAfterJob )
880  {
881  mRefreshAfterJob = false;
882  clearTemporalCache();
883  clearElevationCache();
884  refresh();
885  }
886 }
887 
888 void QgsMapCanvas::previewJobFinished()
889 {
890  QgsMapRendererQImageJob *job = qobject_cast<QgsMapRendererQImageJob *>( sender() );
891  Q_ASSERT( job );
892 
893  if ( mMap )
894  {
895  mMap->addPreviewImage( job->renderedImage(), job->mapSettings().extent() );
896  mPreviewJobs.removeAll( job );
897 
898  int number = job->property( "number" ).toInt();
899  if ( number < 8 )
900  {
901  startPreviewJob( number + 1 );
902  }
903 
904  delete job;
905  }
906 }
907 
908 QgsRectangle QgsMapCanvas::imageRect( const QImage &img, const QgsMapSettings &mapSettings )
909 {
910  // This is a hack to pass QgsMapCanvasItem::setRect what it
911  // expects (encoding of position and size of the item)
912  const QgsMapToPixel &m2p = mapSettings.mapToPixel();
913  QgsPointXY topLeft = m2p.toMapCoordinates( 0, 0 );
914 #ifdef QGISDEBUG
915  // do not assert this, since it might lead to crashes when changing screen while rendering
916  if ( img.devicePixelRatio() != mapSettings.devicePixelRatio() )
917  {
918  QgsLogger::warning( QStringLiteral( "The renderer map has a wrong device pixel ratio" ) );
919  }
920 #endif
921  double res = m2p.mapUnitsPerPixel() / img.devicePixelRatioF();
922  QgsRectangle rect( topLeft.x(), topLeft.y(), topLeft.x() + img.width()*res, topLeft.y() - img.height()*res );
923  return rect;
924 }
925 
927 {
928  return mUsePreviewJobs;
929 }
930 
932 {
933  mUsePreviewJobs = enabled;
934 }
935 
936 void QgsMapCanvas::setCustomDropHandlers( const QVector<QPointer<QgsCustomDropHandler> > &handlers )
937 {
938  mDropHandlers = handlers;
939 }
940 
941 void QgsMapCanvas::clearTemporalCache()
942 {
943  if ( mCache )
944  {
945  bool invalidateLabels = false;
946  const QList<QgsMapLayer *> layerList = mapSettings().layers();
947  for ( QgsMapLayer *layer : layerList )
948  {
949  bool alreadyInvalidatedThisLayer = false;
950  if ( QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( layer ) )
951  {
952  if ( vl->renderer() && QgsSymbolLayerUtils::rendererFrameRate( vl->renderer() ) > -1 )
953  {
954  // layer has an animated symbol assigned, so we have to redraw it regardless of whether
955  // or not it has temporal settings
956  mCache->invalidateCacheForLayer( layer );
957  alreadyInvalidatedThisLayer = true;
958  // we can't shortcut and "continue" here, as we still need to check whether the layer
959  // will cause label invalidation using the logic below
960  }
961  }
962 
964  {
965  if ( QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( layer ) )
966  {
967  if ( vl->labelsEnabled() || vl->diagramsEnabled() )
968  invalidateLabels = true;
969  }
970 
972  continue;
973 
974  if ( !alreadyInvalidatedThisLayer )
975  mCache->invalidateCacheForLayer( layer );
976  }
977  }
978 
979  if ( invalidateLabels )
980  {
981  mCache->clearCacheImage( QStringLiteral( "_labels_" ) );
982  mCache->clearCacheImage( QStringLiteral( "_preview_labels_" ) );
983  }
984  }
985 }
986 
987 void QgsMapCanvas::clearElevationCache()
988 {
989  if ( mCache )
990  {
991  bool invalidateLabels = false;
992  const QList<QgsMapLayer *> layerList = mapSettings().layers();
993  for ( QgsMapLayer *layer : layerList )
994  {
996  {
997  if ( QgsVectorLayer *vl = qobject_cast< QgsVectorLayer * >( layer ) )
998  {
999  if ( vl->labelsEnabled() || vl->diagramsEnabled() )
1000  invalidateLabels = true;
1001  }
1002 
1004  continue;
1005 
1006  mCache->invalidateCacheForLayer( layer );
1007  }
1008  }
1009 
1010  if ( invalidateLabels )
1011  {
1012  mCache->clearCacheImage( QStringLiteral( "_labels_" ) );
1013  mCache->clearCacheImage( QStringLiteral( "_preview_labels_" ) );
1014  }
1015  }
1016 }
1017 
1018 void QgsMapCanvas::showContextMenu( QgsMapMouseEvent *event )
1019 {
1020  const QgsPointXY mapPoint = event->originalMapPoint();
1021 
1022  QMenu menu;
1023 
1024  QMenu *copyCoordinateMenu = new QMenu( tr( "Copy Coordinate" ), &menu );
1025  copyCoordinateMenu->setIcon( QgsApplication::getThemeIcon( QStringLiteral( "/mActionEditCopy.svg" ) ) );
1026 
1027  auto addCoordinateFormat = [ &, this]( const QString identifier, const QgsCoordinateReferenceSystem & crs )
1028  {
1029  const QgsCoordinateTransform ct( mSettings.destinationCrs(), crs, mSettings.transformContext() );
1030  try
1031  {
1032  const QgsPointXY transformedPoint = ct.transform( mapPoint );
1033 
1034  // calculate precision based on visible map extent -- if user is zoomed in, we get better precision!
1035  int displayPrecision = 0;
1036  try
1037  {
1038  QgsCoordinateTransform extentTransform = ct;
1039  extentTransform.setBallparkTransformsAreAppropriate( true );
1040  QgsRectangle extentReproj = extentTransform.transformBoundingBox( extent() );
1041  const double mapUnitsPerPixel = ( extentReproj.width() / width() + extentReproj.height() / height() ) * 0.5;
1042  if ( mapUnitsPerPixel > 10 )
1043  displayPrecision = 0;
1044  else if ( mapUnitsPerPixel > 1 )
1045  displayPrecision = 1;
1046  else if ( mapUnitsPerPixel > 0.1 )
1047  displayPrecision = 2;
1048  else if ( mapUnitsPerPixel > 0.01 )
1049  displayPrecision = 3;
1050  else if ( mapUnitsPerPixel > 0.001 )
1051  displayPrecision = 4;
1052  else if ( mapUnitsPerPixel > 0.0001 )
1053  displayPrecision = 5;
1054  else if ( mapUnitsPerPixel > 0.00001 )
1055  displayPrecision = 6;
1056  else if ( mapUnitsPerPixel > 0.000001 )
1057  displayPrecision = 7;
1058  else if ( mapUnitsPerPixel > 0.0000001 )
1059  displayPrecision = 8;
1060  else
1061  displayPrecision = 9;
1062  }
1063  catch ( QgsCsException & )
1064  {
1065  displayPrecision = crs.mapUnits() == QgsUnitTypes::DistanceDegrees ? 5 : 3;
1066  }
1067 
1068  const QList< Qgis::CrsAxisDirection > axisList = crs.axisOrdering();
1069  QString firstSuffix;
1070  QString secondSuffix;
1071  if ( axisList.size() >= 2 )
1072  {
1075  }
1076 
1077  QString firstNumber;
1078  QString secondNumber;
1080  {
1081  firstNumber = QString::number( transformedPoint.y(), 'f', displayPrecision );
1082  secondNumber = QString::number( transformedPoint.x(), 'f', displayPrecision );
1083  }
1084  else
1085  {
1086  firstNumber = QString::number( transformedPoint.x(), 'f', displayPrecision );
1087  secondNumber = QString::number( transformedPoint.y(), 'f', displayPrecision );
1088  }
1089 
1090  QAction *copyCoordinateAction = new QAction( QStringLiteral( "%5 (%1%2, %3%4)" ).arg(
1091  firstNumber, firstSuffix, secondNumber, secondSuffix, identifier ), &menu );
1092 
1093  connect( copyCoordinateAction, &QAction::triggered, this, [firstNumber, secondNumber, transformedPoint]
1094  {
1095  QClipboard *clipboard = QApplication::clipboard();
1096 
1097  const QString coordinates = firstNumber + ',' + secondNumber;
1098 
1099  //if we are on x11 system put text into selection ready for middle button pasting
1100  if ( clipboard->supportsSelection() )
1101  {
1102  clipboard->setText( coordinates, QClipboard::Selection );
1103  }
1104  clipboard->setText( coordinates, QClipboard::Clipboard );
1105 
1106  } );
1107  copyCoordinateMenu->addAction( copyCoordinateAction );
1108  }
1109  catch ( QgsCsException & )
1110  {
1111 
1112  }
1113  };
1114 
1115  addCoordinateFormat( tr( "Map CRS — %1" ).arg( mSettings.destinationCrs().userFriendlyIdentifier( QgsCoordinateReferenceSystem::MediumString ) ), mSettings.destinationCrs() );
1116  QgsCoordinateReferenceSystem wgs84( QStringLiteral( "EPSG:4326" ) );
1117  if ( mSettings.destinationCrs() != wgs84 )
1118  addCoordinateFormat( wgs84.userFriendlyIdentifier( QgsCoordinateReferenceSystem::MediumString ), wgs84 );
1119 
1120  QgsSettings settings;
1121  const QString customCrsString = settings.value( QStringLiteral( "qgis/custom_coordinate_crs" ) ).toString();
1122  if ( !customCrsString.isEmpty() )
1123  {
1124  QgsCoordinateReferenceSystem customCrs( customCrsString );
1125  if ( customCrs != mSettings.destinationCrs() && customCrs != QgsCoordinateReferenceSystem( QStringLiteral( "EPSG:4326" ) ) )
1126  {
1127  addCoordinateFormat( customCrs.userFriendlyIdentifier( QgsCoordinateReferenceSystem::MediumString ), customCrs );
1128  }
1129  }
1130  copyCoordinateMenu->addSeparator();
1131  QAction *setCustomCrsAction = new QAction( tr( "Set Custom CRS…" ), &menu );
1132  connect( setCustomCrsAction, &QAction::triggered, this, [ = ]
1133  {
1134  QgsProjectionSelectionDialog selector( this );
1135  selector.setCrs( QgsCoordinateReferenceSystem( customCrsString ) );
1136  if ( selector.exec() )
1137  {
1138  QgsSettings().setValue( QStringLiteral( "qgis/custom_coordinate_crs" ), selector.crs().authid().isEmpty() ? selector.crs().toWkt( QgsCoordinateReferenceSystem::WKT_PREFERRED ) : selector.crs().authid() );
1139  }
1140  } );
1141  copyCoordinateMenu->addAction( setCustomCrsAction );
1142 
1143  menu.addMenu( copyCoordinateMenu );
1144 
1145  if ( mMapTool )
1146  if ( !mapTool()->populateContextMenuWithEvent( &menu, event ) )
1147  mMapTool->populateContextMenu( &menu );
1148 
1149  emit contextMenuAboutToShow( &menu, event );
1150 
1151  menu.exec( event->globalPos() );
1152 }
1153 
1154 void QgsMapCanvas::notifyRendererErrors( const QgsMapRendererJob::Errors &errors )
1155 {
1156  const QDateTime currentTime = QDateTime::currentDateTime();
1157 
1158  // remove errors too old
1159  for ( const QgsMapRendererJob::Error &error : errors )
1160  {
1161  const QString errorKey = error.layerID + ':' + error.message;
1162  if ( mRendererErrors.contains( errorKey ) )
1163  {
1164  const QDateTime sameErrorTime = mRendererErrors.value( errorKey );
1165 
1166  if ( sameErrorTime.secsTo( currentTime ) < 60 )
1167  continue;
1168  }
1169 
1170  mRendererErrors[errorKey] = currentTime;
1171 
1172  if ( QgsMapLayer *layer = QgsProject::instance()->mapLayer( error.layerID ) )
1173  emit renderErrorOccurred( error.message, layer );
1174  }
1175 }
1176 
1177 void QgsMapCanvas::updateDevicePixelFromScreen()
1178 {
1179  mSettings.setDevicePixelRatio( devicePixelRatio() );
1180  // TODO: QGIS 4 -> always respect screen dpi
1182  {
1183  if ( window()->windowHandle() )
1184  {
1185  mSettings.setOutputDpi( window()->windowHandle()->screen()->physicalDotsPerInch() );
1186  mSettings.setDpiTarget( window()->windowHandle()->screen()->physicalDotsPerInch() );
1187  }
1188  }
1189  else
1190  {
1191  // Fallback: compatibility with QGIS <= 3.20; always assume low dpi screens
1192  mSettings.setOutputDpi( window()->windowHandle()->screen()->logicalDotsPerInch() );
1193  mSettings.setDpiTarget( window()->windowHandle()->screen()->logicalDotsPerInch() );
1194  }
1195 }
1196 
1197 void QgsMapCanvas::setTemporalRange( const QgsDateTimeRange &dateTimeRange )
1198 {
1199  if ( temporalRange() == dateTimeRange )
1200  return;
1201 
1202  mSettings.setTemporalRange( dateTimeRange );
1203  mSettings.setIsTemporal( dateTimeRange.begin().isValid() || dateTimeRange.end().isValid() );
1204 
1205  emit temporalRangeChanged();
1206 
1207  // we need to discard any previously cached images which have temporal properties enabled, so that these will be updated when
1208  // the canvas is redrawn
1209  if ( !mJob )
1210  clearTemporalCache();
1211 
1212  autoRefreshTriggered();
1213 }
1214 
1215 const QgsDateTimeRange &QgsMapCanvas::temporalRange() const
1216 {
1217  return mSettings.temporalRange();
1218 }
1219 
1221 {
1222  mInteractionBlockers.append( blocker );
1223 }
1224 
1226 {
1227  mInteractionBlockers.removeAll( blocker );
1228 }
1229 
1231 {
1232  for ( const QgsMapCanvasInteractionBlocker *block : mInteractionBlockers )
1233  {
1234  if ( block->blockCanvasInteraction( interaction ) )
1235  return false;
1236  }
1237  return true;
1238 }
1239 
1240 void QgsMapCanvas::mapUpdateTimeout()
1241 {
1242  if ( mJob )
1243  {
1244  const QImage &img = mJob->renderedImage();
1245  mMap->setContent( img, imageRect( img, mSettings ) );
1246  }
1247 }
1248 
1250 {
1251  if ( mJob )
1252  {
1253  QgsDebugMsgLevel( QStringLiteral( "CANVAS stop rendering!" ), 2 );
1254  mJobCanceled = true;
1255  disconnect( mJob, &QgsMapRendererJob::finished, this, &QgsMapCanvas::rendererJobFinished );
1256  connect( mJob, &QgsMapRendererQImageJob::finished, mJob, &QgsMapRendererQImageJob::deleteLater );
1257  mJob->cancelWithoutBlocking();
1258  mJob = nullptr;
1259  emit mapRefreshCanceled();
1260  }
1261  stopPreviewJobs();
1262 }
1263 
1264 //the format defaults to "PNG" if not specified
1265 void QgsMapCanvas::saveAsImage( const QString &fileName, QPixmap *theQPixmap, const QString &format )
1266 {
1267  QPainter painter;
1268  QImage image;
1269 
1270  //
1271  //check if the optional QPaintDevice was supplied
1272  //
1273  if ( theQPixmap )
1274  {
1275  image = theQPixmap->toImage();
1276  painter.begin( &image );
1277 
1278  // render
1279  QgsMapRendererCustomPainterJob job( mSettings, &painter );
1280  job.start();
1281  job.waitForFinished();
1282  emit renderComplete( &painter );
1283  }
1284  else //use the map view
1285  {
1286  image = mMap->contentImage().copy();
1287  painter.begin( &image );
1288  }
1289 
1290  // draw annotations
1291  QStyleOptionGraphicsItem option;
1292  option.initFrom( this );
1293  QGraphicsItem *item = nullptr;
1294  QListIterator<QGraphicsItem *> i( items() );
1295  i.toBack();
1296  while ( i.hasPrevious() )
1297  {
1298  item = i.previous();
1299 
1300  if ( !( item && dynamic_cast< QgsMapCanvasAnnotationItem * >( item ) ) )
1301  {
1302  continue;
1303  }
1304 
1305  QgsScopedQPainterState painterState( &painter );
1306 
1307  QPointF itemScenePos = item->scenePos();
1308  painter.translate( itemScenePos.x(), itemScenePos.y() );
1309 
1310  item->paint( &painter, &option );
1311  }
1312 
1313  painter.end();
1314  image.save( fileName, format.toLocal8Bit().data() );
1315 
1316  QFileInfo myInfo = QFileInfo( fileName );
1317 
1318  // build the world file name
1319  QString outputSuffix = myInfo.suffix();
1320  QString myWorldFileName = myInfo.absolutePath() + '/' + myInfo.completeBaseName() + '.'
1321  + outputSuffix.at( 0 ) + outputSuffix.at( myInfo.suffix().size() - 1 ) + 'w';
1322  QFile myWorldFile( myWorldFileName );
1323  if ( !myWorldFile.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) //don't use QIODevice::Text
1324  {
1325  return;
1326  }
1327  QTextStream myStream( &myWorldFile );
1329 }
1330 
1332 {
1333  return mapSettings().visibleExtent();
1334 }
1335 
1337 {
1338  return QgsMapLayerUtils::combinedExtent( mSettings.layers(), mapSettings().destinationCrs(), QgsProject::instance()->transformContext() );
1339 }
1340 
1342 {
1344  QgsCoordinateTransform ct( extent.crs(), mapSettings().destinationCrs(), mProject ? mProject->transformContext() : QgsProject::instance()->transformContext() );
1346  QgsRectangle rect;
1347  try
1348  {
1349  rect = ct.transformBoundingBox( extent );
1350  }
1351  catch ( QgsCsException & )
1352  {
1353  rect = mapSettings().fullExtent();
1354  }
1355 
1356  return rect;
1357 }
1358 
1359 void QgsMapCanvas::setExtent( const QgsRectangle &r, bool magnified )
1360 {
1361  QgsRectangle current = extent();
1362 
1363  if ( ( r == current ) && magnified )
1364  return;
1365 
1366  if ( r.isEmpty() )
1367  {
1368  if ( !mSettings.hasValidSettings() )
1369  {
1370  // we can't even just move the map center
1371  QgsDebugMsgLevel( QStringLiteral( "Empty extent - ignoring" ), 2 );
1372  return;
1373  }
1374 
1375  // ### QGIS 3: do not allow empty extent - require users to call setCenter() explicitly
1376  QgsDebugMsgLevel( QStringLiteral( "Empty extent - keeping old scale with new center!" ), 2 );
1377  setCenter( r.center() );
1378  }
1379  else
1380  {
1381  // If scale is locked we need to maintain the current scale, so we
1382  // - magnify and recenter the map
1383  // - restore locked scale
1384  if ( mScaleLocked && magnified )
1385  {
1386  ScaleRestorer restorer( this );
1387  const double ratio { extent().width() / extent().height() };
1388  const double factor { r.width() / r.height() > ratio ? extent().width() / r.width() : extent().height() / r.height() };
1389  const double scaleFactor { std::clamp( mSettings.magnificationFactor() * factor, QgsGuiUtils::CANVAS_MAGNIFICATION_MIN, QgsGuiUtils::CANVAS_MAGNIFICATION_MAX ) };
1390  const QgsPointXY newCenter { r.center() };
1391  mSettings.setMagnificationFactor( scaleFactor, &newCenter );
1392  emit magnificationChanged( scaleFactor );
1393  }
1394  else
1395  {
1396  mSettings.setExtent( r, magnified );
1397  }
1398  }
1399  emit extentsChanged();
1400  updateScale();
1401 
1402  //clear all extent items after current index
1403  for ( int i = mLastExtent.size() - 1; i > mLastExtentIndex; i-- )
1404  {
1405  mLastExtent.removeAt( i );
1406  }
1407 
1408  if ( !mLastExtent.isEmpty() && mLastExtent.last() != mSettings.extent() )
1409  {
1410  mLastExtent.append( mSettings.extent() );
1411  }
1412 
1413  // adjust history to no more than 100
1414  if ( mLastExtent.size() > 100 )
1415  {
1416  mLastExtent.removeAt( 0 );
1417  }
1418 
1419  // the last item is the current extent
1420  mLastExtentIndex = mLastExtent.size() - 1;
1421 
1422  // update controls' enabled state
1423  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
1424  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
1425 }
1426 
1428 {
1429  QgsRectangle canvasExtent = extent;
1430  if ( extent.crs() != mapSettings().destinationCrs() )
1431  {
1432  QgsCoordinateTransform ct( extent.crs(), mapSettings().destinationCrs(), QgsProject::instance() );
1434  canvasExtent = ct.transformBoundingBox( extent );
1435 
1436  if ( canvasExtent.isEmpty() )
1437  {
1438  return false;
1439  }
1440  }
1441 
1442  setExtent( canvasExtent, true );
1443  return true;
1444 }
1445 
1447 {
1448  const QgsRectangle r = mapSettings().extent();
1449  const double xMin = center.x() - r.width() / 2.0;
1450  const double yMin = center.y() - r.height() / 2.0;
1451  const QgsRectangle rect(
1452  xMin, yMin,
1453  xMin + r.width(), yMin + r.height()
1454  );
1455  if ( ! rect.isEmpty() )
1456  {
1457  setExtent( rect, true );
1458  }
1459 } // setCenter
1460 
1462 {
1464  return r.center();
1465 }
1466 
1467 QgsPointXY QgsMapCanvas::cursorPoint() const
1468 {
1469  return mCursorPoint;
1470 }
1471 
1473 {
1474  return mapSettings().rotation();
1475 } // rotation
1476 
1477 void QgsMapCanvas::setRotation( double degrees )
1478 {
1479  double current = rotation();
1480 
1481  if ( qgsDoubleNear( degrees, current ) )
1482  return;
1483 
1484  mSettings.setRotation( degrees );
1485  emit rotationChanged( degrees );
1486  emit extentsChanged(); // visible extent changes with rotation
1487 } // setRotation
1488 
1489 
1491 {
1492  emit scaleChanged( mapSettings().scale() );
1493 }
1494 
1496 {
1498  // If the full extent is an empty set, don't do the zoom
1499  if ( !extent.isEmpty() )
1500  {
1501  // Add a 5% margin around the full extent
1502  extent.scale( 1.05 );
1503  setExtent( extent );
1504  }
1505  refresh();
1506 }
1507 
1509 {
1511 
1512  // If the full extent is an empty set, don't do the zoom
1513  if ( !extent.isEmpty() )
1514  {
1515  // Add a 5% margin around the full extent
1516  extent.scale( 1.05 );
1517  setExtent( extent );
1518  }
1519  refresh();
1520 }
1521 
1523 {
1524  if ( mLastExtentIndex > 0 )
1525  {
1526  mLastExtentIndex--;
1527  mSettings.setExtent( mLastExtent[mLastExtentIndex] );
1528  emit extentsChanged();
1529  updateScale();
1530  refresh();
1531  // update controls' enabled state
1532  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
1533  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
1534  }
1535 
1536 } // zoomToPreviousExtent
1537 
1539 {
1540  if ( mLastExtentIndex < mLastExtent.size() - 1 )
1541  {
1542  mLastExtentIndex++;
1543  mSettings.setExtent( mLastExtent[mLastExtentIndex] );
1544  emit extentsChanged();
1545  updateScale();
1546  refresh();
1547  // update controls' enabled state
1548  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
1549  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
1550  }
1551 }// zoomToNextExtent
1552 
1554 {
1555  mLastExtent.clear(); // clear the zoom history list
1556  mLastExtent.append( mSettings.extent() ) ; // set the current extent in the list
1557  mLastExtentIndex = mLastExtent.size() - 1;
1558  // update controls' enabled state
1559  emit zoomLastStatusChanged( mLastExtentIndex > 0 );
1560  emit zoomNextStatusChanged( mLastExtentIndex < mLastExtent.size() - 1 );
1561 }// clearExtentHistory
1562 
1563 QgsRectangle QgsMapCanvas::optimalExtentForPointLayer( QgsVectorLayer *layer, const QgsPointXY &center, int scaleFactor )
1564 {
1565  QgsRectangle rect( center, center );
1566 
1567  if ( layer->geometryType() == QgsWkbTypes::PointGeometry )
1568  {
1569  QgsPointXY centerLayerCoordinates = mSettings.mapToLayerCoordinates( layer, center );
1570  QgsRectangle extentRect = mSettings.mapToLayerCoordinates( layer, extent() ).scaled( 1.0 / scaleFactor, &centerLayerCoordinates );
1572  QgsFeatureIterator fit = layer->getFeatures( req );
1573  QgsFeature f;
1574  QgsPointXY closestPoint;
1575  double closestSquaredDistance = pow( extentRect.width(), 2.0 ) + pow( extentRect.height(), 2.0 );
1576  bool pointFound = false;
1577  while ( fit.nextFeature( f ) )
1578  {
1579  QgsPointXY point = f.geometry().asPoint();
1580  double sqrDist = point.sqrDist( centerLayerCoordinates );
1581  if ( sqrDist > closestSquaredDistance || sqrDist < 4 * std::numeric_limits<double>::epsilon() )
1582  continue;
1583  pointFound = true;
1584  closestPoint = point;
1585  closestSquaredDistance = sqrDist;
1586  }
1587  if ( pointFound )
1588  {
1589  // combine selected point with closest point and scale this rect
1590  rect.combineExtentWith( mSettings.layerToMapCoordinates( layer, closestPoint ) );
1591  rect.scale( scaleFactor, &center );
1592  }
1593  }
1594  return rect;
1595 }
1596 
1598 {
1599  QgsTemporaryCursorOverride cursorOverride( Qt::WaitCursor );
1600 
1601  if ( !layer )
1602  {
1603  // use current layer by default
1604  layer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
1605  }
1606 
1607  if ( !layer || !layer->isSpatial() || layer->selectedFeatureCount() == 0 )
1608  return;
1609 
1610  QgsRectangle rect = layer->boundingBoxOfSelected();
1611  if ( rect.isNull() )
1612  {
1613  cursorOverride.release();
1614  emit messageEmitted( tr( "Cannot zoom to selected feature(s)" ), tr( "No extent could be determined." ), Qgis::MessageLevel::Warning );
1615  return;
1616  }
1617 
1618  rect = mapSettings().layerExtentToOutputExtent( layer, rect );
1619 
1620  // zoom in if point cannot be distinguished from others
1621  // also check that rect is empty, as it might not in case of multi points
1622  if ( layer->geometryType() == QgsWkbTypes::PointGeometry && rect.isEmpty() )
1623  {
1624  rect = optimalExtentForPointLayer( layer, rect.center() );
1625  }
1626  zoomToFeatureExtent( rect );
1627 }
1628 
1629 void QgsMapCanvas::zoomToSelected( const QList<QgsMapLayer *> &layers )
1630 {
1631  QgsRectangle rect;
1632  rect.setMinimal();
1633  QgsRectangle selectionExtent;
1634  selectionExtent.setMinimal();
1635 
1636  for ( QgsMapLayer *mapLayer : layers )
1637  {
1638  QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( mapLayer );
1639 
1640  if ( !layer || !layer->isSpatial() || layer->selectedFeatureCount() == 0 )
1641  continue;
1642 
1643  rect = layer->boundingBoxOfSelected();
1644 
1645  if ( rect.isNull() )
1646  continue;
1647 
1648  rect = mapSettings().layerExtentToOutputExtent( layer, rect );
1649 
1650  if ( layer->geometryType() == QgsWkbTypes::PointGeometry && rect.isEmpty() )
1651  rect = optimalExtentForPointLayer( layer, rect.center() );
1652 
1653  selectionExtent.combineExtentWith( rect );
1654  }
1655 
1656  if ( selectionExtent.isNull() )
1657  {
1658  emit messageEmitted( tr( "Cannot zoom to selected feature(s)" ), tr( "No extent could be determined." ), Qgis::MessageLevel::Warning );
1659  return;
1660  }
1661 
1662  zoomToFeatureExtent( selectionExtent );
1663 }
1664 
1666 {
1667  return mSettings.zRange();
1668 }
1669 
1671 {
1672  if ( zRange() == range )
1673  return;
1674 
1675  mSettings.setZRange( range );
1676 
1677  emit zRangeChanged();
1678 
1679  // we need to discard any previously cached images which are elevation aware, so that these will be updated when
1680  // the canvas is redrawn
1681  if ( !mJob )
1682  clearElevationCache();
1683 
1684  autoRefreshTriggered();
1685 }
1686 
1688 {
1689  // no selected features, only one selected point feature
1690  //or two point features with the same x- or y-coordinates
1691  if ( rect.isEmpty() )
1692  {
1693  // zoom in
1694  QgsPointXY c = rect.center();
1695  rect = extent();
1696  rect.scale( 1.0, &c );
1697  }
1698  //zoom to an area
1699  else
1700  {
1701  // Expand rect to give a bit of space around the selected
1702  // objects so as to keep them clear of the map boundaries
1703  // The same 5% should apply to all margins.
1704  rect.scale( 1.05 );
1705  }
1706 
1707  setExtent( rect );
1708  refresh();
1709 }
1710 
1712 {
1713  if ( !layer )
1714  {
1715  return;
1716  }
1717 
1718  QgsRectangle bbox;
1719  QString errorMsg;
1720  if ( boundingBoxOfFeatureIds( ids, layer, bbox, errorMsg ) )
1721  {
1722  if ( bbox.isEmpty() )
1723  {
1724  bbox = optimalExtentForPointLayer( layer, bbox.center() );
1725  }
1726  zoomToFeatureExtent( bbox );
1727  }
1728  else
1729  {
1730  emit messageEmitted( tr( "Zoom to feature id failed" ), errorMsg, Qgis::MessageLevel::Warning );
1731  }
1732 
1733 }
1734 
1735 void QgsMapCanvas::panToFeatureIds( QgsVectorLayer *layer, const QgsFeatureIds &ids, bool alwaysRecenter )
1736 {
1737  if ( !layer )
1738  {
1739  return;
1740  }
1741 
1742  QgsRectangle bbox;
1743  QString errorMsg;
1744  if ( boundingBoxOfFeatureIds( ids, layer, bbox, errorMsg ) )
1745  {
1746  if ( alwaysRecenter || !mapSettings().extent().contains( bbox ) )
1747  setCenter( bbox.center() );
1748  refresh();
1749  }
1750  else
1751  {
1752  emit messageEmitted( tr( "Pan to feature id failed" ), errorMsg, Qgis::MessageLevel::Warning );
1753  }
1754 }
1755 
1756 bool QgsMapCanvas::boundingBoxOfFeatureIds( const QgsFeatureIds &ids, QgsVectorLayer *layer, QgsRectangle &bbox, QString &errorMsg ) const
1757 {
1758  QgsFeatureIterator it = layer->getFeatures( QgsFeatureRequest().setFilterFids( ids ).setNoAttributes() );
1759  bbox.setMinimal();
1760  QgsFeature fet;
1761  int featureCount = 0;
1762  errorMsg.clear();
1763 
1764  while ( it.nextFeature( fet ) )
1765  {
1766  QgsGeometry geom = fet.geometry();
1767  if ( geom.isNull() )
1768  {
1769  errorMsg = tr( "Feature does not have a geometry" );
1770  }
1771  else if ( geom.constGet()->isEmpty() )
1772  {
1773  errorMsg = tr( "Feature geometry is empty" );
1774  }
1775  if ( !errorMsg.isEmpty() )
1776  {
1777  return false;
1778  }
1780  bbox.combineExtentWith( r );
1781  featureCount++;
1782  }
1783 
1784  if ( featureCount != ids.count() )
1785  {
1786  errorMsg = tr( "Feature not found" );
1787  return false;
1788  }
1789 
1790  return true;
1791 }
1792 
1794 {
1795  if ( !layer )
1796  {
1797  // use current layer by default
1798  layer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
1799  }
1800 
1801  if ( !layer || !layer->isSpatial() || layer->selectedFeatureCount() == 0 )
1802  return;
1803 
1804  QgsRectangle rect = layer->boundingBoxOfSelected();
1805  if ( rect.isNull() )
1806  {
1807  emit messageEmitted( tr( "Cannot pan to selected feature(s)" ), tr( "No extent could be determined." ), Qgis::MessageLevel::Warning );
1808  return;
1809  }
1810 
1811  rect = mapSettings().layerExtentToOutputExtent( layer, rect );
1812  setCenter( rect.center() );
1813  refresh();
1814 }
1815 
1816 void QgsMapCanvas::panToSelected( const QList<QgsMapLayer *> &layers )
1817 {
1818  QgsRectangle rect;
1819  rect.setMinimal();
1820  QgsRectangle selectionExtent;
1821  selectionExtent.setMinimal();
1822 
1823  for ( QgsMapLayer *mapLayer : layers )
1824  {
1825  QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( mapLayer );
1826 
1827  if ( !layer || !layer->isSpatial() || layer->selectedFeatureCount() == 0 )
1828  continue;
1829 
1830  rect = layer->boundingBoxOfSelected();
1831 
1832  if ( rect.isNull() )
1833  continue;
1834 
1835  rect = mapSettings().layerExtentToOutputExtent( layer, rect );
1836 
1837  if ( layer->geometryType() == QgsWkbTypes::PointGeometry && rect.isEmpty() )
1838  rect = optimalExtentForPointLayer( layer, rect.center() );
1839 
1840  selectionExtent.combineExtentWith( rect );
1841  }
1842 
1843  if ( selectionExtent.isNull() )
1844  {
1845  emit messageEmitted( tr( "Cannot pan to selected feature(s)" ), tr( "No extent could be determined." ), Qgis::MessageLevel::Warning );
1846  return;
1847  }
1848 
1849  setCenter( selectionExtent.center() );
1850  refresh();
1851 }
1852 
1854  const QColor &color1, const QColor &color2,
1855  int flashes, int duration )
1856 {
1857  if ( !layer )
1858  {
1859  return;
1860  }
1861 
1862  QList< QgsGeometry > geoms;
1863 
1864  QgsFeatureIterator it = layer->getFeatures( QgsFeatureRequest().setFilterFids( ids ).setNoAttributes() );
1865  QgsFeature fet;
1866  while ( it.nextFeature( fet ) )
1867  {
1868  if ( !fet.hasGeometry() )
1869  continue;
1870  geoms << fet.geometry();
1871  }
1872 
1873  flashGeometries( geoms, layer->crs(), color1, color2, flashes, duration );
1874 }
1875 
1876 void QgsMapCanvas::flashGeometries( const QList<QgsGeometry> &geometries, const QgsCoordinateReferenceSystem &crs, const QColor &color1, const QColor &color2, int flashes, int duration )
1877 {
1878  if ( geometries.isEmpty() )
1879  return;
1880 
1881  QgsWkbTypes::GeometryType geomType = QgsWkbTypes::geometryType( geometries.at( 0 ).wkbType() );
1882  QgsRubberBand *rb = new QgsRubberBand( this, geomType );
1883  for ( const QgsGeometry &geom : geometries )
1884  rb->addGeometry( geom, crs, false );
1885  rb->updatePosition();
1886  rb->update();
1887 
1888  if ( geomType == QgsWkbTypes::LineGeometry || geomType == QgsWkbTypes::PointGeometry )
1889  {
1890  rb->setWidth( 2 );
1891  rb->setSecondaryStrokeColor( QColor( 255, 255, 255 ) );
1892  }
1893  if ( geomType == QgsWkbTypes::PointGeometry )
1895 
1896  QColor startColor = color1;
1897  if ( !startColor.isValid() )
1898  {
1899  if ( geomType == QgsWkbTypes::PolygonGeometry )
1900  {
1901  startColor = rb->fillColor();
1902  }
1903  else
1904  {
1905  startColor = rb->strokeColor();
1906  }
1907  startColor.setAlpha( 255 );
1908  }
1909  QColor endColor = color2;
1910  if ( !endColor.isValid() )
1911  {
1912  endColor = startColor;
1913  endColor.setAlpha( 0 );
1914  }
1915 
1916 
1917  QVariantAnimation *animation = new QVariantAnimation( this );
1918  connect( animation, &QVariantAnimation::finished, this, [animation, rb]
1919  {
1920  animation->deleteLater();
1921  delete rb;
1922  } );
1923  connect( animation, &QPropertyAnimation::valueChanged, this, [rb, geomType]( const QVariant & value )
1924  {
1925  QColor c = value.value<QColor>();
1926  if ( geomType == QgsWkbTypes::PolygonGeometry )
1927  {
1928  rb->setFillColor( c );
1929  }
1930  else
1931  {
1932  rb->setStrokeColor( c );
1933  QColor c = rb->secondaryStrokeColor();
1934  c.setAlpha( c.alpha() );
1935  rb->setSecondaryStrokeColor( c );
1936  }
1937  rb->update();
1938  } );
1939 
1940  animation->setDuration( duration * flashes );
1941  animation->setStartValue( endColor );
1942  double midStep = 0.2 / flashes;
1943  for ( int i = 0; i < flashes; ++i )
1944  {
1945  double start = static_cast< double >( i ) / flashes;
1946  animation->setKeyValueAt( start + midStep, startColor );
1947  double end = static_cast< double >( i + 1 ) / flashes;
1948  if ( !qgsDoubleNear( end, 1.0 ) )
1949  animation->setKeyValueAt( end, endColor );
1950  }
1951  animation->setEndValue( endColor );
1952  animation->start();
1953 }
1954 
1955 void QgsMapCanvas::keyPressEvent( QKeyEvent *e )
1956 {
1957  if ( mCanvasProperties->mouseButtonDown || mCanvasProperties->panSelectorDown )
1958  {
1959  emit keyPressed( e );
1960  return;
1961  }
1962 
1963  // Don't want to interfer with mouse events
1964  if ( ! mCanvasProperties->mouseButtonDown )
1965  {
1966  // this is backwards, but we can't change now without breaking api because
1967  // forever QgsMapTools have had to explicitly mark events as ignored in order to
1968  // indicate that they've consumed the event and that the default behavior should not
1969  // be applied..!
1970  e->accept();
1971  if ( mMapTool )
1972  {
1973  mMapTool->keyPressEvent( e );
1974  if ( !e->isAccepted() ) // map tool consumed event
1975  return;
1976  }
1977 
1978  QgsRectangle currentExtent = mapSettings().visibleExtent();
1979  double dx = std::fabs( currentExtent.width() / 4 );
1980  double dy = std::fabs( currentExtent.height() / 4 );
1981 
1982  switch ( e->key() )
1983  {
1984  case Qt::Key_Left:
1985  QgsDebugMsgLevel( QStringLiteral( "Pan left" ), 2 );
1986  setCenter( center() - QgsVector( dx, 0 ).rotateBy( rotation() * M_PI / 180.0 ) );
1987  refresh();
1988  break;
1989 
1990  case Qt::Key_Right:
1991  QgsDebugMsgLevel( QStringLiteral( "Pan right" ), 2 );
1992  setCenter( center() + QgsVector( dx, 0 ).rotateBy( rotation() * M_PI / 180.0 ) );
1993  refresh();
1994  break;
1995 
1996  case Qt::Key_Up:
1997  QgsDebugMsgLevel( QStringLiteral( "Pan up" ), 2 );
1998  setCenter( center() + QgsVector( 0, dy ).rotateBy( rotation() * M_PI / 180.0 ) );
1999  refresh();
2000  break;
2001 
2002  case Qt::Key_Down:
2003  QgsDebugMsgLevel( QStringLiteral( "Pan down" ), 2 );
2004  setCenter( center() - QgsVector( 0, dy ).rotateBy( rotation() * M_PI / 180.0 ) );
2005  refresh();
2006  break;
2007 
2008  case Qt::Key_Space:
2009  QgsDebugMsgLevel( QStringLiteral( "Pressing pan selector" ), 2 );
2010 
2011  //mCanvasProperties->dragging = true;
2012  if ( ! e->isAutoRepeat() )
2013  {
2014  mTemporaryCursorOverride.reset( new QgsTemporaryCursorOverride( Qt::ClosedHandCursor ) );
2015  mCanvasProperties->panSelectorDown = true;
2016  panActionStart( mCanvasProperties->mouseLastXY );
2017  }
2018  break;
2019 
2020  case Qt::Key_PageUp:
2021  QgsDebugMsgLevel( QStringLiteral( "Zoom in" ), 2 );
2022  zoomIn();
2023  break;
2024 
2025  case Qt::Key_PageDown:
2026  QgsDebugMsgLevel( QStringLiteral( "Zoom out" ), 2 );
2027  zoomOut();
2028  break;
2029 
2030 #if 0
2031  case Qt::Key_P:
2032  mUseParallelRendering = !mUseParallelRendering;
2033  refresh();
2034  break;
2035 
2036  case Qt::Key_S:
2037  mDrawRenderingStats = !mDrawRenderingStats;
2038  refresh();
2039  break;
2040 #endif
2041 
2042  default:
2043  // Pass it on
2044  if ( !mMapTool )
2045  {
2046  e->ignore();
2047  QgsDebugMsgLevel( "Ignoring key: " + QString::number( e->key() ), 2 );
2048  }
2049  }
2050  }
2051 
2052  emit keyPressed( e );
2053 }
2054 
2055 void QgsMapCanvas::keyReleaseEvent( QKeyEvent *e )
2056 {
2057  QgsDebugMsgLevel( QStringLiteral( "keyRelease event" ), 2 );
2058 
2059  switch ( e->key() )
2060  {
2061  case Qt::Key_Space:
2062  if ( !e->isAutoRepeat() && mCanvasProperties->panSelectorDown )
2063  {
2064  QgsDebugMsgLevel( QStringLiteral( "Releasing pan selector" ), 2 );
2065  mTemporaryCursorOverride.reset();
2066  mCanvasProperties->panSelectorDown = false;
2067  panActionEnd( mCanvasProperties->mouseLastXY );
2068  }
2069  break;
2070 
2071  default:
2072  // Pass it on
2073  if ( mMapTool )
2074  {
2075  mMapTool->keyReleaseEvent( e );
2076  }
2077  else e->ignore();
2078 
2079  QgsDebugMsgLevel( "Ignoring key release: " + QString::number( e->key() ), 2 );
2080  }
2081 
2082  emit keyReleased( e );
2083 
2084 } //keyReleaseEvent()
2085 
2086 
2088 {
2089  // call handler of current map tool
2090  if ( mMapTool )
2091  {
2092  std::unique_ptr<QgsMapMouseEvent> me( new QgsMapMouseEvent( this, e ) );
2093  mMapTool->canvasDoubleClickEvent( me.get() );
2094  }
2095 }// mouseDoubleClickEvent
2096 
2097 
2098 void QgsMapCanvas::beginZoomRect( QPoint pos )
2099 {
2100  mZoomRect.setRect( 0, 0, 0, 0 );
2101  mTemporaryCursorOverride.reset( new QgsTemporaryCursorOverride( mZoomCursor ) );
2102  mZoomDragging = true;
2103  mZoomRubberBand.reset( new QgsRubberBand( this, QgsWkbTypes::PolygonGeometry ) );
2104  QColor color( Qt::blue );
2105  color.setAlpha( 63 );
2106  mZoomRubberBand->setColor( color );
2107  mZoomRect.setTopLeft( pos );
2108 }
2109 
2110 void QgsMapCanvas::stopZoomRect()
2111 {
2112  if ( mZoomDragging )
2113  {
2114  mZoomDragging = false;
2115  mZoomRubberBand.reset( nullptr );
2116  mTemporaryCursorOverride.reset();
2117  }
2118 }
2119 
2120 void QgsMapCanvas::endZoomRect( QPoint pos )
2121 {
2122  stopZoomRect();
2123 
2124  // store the rectangle
2125  mZoomRect.setRight( pos.x() );
2126  mZoomRect.setBottom( pos.y() );
2127 
2128  //account for bottom right -> top left dragging
2129  mZoomRect = mZoomRect.normalized();
2130 
2131  if ( mZoomRect.width() < 5 && mZoomRect.height() < 5 )
2132  {
2133  //probably a mistake - would result in huge zoom!
2134  return;
2135  }
2136 
2137  // set center and zoom
2138  const QSize &zoomRectSize = mZoomRect.size();
2139  const QSize &canvasSize = mSettings.outputSize();
2140  double sfx = static_cast< double >( zoomRectSize.width() ) / canvasSize.width();
2141  double sfy = static_cast< double >( zoomRectSize.height() ) / canvasSize.height();
2142  double sf = std::max( sfx, sfy );
2143 
2144  QgsPointXY c = mSettings.mapToPixel().toMapCoordinates( mZoomRect.center() );
2145 
2146  zoomByFactor( sf, &c );
2147  refresh();
2148 }
2149 
2150 void QgsMapCanvas::startPan()
2151 {
2152  if ( !mCanvasProperties->panSelectorDown )
2153  {
2154  mCanvasProperties->panSelectorDown = true;
2155  mTemporaryCursorOverride.reset( new QgsTemporaryCursorOverride( Qt::ClosedHandCursor ) );
2156  panActionStart( mCanvasProperties->mouseLastXY );
2157  }
2158 }
2159 
2160 void QgsMapCanvas::stopPan()
2161 {
2162  if ( mCanvasProperties->panSelectorDown )
2163  {
2164  mCanvasProperties->panSelectorDown = false;
2165  mTemporaryCursorOverride.reset();
2166  panActionEnd( mCanvasProperties->mouseLastXY );
2167  }
2168 }
2169 
2170 void QgsMapCanvas::mousePressEvent( QMouseEvent *e )
2171 {
2172  // use shift+middle mouse button for zooming, map tools won't receive any events in that case
2173  if ( e->button() == Qt::MiddleButton &&
2174  e->modifiers() & Qt::ShiftModifier )
2175  {
2176  beginZoomRect( e->pos() );
2177  return;
2178  }
2179  //use middle mouse button for panning, map tools won't receive any events in that case
2180  else if ( e->button() == Qt::MiddleButton )
2181  {
2182  startPan();
2183  }
2184  else
2185  {
2186  // If doing a middle-button-click, followed by a right-button-click,
2187  // cancel the pan or zoomRect action started above.
2188  stopPan();
2189  stopZoomRect();
2190 
2191  // call handler of current map tool
2192  if ( mMapTool )
2193  {
2194  if ( mMapTool->flags() & QgsMapTool::AllowZoomRect && e->button() == Qt::LeftButton
2195  && e->modifiers() & Qt::ShiftModifier )
2196  {
2197  beginZoomRect( e->pos() );
2198  return;
2199  }
2200  else if ( mMapTool->flags() & QgsMapTool::ShowContextMenu && e->button() == Qt::RightButton )
2201  {
2202  std::unique_ptr<QgsMapMouseEvent> me( new QgsMapMouseEvent( this, e ) );
2203  showContextMenu( me.get() );
2204  return;
2205  }
2206  else
2207  {
2208  std::unique_ptr<QgsMapMouseEvent> me( new QgsMapMouseEvent( this, e ) );
2209  mMapTool->canvasPressEvent( me.get() );
2210  }
2211  }
2212  }
2213 
2214  if ( mCanvasProperties->panSelectorDown )
2215  {
2216  return;
2217  }
2218 
2219  mCanvasProperties->mouseButtonDown = true;
2220  mCanvasProperties->rubberStartPoint = e->pos();
2221 }
2222 
2223 void QgsMapCanvas::mouseReleaseEvent( QMouseEvent *e )
2224 {
2225  // if using shift+middle mouse button for zooming, end zooming and return
2226  if ( mZoomDragging &&
2227  e->button() == Qt::MiddleButton )
2228  {
2229  endZoomRect( e->pos() );
2230  return;
2231  }
2232  //use middle mouse button for panning, map tools won't receive any events in that case
2233  else if ( e->button() == Qt::MiddleButton )
2234  {
2235  stopPan();
2236  }
2237  else if ( e->button() == Qt::BackButton )
2238  {
2240  return;
2241  }
2242  else if ( e->button() == Qt::ForwardButton )
2243  {
2244  zoomToNextExtent();
2245  return;
2246  }
2247  else
2248  {
2249  if ( mZoomDragging && e->button() == Qt::LeftButton )
2250  {
2251  endZoomRect( e->pos() );
2252  return;
2253  }
2254 
2255  // call handler of current map tool
2256  if ( mMapTool )
2257  {
2258  // right button was pressed in zoom tool? return to previous non zoom tool
2259  if ( e->button() == Qt::RightButton && mMapTool->flags() & QgsMapTool::Transient )
2260  {
2261  QgsDebugMsgLevel( QStringLiteral( "Right click in map tool zoom or pan, last tool is %1." ).arg(
2262  mLastNonZoomMapTool ? QStringLiteral( "not null" ) : QStringLiteral( "null" ) ), 2 );
2263 
2264  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( mCurrentLayer );
2265 
2266  // change to older non-zoom tool
2267  if ( mLastNonZoomMapTool
2268  && ( !( mLastNonZoomMapTool->flags() & QgsMapTool::EditTool )
2269  || ( vlayer && vlayer->isEditable() ) ) )
2270  {
2271  QgsMapTool *t = mLastNonZoomMapTool;
2272  mLastNonZoomMapTool = nullptr;
2273  setMapTool( t );
2274  }
2275  return;
2276  }
2277  std::unique_ptr<QgsMapMouseEvent> me( new QgsMapMouseEvent( this, e ) );
2278  mMapTool->canvasReleaseEvent( me.get() );
2279  }
2280  }
2281 
2282 
2283  mCanvasProperties->mouseButtonDown = false;
2284 
2285  if ( mCanvasProperties->panSelectorDown )
2286  return;
2287 
2288 }
2289 
2290 void QgsMapCanvas::resizeEvent( QResizeEvent *e )
2291 {
2292  QGraphicsView::resizeEvent( e );
2293  mResizeTimer->start( 500 ); // in charge of refreshing canvas
2294 
2295  double oldScale = mSettings.scale();
2296  QSize lastSize = viewport()->size();
2297  mSettings.setOutputSize( lastSize );
2298 
2299  mScene->setSceneRect( QRectF( 0, 0, lastSize.width(), lastSize.height() ) );
2300 
2301  moveCanvasContents( true );
2302 
2303  if ( mScaleLocked )
2304  {
2305  double scaleFactor = oldScale / mSettings.scale();
2306  QgsRectangle r = mSettings.extent();
2307  QgsPointXY center = r.center();
2308  r.scale( scaleFactor, &center );
2309  mSettings.setExtent( r );
2310  }
2311  else
2312  {
2313  updateScale();
2314  }
2315 
2316  emit extentsChanged();
2317 }
2318 
2319 void QgsMapCanvas::paintEvent( QPaintEvent *e )
2320 {
2321  // no custom event handling anymore
2322 
2323  QGraphicsView::paintEvent( e );
2324 } // paintEvent
2325 
2327 {
2328  if ( mBlockItemPositionUpdates )
2329  return;
2330 
2331  const QList<QGraphicsItem *> items = mScene->items();
2332  for ( QGraphicsItem *gi : items )
2333  {
2334  QgsMapCanvasItem *item = dynamic_cast<QgsMapCanvasItem *>( gi );
2335 
2336  if ( item )
2337  {
2338  item->updatePosition();
2339  }
2340  }
2341 }
2342 
2343 
2344 void QgsMapCanvas::wheelEvent( QWheelEvent *e )
2345 {
2346  // Zoom the map canvas in response to a mouse wheel event. Moving the
2347  // wheel forward (away) from the user zooms in
2348 
2349  QgsDebugMsgLevel( "Wheel event delta " + QString::number( e->angleDelta().y() ), 2 );
2350 
2351  if ( mMapTool )
2352  {
2353  mMapTool->wheelEvent( e );
2354  if ( e->isAccepted() )
2355  return;
2356  }
2357 
2358  if ( e->angleDelta().y() == 0 )
2359  {
2360  e->accept();
2361  return;
2362  }
2363 
2364  double zoomFactor = e->angleDelta().y() > 0 ? 1. / zoomInFactor() : zoomOutFactor();
2365 
2366  // "Normal" mouse have an angle delta of 120, precision mouses provide data faster, in smaller steps
2367  zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 120.0 * std::fabs( e->angleDelta().y() );
2368 
2369  if ( e->modifiers() & Qt::ControlModifier )
2370  {
2371  //holding ctrl while wheel zooming results in a finer zoom
2372  zoomFactor = 1.0 + ( zoomFactor - 1.0 ) / 20.0;
2373  }
2374 
2375  double signedWheelFactor = e->angleDelta().y() > 0 ? 1 / zoomFactor : zoomFactor;
2376 
2377  // zoom map to mouse cursor by scaling
2378  QgsPointXY oldCenter = center();
2379 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
2380  QgsPointXY mousePos( getCoordinateTransform()->toMapCoordinates( e->pos().x(), e->pos().y() ) );
2381 #else
2382  QgsPointXY mousePos( getCoordinateTransform()->toMapCoordinates( e->position().x(), e->position().y() ) );
2383 #endif
2384  QgsPointXY newCenter( mousePos.x() + ( ( oldCenter.x() - mousePos.x() ) * signedWheelFactor ),
2385  mousePos.y() + ( ( oldCenter.y() - mousePos.y() ) * signedWheelFactor ) );
2386 
2387  zoomByFactor( signedWheelFactor, &newCenter );
2388  e->accept();
2389 }
2390 
2391 void QgsMapCanvas::setWheelFactor( double factor )
2392 {
2393  mWheelZoomFactor = factor;
2394 }
2395 
2397 {
2398  // magnification is alreday handled in zoomByFactor
2400 }
2401 
2403 {
2404  // magnification is alreday handled in zoomByFactor
2406 }
2407 
2408 void QgsMapCanvas::zoomScale( double newScale, bool ignoreScaleLock )
2409 {
2410  zoomByFactor( newScale / scale(), nullptr, ignoreScaleLock );
2411 }
2412 
2413 void QgsMapCanvas::zoomWithCenter( int x, int y, bool zoomIn )
2414 {
2415  double scaleFactor = ( zoomIn ? zoomInFactor() : zoomOutFactor() );
2416 
2417  // transform the mouse pos to map coordinates
2419 
2420  if ( mScaleLocked )
2421  {
2422  ScaleRestorer restorer( this );
2424  }
2425  else
2426  {
2428  r.scale( scaleFactor, &center );
2429  setExtent( r, true );
2430  refresh();
2431  }
2432 }
2433 
2434 void QgsMapCanvas::setScaleLocked( bool isLocked )
2435 {
2436  if ( mScaleLocked != isLocked )
2437  {
2438  mScaleLocked = isLocked;
2439  emit scaleLockChanged( mScaleLocked );
2440  }
2441 }
2442 
2443 void QgsMapCanvas::mouseMoveEvent( QMouseEvent *e )
2444 {
2445  mCanvasProperties->mouseLastXY = e->pos();
2446 
2447  if ( mCanvasProperties->panSelectorDown )
2448  {
2449  panAction( e );
2450  }
2451  else if ( mZoomDragging )
2452  {
2453  mZoomRect.setBottomRight( e->pos() );
2454  mZoomRubberBand->setToCanvasRectangle( mZoomRect );
2455  mZoomRubberBand->show();
2456  }
2457  else
2458  {
2459  // call handler of current map tool
2460  if ( mMapTool )
2461  {
2462  std::unique_ptr<QgsMapMouseEvent> me( new QgsMapMouseEvent( this, e ) );
2463  mMapTool->canvasMoveEvent( me.get() );
2464  }
2465  }
2466 
2467  // show x y on status bar (if we are mid pan operation, then the cursor point hasn't changed!)
2468  if ( !panOperationInProgress() )
2469  {
2470  mCursorPoint = getCoordinateTransform()->toMapCoordinates( mCanvasProperties->mouseLastXY );
2471  emit xyCoordinates( mCursorPoint );
2472  }
2473 }
2474 
2475 void QgsMapCanvas::setMapTool( QgsMapTool *tool, bool clean )
2476 {
2477  if ( !tool )
2478  return;
2479 
2480  if ( mMapTool )
2481  {
2482  if ( clean )
2483  mMapTool->clean();
2484 
2485  disconnect( mMapTool, &QObject::destroyed, this, &QgsMapCanvas::mapToolDestroyed );
2486  mMapTool->deactivate();
2487  }
2488 
2489  if ( ( tool->flags() & QgsMapTool::Transient )
2490  && mMapTool && !( mMapTool->flags() & QgsMapTool::Transient ) )
2491  {
2492  // if zoom or pan tool will be active, save old tool
2493  // to bring it back on right click
2494  // (but only if it wasn't also zoom or pan tool)
2495  mLastNonZoomMapTool = mMapTool;
2496  }
2497  else
2498  {
2499  mLastNonZoomMapTool = nullptr;
2500  }
2501 
2502  QgsMapTool *oldTool = mMapTool;
2503 
2504  // set new map tool and activate it
2505  mMapTool = tool;
2506  emit mapToolSet( mMapTool, oldTool );
2507  if ( mMapTool )
2508  {
2509  connect( mMapTool, &QObject::destroyed, this, &QgsMapCanvas::mapToolDestroyed );
2510  mMapTool->activate();
2511  }
2512 
2513 } // setMapTool
2514 
2516 {
2517  if ( mMapTool && mMapTool == tool )
2518  {
2519  disconnect( mMapTool, &QObject::destroyed, this, &QgsMapCanvas::mapToolDestroyed );
2520  QgsMapTool *oldTool = mMapTool;
2521  mMapTool = nullptr;
2522  oldTool->deactivate();
2523  emit mapToolSet( nullptr, oldTool );
2524  setCursor( Qt::ArrowCursor );
2525  }
2526 
2527  if ( mLastNonZoomMapTool && mLastNonZoomMapTool == tool )
2528  {
2529  mLastNonZoomMapTool = nullptr;
2530  }
2531 }
2532 
2534 {
2535  mProject = project;
2536 }
2537 
2538 void QgsMapCanvas::setCanvasColor( const QColor &color )
2539 {
2540  if ( canvasColor() == color )
2541  return;
2542 
2543  // background of map's pixmap
2544  mSettings.setBackgroundColor( color );
2545 
2546  // background of the QGraphicsView
2547  QBrush bgBrush( color );
2548  setBackgroundBrush( bgBrush );
2549 #if 0
2550  QPalette palette;
2551  palette.setColor( backgroundRole(), color );
2552  setPalette( palette );
2553 #endif
2554 
2555  // background of QGraphicsScene
2556  mScene->setBackgroundBrush( bgBrush );
2557 
2558  refresh();
2559 
2560  emit canvasColorChanged();
2561 }
2562 
2564 {
2565  return mScene->backgroundBrush().color();
2566 }
2567 
2568 void QgsMapCanvas::setSelectionColor( const QColor &color )
2569 {
2570  if ( mSettings.selectionColor() == color )
2571  return;
2572 
2573  mSettings.setSelectionColor( color );
2574 
2575  if ( mCache )
2576  {
2577  bool hasSelectedFeatures = false;
2578  const auto layers = mSettings.layers();
2579  for ( QgsMapLayer *layer : layers )
2580  {
2581  QgsVectorLayer *vlayer = qobject_cast<QgsVectorLayer *>( layer );
2582  if ( vlayer && vlayer->selectedFeatureCount() )
2583  {
2584  hasSelectedFeatures = true;
2585  break;
2586  }
2587  }
2588 
2589  if ( hasSelectedFeatures )
2590  {
2591  mCache->clear();
2592  refresh();
2593  }
2594  }
2595 }
2596 
2598 {
2599  return mSettings.selectionColor();
2600 }
2601 
2603 {
2604  return mapSettings().layers().size();
2605 }
2606 
2607 QList<QgsMapLayer *> QgsMapCanvas::layers( bool expandGroupLayers ) const
2608 {
2609  return mapSettings().layers( expandGroupLayers );
2610 }
2611 
2613 {
2614  // called when a layer has changed visibility setting
2615  refresh();
2616 }
2617 
2618 void QgsMapCanvas::freeze( bool frozen )
2619 {
2620  mFrozen = frozen;
2621 }
2622 
2624 {
2625  return mFrozen;
2626 }
2627 
2629 {
2630  return mapSettings().mapUnitsPerPixel();
2631 }
2632 
2634 {
2635  return mapSettings().mapUnits();
2636 }
2637 
2638 QMap<QString, QString> QgsMapCanvas::layerStyleOverrides() const
2639 {
2640  return mSettings.layerStyleOverrides();
2641 }
2642 
2643 void QgsMapCanvas::setLayerStyleOverrides( const QMap<QString, QString> &overrides )
2644 {
2645  if ( overrides == mSettings.layerStyleOverrides() )
2646  return;
2647 
2648  mSettings.setLayerStyleOverrides( overrides );
2649  clearCache();
2651 }
2652 
2653 void QgsMapCanvas::setTheme( const QString &theme )
2654 {
2655  if ( mTheme == theme )
2656  return;
2657 
2658  clearCache();
2659  if ( theme.isEmpty() || !QgsProject::instance()->mapThemeCollection()->hasMapTheme( theme ) )
2660  {
2661  mTheme.clear();
2662  mSettings.setLayerStyleOverrides( QMap< QString, QString>() );
2663  setLayers( QgsProject::instance()->mapThemeCollection()->masterVisibleLayers() );
2664  emit themeChanged( QString() );
2665  }
2666  else
2667  {
2668  mTheme = theme;
2669  setLayersPrivate( QgsProject::instance()->mapThemeCollection()->mapThemeVisibleLayers( mTheme ) );
2670  emit themeChanged( theme );
2671  }
2672 }
2673 
2675 {
2676  mRenderFlag = flag;
2677 
2678  if ( mRenderFlag )
2679  {
2680  refresh();
2681  }
2682  else
2683  stopRendering();
2684 }
2685 
2686 #if 0
2687 void QgsMapCanvas::connectNotify( const char *signal )
2688 {
2689  Q_UNUSED( signal )
2690  QgsDebugMsg( "QgsMapCanvas connected to " + QString( signal ) );
2691 } //connectNotify
2692 #endif
2693 
2694 void QgsMapCanvas::layerRepaintRequested( bool deferred )
2695 {
2696  if ( !deferred )
2697  refresh();
2698 }
2699 
2700 void QgsMapCanvas::autoRefreshTriggered()
2701 {
2702  if ( mJob )
2703  {
2704  // canvas is currently being redrawn, so we defer the last requested
2705  // auto refresh until current rendering job finishes
2706  mRefreshAfterJob = true;
2707  return;
2708  }
2709 
2710  refresh();
2711 }
2712 
2713 void QgsMapCanvas::updateAutoRefreshTimer()
2714 {
2715  // min auto refresh interval stores the smallest interval between layer auto refreshes. We automatically
2716  // trigger a map refresh on this minimum interval
2717  int minAutoRefreshInterval = -1;
2718  const auto layers = mSettings.layers();
2719  for ( QgsMapLayer *layer : layers )
2720  {
2721  int layerRefreshInterval = 0;
2722 
2724  {
2725  layerRefreshInterval = layer->autoRefreshInterval();
2726  }
2727  else if ( QgsVectorLayer *vectorLayer = qobject_cast< QgsVectorLayer * >( layer ) )
2728  {
2729  if ( const QgsFeatureRenderer *renderer = vectorLayer->renderer() )
2730  {
2731  const double rendererRefreshRate = QgsSymbolLayerUtils::rendererFrameRate( renderer );
2732  if ( rendererRefreshRate > 0 )
2733  {
2734  layerRefreshInterval = 1000 / rendererRefreshRate;
2735  }
2736  }
2737  }
2738 
2739  if ( layerRefreshInterval == 0 )
2740  continue;
2741 
2742  minAutoRefreshInterval = minAutoRefreshInterval > 0 ? std::min( layerRefreshInterval, minAutoRefreshInterval ) : layerRefreshInterval;
2743  }
2744 
2745  if ( minAutoRefreshInterval > 0 )
2746  {
2747  mAutoRefreshTimer.setInterval( minAutoRefreshInterval );
2748  mAutoRefreshTimer.start();
2749  }
2750  else
2751  {
2752  mAutoRefreshTimer.stop();
2753  }
2754 }
2755 
2756 void QgsMapCanvas::projectThemesChanged()
2757 {
2758  if ( mTheme.isEmpty() )
2759  return;
2760 
2761  if ( !QgsProject::instance()->mapThemeCollection()->hasMapTheme( mTheme ) )
2762  {
2763  // theme has been removed - stop following
2764  setTheme( QString() );
2765  }
2766 
2767 }
2768 
2770 {
2771  return mMapTool;
2772 }
2773 
2775 {
2776  return mProject;
2777 }
2778 
2779 void QgsMapCanvas::panActionEnd( QPoint releasePoint )
2780 {
2781  // move map image and other items to standard position
2782  moveCanvasContents( true ); // true means reset
2783 
2784  // use start and end box points to calculate the extent
2785  QgsPointXY start = getCoordinateTransform()->toMapCoordinates( mCanvasProperties->rubberStartPoint );
2786  QgsPointXY end = getCoordinateTransform()->toMapCoordinates( releasePoint );
2787 
2788  // modify the center
2789  double dx = end.x() - start.x();
2790  double dy = end.y() - start.y();
2791  QgsPointXY c = center();
2792  c.set( c.x() - dx, c.y() - dy );
2793  setCenter( c );
2794 
2795  refresh();
2796 }
2797 
2798 void QgsMapCanvas::panActionStart( QPoint releasePoint )
2799 {
2800  mCanvasProperties->rubberStartPoint = releasePoint;
2801 
2802  mDa = QgsDistanceArea();
2803  mDa.setEllipsoid( QgsProject::instance()->ellipsoid() );
2804  mDa.setSourceCrs( mapSettings().destinationCrs(), QgsProject::instance()->transformContext() );
2805 }
2806 
2807 void QgsMapCanvas::panAction( QMouseEvent *e )
2808 {
2809  Q_UNUSED( e )
2810 
2811  QgsPointXY currentMapPoint = getCoordinateTransform()->toMapCoordinates( e->pos() );
2812  QgsPointXY startMapPoint = getCoordinateTransform()->toMapCoordinates( mCanvasProperties->rubberStartPoint );
2813  try
2814  {
2815  emit panDistanceBearingChanged( mDa.measureLine( currentMapPoint, startMapPoint ), mDa.lengthUnits(), mDa.bearing( currentMapPoint, startMapPoint ) * 180 / M_PI );
2816  }
2817  catch ( QgsCsException & )
2818  {}
2819 
2820  // move all map canvas items
2822 }
2823 
2825 {
2826  QPoint pnt( 0, 0 );
2827  if ( !reset )
2828  pnt += mCanvasProperties->mouseLastXY - mCanvasProperties->rubberStartPoint;
2829 
2830  setSceneRect( -pnt.x(), -pnt.y(), viewport()->size().width(), viewport()->size().height() );
2831 }
2832 
2833 void QgsMapCanvas::dropEvent( QDropEvent *event )
2834 {
2835  if ( QgsMimeDataUtils::isUriList( event->mimeData() ) )
2836  {
2838  bool allHandled = true;
2839  for ( const QgsMimeDataUtils::Uri &uri : lst )
2840  {
2841  bool handled = false;
2842  for ( QgsCustomDropHandler *handler : std::as_const( mDropHandlers ) )
2843  {
2844  if ( handler && handler->customUriProviderKey() == uri.providerKey )
2845  {
2846  if ( handler->handleCustomUriCanvasDrop( uri, this ) )
2847  {
2848  handled = true;
2849  break;
2850  }
2851  }
2852  }
2853  if ( !handled )
2854  allHandled = false;
2855  }
2856  if ( allHandled )
2857  event->accept();
2858  else
2859  event->ignore();
2860  }
2861  else
2862  {
2863  event->ignore();
2864  }
2865 }
2866 
2867 void QgsMapCanvas::showEvent( QShowEvent *event )
2868 {
2869  Q_UNUSED( event )
2870  updateDevicePixelFromScreen();
2871  // keep device pixel ratio up to date on screen or resolution change
2872  QWindow *l_window = window()->windowHandle();
2873  if ( l_window )
2874  {
2875  connect( l_window, &QWindow::screenChanged, this, [ = ]( QScreen * )
2876  {
2877  disconnect( mScreenDpiChangedConnection );
2878  QWindow *windowInLambda = window()->windowHandle();
2879  if ( windowInLambda )
2880  {
2881  mScreenDpiChangedConnection = connect( windowInLambda->screen(), &QScreen::physicalDotsPerInchChanged, this, &QgsMapCanvas::updateDevicePixelFromScreen );
2882  updateDevicePixelFromScreen();
2883  }
2884  } );
2885 
2886  mScreenDpiChangedConnection = connect( l_window->screen(), &QScreen::physicalDotsPerInchChanged, this, &QgsMapCanvas::updateDevicePixelFromScreen );
2887  }
2888 }
2889 
2891 {
2892  return mCanvasProperties->mouseLastXY;
2893 }
2894 
2895 void QgsMapCanvas::setPreviewModeEnabled( bool previewEnabled )
2896 {
2897  if ( !mPreviewEffect )
2898  {
2899  return;
2900  }
2901 
2902  mPreviewEffect->setEnabled( previewEnabled );
2903 }
2904 
2906 {
2907  if ( !mPreviewEffect )
2908  {
2909  return false;
2910  }
2911 
2912  return mPreviewEffect->isEnabled();
2913 }
2914 
2916 {
2917  if ( !mPreviewEffect )
2918  {
2919  return;
2920  }
2921 
2922  mPreviewEffect->setMode( mode );
2923 }
2924 
2926 {
2927  if ( !mPreviewEffect )
2928  {
2930  }
2931 
2932  return mPreviewEffect->mode();
2933 }
2934 
2936 {
2937  if ( !mSnappingUtils )
2938  {
2939  // associate a dummy instance, but better than null pointer
2940  QgsMapCanvas *c = const_cast<QgsMapCanvas *>( this );
2941  c->mSnappingUtils = new QgsMapCanvasSnappingUtils( c, c );
2942  }
2943  return mSnappingUtils;
2944 }
2945 
2947 {
2948  mSnappingUtils = utils;
2949 }
2950 
2951 void QgsMapCanvas::readProject( const QDomDocument &doc )
2952 {
2953  QgsProject *project = qobject_cast< QgsProject * >( sender() );
2954 
2955  QDomNodeList nodes = doc.elementsByTagName( QStringLiteral( "mapcanvas" ) );
2956  if ( nodes.count() )
2957  {
2958  QDomNode node = nodes.item( 0 );
2959 
2960  // Search the specific MapCanvas node using the name
2961  if ( nodes.count() > 1 )
2962  {
2963  for ( int i = 0; i < nodes.size(); ++i )
2964  {
2965  QDomElement elementNode = nodes.at( i ).toElement();
2966 
2967  if ( elementNode.hasAttribute( QStringLiteral( "name" ) ) && elementNode.attribute( QStringLiteral( "name" ) ) == objectName() )
2968  {
2969  node = nodes.at( i );
2970  break;
2971  }
2972  }
2973  }
2974 
2975  QgsMapSettings tmpSettings;
2976  tmpSettings.readXml( node );
2977  if ( objectName() != QLatin1String( "theMapCanvas" ) )
2978  {
2979  // never manually set the crs for the main canvas - this is instead connected to the project CRS
2980  setDestinationCrs( tmpSettings.destinationCrs() );
2981  }
2982  setExtent( tmpSettings.extent() );
2983  setRotation( tmpSettings.rotation() );
2985 
2986  clearExtentHistory(); // clear the extent history on project load
2987 
2988  QDomElement elem = node.toElement();
2989  if ( elem.hasAttribute( QStringLiteral( "theme" ) ) )
2990  {
2991  if ( QgsProject::instance()->mapThemeCollection()->hasMapTheme( elem.attribute( QStringLiteral( "theme" ) ) ) )
2992  {
2993  setTheme( elem.attribute( QStringLiteral( "theme" ) ) );
2994  }
2995  }
2996  setAnnotationsVisible( elem.attribute( QStringLiteral( "annotationsVisible" ), QStringLiteral( "1" ) ).toInt() );
2997 
2998  // restore canvas expression context
2999  const QDomNodeList scopeElements = elem.elementsByTagName( QStringLiteral( "expressionContextScope" ) );
3000  if ( scopeElements.size() > 0 )
3001  {
3002  const QDomElement scopeElement = scopeElements.at( 0 ).toElement();
3003  mExpressionContextScope.readXml( scopeElement, QgsReadWriteContext() );
3004  }
3005  }
3006  else
3007  {
3008  QgsDebugMsg( QStringLiteral( "Couldn't read mapcanvas information from project" ) );
3010  {
3012  }
3013 
3015  clearExtentHistory(); // clear the extent history on project load
3016  }
3017 }
3018 
3019 void QgsMapCanvas::writeProject( QDomDocument &doc )
3020 {
3021  // create node "mapcanvas" and call mMapRenderer->writeXml()
3022 
3023  QDomNodeList nl = doc.elementsByTagName( QStringLiteral( "qgis" ) );
3024  if ( !nl.count() )
3025  {
3026  QgsDebugMsg( QStringLiteral( "Unable to find qgis element in project file" ) );
3027  return;
3028  }
3029  QDomNode qgisNode = nl.item( 0 ); // there should only be one, so zeroth element OK
3030 
3031  QDomElement mapcanvasNode = doc.createElement( QStringLiteral( "mapcanvas" ) );
3032  mapcanvasNode.setAttribute( QStringLiteral( "name" ), objectName() );
3033  if ( !mTheme.isEmpty() )
3034  mapcanvasNode.setAttribute( QStringLiteral( "theme" ), mTheme );
3035  mapcanvasNode.setAttribute( QStringLiteral( "annotationsVisible" ), mAnnotationsVisible );
3036  qgisNode.appendChild( mapcanvasNode );
3037 
3038  mSettings.writeXml( mapcanvasNode, doc );
3039 
3040  // store canvas expression context
3041  QDomElement scopeElement = doc.createElement( QStringLiteral( "expressionContextScope" ) );
3042  QgsExpressionContextScope tmpScope( mExpressionContextScope );
3043  tmpScope.removeVariable( QStringLiteral( "atlas_featurenumber" ) );
3044  tmpScope.removeVariable( QStringLiteral( "atlas_pagename" ) );
3045  tmpScope.removeVariable( QStringLiteral( "atlas_feature" ) );
3046  tmpScope.removeVariable( QStringLiteral( "atlas_featureid" ) );
3047  tmpScope.removeVariable( QStringLiteral( "atlas_geometry" ) );
3048  tmpScope.writeXml( scopeElement, doc, QgsReadWriteContext() );
3049  mapcanvasNode.appendChild( scopeElement );
3050 
3051  // TODO: store only units, extent, projections, dest CRS
3052 }
3053 
3054 void QgsMapCanvas::zoomByFactor( double scaleFactor, const QgsPointXY *center, bool ignoreScaleLock )
3055 {
3056  if ( mScaleLocked && !ignoreScaleLock )
3057  {
3058  ScaleRestorer restorer( this );
3060  }
3061  else
3062  {
3064  r.scale( scaleFactor, center );
3065  setExtent( r, true );
3066  refresh();
3067  }
3068 }
3069 
3071 {
3072  // Find out which layer it was that sent the signal.
3073  QgsVectorLayer *layer = qobject_cast<QgsVectorLayer *>( sender() );
3074  if ( layer )
3075  {
3076  emit selectionChanged( layer );
3077  refresh();
3078  }
3079 }
3080 
3081 void QgsMapCanvas::dragEnterEvent( QDragEnterEvent *event )
3082 {
3083  // By default graphics view delegates the drag events to graphics items.
3084  // But we do not want that and by ignoring the drag enter we let the
3085  // parent (e.g. QgisApp) to handle drops of map layers etc.
3086 
3087  // so we ONLY accept the event if we know in advance that a custom drop handler
3088  // wants it
3089 
3090  if ( QgsMimeDataUtils::isUriList( event->mimeData() ) )
3091  {
3093  bool allHandled = true;
3094  for ( const QgsMimeDataUtils::Uri &uri : lst )
3095  {
3096  bool handled = false;
3097  for ( QgsCustomDropHandler *handler : std::as_const( mDropHandlers ) )
3098  {
3099  if ( handler->canHandleCustomUriCanvasDrop( uri, this ) )
3100  {
3101  handled = true;
3102  break;
3103  }
3104  }
3105  if ( !handled )
3106  allHandled = false;
3107  }
3108  if ( allHandled )
3109  event->accept();
3110  else
3111  event->ignore();
3112  }
3113  else
3114  {
3115  event->ignore();
3116  }
3117 }
3118 
3119 bool QgsMapCanvas::viewportEvent( QEvent *event )
3120 {
3121  if ( event->type() == QEvent::ToolTip && mMapTool && mMapTool->canvasToolTipEvent( qgis::down_cast<QHelpEvent *>( event ) ) )
3122  {
3123  return true;
3124  }
3125  return QGraphicsView::viewportEvent( event );
3126 }
3127 
3128 void QgsMapCanvas::mapToolDestroyed()
3129 {
3130  QgsDebugMsgLevel( QStringLiteral( "maptool destroyed" ), 2 );
3131  mMapTool = nullptr;
3132 }
3133 
3134 bool QgsMapCanvas::event( QEvent *e )
3135 {
3136  if ( !QTouchDevice::devices().empty() )
3137  {
3138  if ( e->type() == QEvent::Gesture )
3139  {
3140  if ( QTapAndHoldGesture *tapAndHoldGesture = qobject_cast< QTapAndHoldGesture * >( static_cast<QGestureEvent *>( e )->gesture( Qt::TapAndHoldGesture ) ) )
3141  {
3142  QPointF pos = tapAndHoldGesture->position();
3143  pos = mapFromGlobal( QPoint( pos.x(), pos.y() ) );
3144  QgsPointXY mapPoint = getCoordinateTransform()->toMapCoordinates( pos.x(), pos.y() );
3145  emit tapAndHoldGestureOccurred( mapPoint, tapAndHoldGesture );
3146  }
3147 
3148  // call handler of current map tool
3149  if ( mMapTool )
3150  {
3151  return mMapTool->gestureEvent( static_cast<QGestureEvent *>( e ) );
3152  }
3153  }
3154  }
3155 
3156  // pass other events to base class
3157  return QGraphicsView::event( e );
3158 }
3159 
3161 {
3162  // reload all layers in canvas
3163  const QList<QgsMapLayer *> layers = mapSettings().layers();
3164  for ( QgsMapLayer *layer : layers )
3165  {
3166  layer->reload();
3167  }
3168 
3169  redrawAllLayers();
3170 }
3171 
3173 {
3174  // clear the cache
3175  clearCache();
3176 
3177  // and then refresh
3178  refresh();
3179 }
3180 
3182 {
3183  while ( mRefreshScheduled || mJob )
3184  {
3185  QgsApplication::processEvents();
3186  }
3187 }
3188 
3190 {
3191  mSettings.setSegmentationTolerance( tolerance );
3192 }
3193 
3195 {
3196  mSettings.setSegmentationToleranceType( type );
3197 }
3198 
3199 QList<QgsMapCanvasAnnotationItem *> QgsMapCanvas::annotationItems() const
3200 {
3201  QList<QgsMapCanvasAnnotationItem *> annotationItemList;
3202  const QList<QGraphicsItem *> items = mScene->items();
3203  for ( QGraphicsItem *gi : items )
3204  {
3205  QgsMapCanvasAnnotationItem *aItem = dynamic_cast< QgsMapCanvasAnnotationItem *>( gi );
3206  if ( aItem )
3207  {
3208  annotationItemList.push_back( aItem );
3209  }
3210  }
3211 
3212  return annotationItemList;
3213 }
3214 
3216 {
3217  mAnnotationsVisible = show;
3218  const QList<QgsMapCanvasAnnotationItem *> items = annotationItems();
3219  for ( QgsMapCanvasAnnotationItem *item : items )
3220  {
3221  item->setVisible( show );
3222  }
3223 }
3224 
3226 {
3227  mSettings.setLabelingEngineSettings( settings );
3228 }
3229 
3231 {
3232  return mSettings.labelingEngineSettings();
3233 }
3234 
3235 void QgsMapCanvas::startPreviewJobs()
3236 {
3237  stopPreviewJobs(); //just in case still running
3238 
3239  //canvas preview jobs aren't compatible with rotation
3240  // TODO fix this
3241  if ( !qgsDoubleNear( mSettings.rotation(), 0.0 ) )
3242  return;
3243 
3244  schedulePreviewJob( 0 );
3245 }
3246 
3247 void QgsMapCanvas::startPreviewJob( int number )
3248 {
3249  QgsRectangle mapRect = mSettings.visibleExtent();
3250 
3251  if ( number == 4 )
3252  number += 1;
3253 
3254  int j = number / 3;
3255  int i = number % 3;
3256 
3257  //copy settings, only update extent
3258  QgsMapSettings jobSettings = mSettings;
3259 
3260  double dx = ( i - 1 ) * mapRect.width();
3261  double dy = ( 1 - j ) * mapRect.height();
3262  QgsRectangle jobExtent = mapRect;
3263 
3264  jobExtent.setXMaximum( jobExtent.xMaximum() + dx );
3265  jobExtent.setXMinimum( jobExtent.xMinimum() + dx );
3266  jobExtent.setYMaximum( jobExtent.yMaximum() + dy );
3267  jobExtent.setYMinimum( jobExtent.yMinimum() + dy );
3268 
3269  jobSettings.setExtent( jobExtent );
3270  jobSettings.setFlag( Qgis::MapSettingsFlag::DrawLabeling, false );
3271  jobSettings.setFlag( Qgis::MapSettingsFlag::RenderPreviewJob, true );
3272 
3273  // truncate preview layers to fast layers
3274  const QList<QgsMapLayer *> layers = jobSettings.layers();
3275  QList< QgsMapLayer * > previewLayers;
3277  context.maxRenderingTimeMs = MAXIMUM_LAYER_PREVIEW_TIME_MS;
3278  for ( QgsMapLayer *layer : layers )
3279  {
3280  context.lastRenderingTimeMs = mLastLayerRenderTime.value( layer->id(), 0 );
3281  QgsDataProvider *provider = layer->dataProvider();
3282  if ( provider && !provider->renderInPreview( context ) )
3283  {
3284  QgsDebugMsgLevel( QStringLiteral( "Layer %1 not rendered because it does not match the renderInPreview criterion %2" ).arg( layer->id() ).arg( mLastLayerRenderTime.value( layer->id() ) ), 3 );
3285  continue;
3286  }
3287 
3288  previewLayers << layer;
3289  }
3290  jobSettings.setLayers( previewLayers );
3291 
3292  QgsMapRendererQImageJob *job = new QgsMapRendererSequentialJob( jobSettings );
3293  job->setProperty( "number", number );
3294  mPreviewJobs.append( job );
3295  connect( job, &QgsMapRendererJob::finished, this, &QgsMapCanvas::previewJobFinished );
3296  job->start();
3297 }
3298 
3299 void QgsMapCanvas::stopPreviewJobs()
3300 {
3301  mPreviewTimer.stop();
3302  for ( auto previewJob = mPreviewJobs.constBegin(); previewJob != mPreviewJobs.constEnd(); ++previewJob )
3303  {
3304  if ( *previewJob )
3305  {
3306  disconnect( *previewJob, &QgsMapRendererJob::finished, this, &QgsMapCanvas::previewJobFinished );
3307  connect( *previewJob, &QgsMapRendererQImageJob::finished, *previewJob, &QgsMapRendererQImageJob::deleteLater );
3308  ( *previewJob )->cancelWithoutBlocking();
3309  }
3310  }
3311  mPreviewJobs.clear();
3312 }
3313 
3314 void QgsMapCanvas::schedulePreviewJob( int number )
3315 {
3316  mPreviewTimer.setSingleShot( true );
3317  mPreviewTimer.setInterval( PREVIEW_JOB_DELAY_MS );
3318  disconnect( mPreviewTimerConnection );
3319  mPreviewTimerConnection = connect( &mPreviewTimer, &QTimer::timeout, this, [ = ]()
3320  {
3321  startPreviewJob( number );
3322  } );
3323  mPreviewTimer.start();
3324 }
3325 
3326 bool QgsMapCanvas::panOperationInProgress()
3327 {
3328  if ( mCanvasProperties->panSelectorDown )
3329  return true;
3330 
3331  if ( QgsMapToolPan *panTool = qobject_cast< QgsMapToolPan *>( mMapTool ) )
3332  {
3333  if ( panTool->isDragging() )
3334  return true;
3335  }
3336 
3337  return false;
3338 }
3339 
3340 int QgsMapCanvas::nextZoomLevel( const QList<double> &resolutions, bool zoomIn ) const
3341 {
3342  int resolutionLevel = -1;
3343  double currentResolution = mapUnitsPerPixel();
3344 
3345  for ( int i = 0, n = resolutions.size(); i < n; ++i )
3346  {
3347  if ( qgsDoubleNear( resolutions[i], currentResolution, 0.0001 ) )
3348  {
3349  resolutionLevel = zoomIn ? ( i - 1 ) : ( i + 1 );
3350  break;
3351  }
3352  else if ( currentResolution <= resolutions[i] )
3353  {
3354  resolutionLevel = zoomIn ? ( i - 1 ) : i;
3355  break;
3356  }
3357  }
3358  return ( resolutionLevel < 0 || resolutionLevel >= resolutions.size() ) ? -1 : resolutionLevel;
3359 }
3360 
3362 {
3363  if ( !mZoomResolutions.isEmpty() )
3364  {
3365  int zoomLevel = nextZoomLevel( mZoomResolutions, true );
3366  if ( zoomLevel != -1 )
3367  {
3368  return mZoomResolutions.at( zoomLevel ) / mapUnitsPerPixel();
3369  }
3370  }
3371  return 1 / mWheelZoomFactor;
3372 }
3373 
3375 {
3376  if ( !mZoomResolutions.isEmpty() )
3377  {
3378  int zoomLevel = nextZoomLevel( mZoomResolutions, false );
3379  if ( zoomLevel != -1 )
3380  {
3381  return mZoomResolutions.at( zoomLevel ) / mapUnitsPerPixel();
3382  }
3383  }
3384  return mWheelZoomFactor;
3385 }
QgsMapCanvas::CanvasProperties::rubberStartPoint
QPoint rubberStartPoint
Beginning point of a rubber band.
Definition: qgsmapcanvas.cpp:135
QgsMapCanvas::renderStarting
void renderStarting()
Emitted when the canvas is about to be rendered.
QgsMapCanvas::zRangeChanged
void zRangeChanged()
Emitted when the map canvas z (elevation) range changes.
QgsMapCanvas::projectExtent
QgsRectangle projectExtent() const
Returns the associated project's full extent, in the canvas' CRS.
Definition: qgsmapcanvas.cpp:1341
QgsMapCanvas::mouseDoubleClickEvent
void mouseDoubleClickEvent(QMouseEvent *e) override
Definition: qgsmapcanvas.cpp:2087
QgsAbstractGeometry::MaximumAngle
@ MaximumAngle
Maximum angle between generating radii (lines from arc center to output vertices)
Definition: qgsabstractgeometry.h:127
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:406
QgsMapLayer::crs
QgsCoordinateReferenceSystem crs
Definition: qgsmaplayer.h:79
QgsMapTool::flags
virtual Flags flags() const
Returns the flags for the map tool.
Definition: qgsmaptool.h:123
QgsMapSettings::labelingEngineSettings
const QgsLabelingEngineSettings & labelingEngineSettings() const
Returns the global configuration of the labeling engine.
Definition: qgsmapsettings.h:667
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:1793
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:198
QgsMapSettings::setDestinationCrs
void setDestinationCrs(const QgsCoordinateReferenceSystem &crs)
Sets the destination crs (coordinate reference system) for the map render.
Definition: qgsmapsettings.cpp:350
QgsMapCanvas::dropEvent
void dropEvent(QDropEvent *event) override
Definition: qgsmapcanvas.cpp:2833
Qgis::MapSettingsFlag::RenderPartialOutput
@ RenderPartialOutput
Whether to make extra effort to update map image with partially rendered layers (better for interacti...
qgsexpressioncontextutils.h
QgsMapCanvas::waitWhileRendering
void waitWhileRendering()
Blocks until the rendering job has finished.
Definition: qgsmapcanvas.cpp:3181
QgsMapCanvas::zoomToPreviousExtent
void zoomToPreviousExtent()
Zoom to the previous extent (view)
Definition: qgsmapcanvas.cpp:1522
QgsTemporalNavigationObject::Animated
@ Animated
Temporal navigation relies on frames within a datetime range.
Definition: qgstemporalnavigationobject.h:54
QgsTemporalProperty::flags
virtual QgsTemporalProperty::Flags flags() const
Returns flags associated to the temporal property.
Definition: qgstemporalproperty.h:74
qgssvgcache.h
QgsRectangle::height
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
Definition: qgsrectangle.h:230
QgsMapLayer::hasAutoRefreshEnabled
bool hasAutoRefreshEnabled() const
Returns true if auto refresh is enabled for the layer.
Definition: qgsmaplayer.cpp:844
QgsMapCanvasInteractionBlocker
An interface for objects which block interactions with a QgsMapCanvas.
Definition: qgsmapcanvasinteractionblocker.h:29
QgsMapCanvasAnnotationItem
An interactive map canvas item which displays a QgsAnnotation.
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:63
QgsMapRendererJob::Error
Definition: qgsmaprendererjob.h:354
qgspallabeling.h
QgsMapCanvas::extent
QgsRectangle extent() const
Returns the current zoom extent of the map canvas.
Definition: qgsmapcanvas.cpp:1331
Qgis::MapSettingsFlag::UseRenderingOptimization
@ UseRenderingOptimization
Enable vector simplification and other rendering optimizations.
QgsMapCanvas::CanvasProperties::mouseLastXY
QPoint mouseLastXY
Last seen point of the mouse.
Definition: qgsmapcanvas.cpp:132
QgsMapCanvas::moveCanvasContents
void moveCanvasContents(bool reset=false)
called when panning is in action, reset indicates end of panning
Definition: qgsmapcanvas.cpp:2824
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:633
qgsruntimeprofiler.h
QgsMapCanvas::setTheme
void setTheme(const QString &theme)
Sets a map theme to show in the canvas.
Definition: qgsmapcanvas.cpp:2653
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:3491
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.
QgsMapCanvas::refresh
void refresh()
Repaints the canvas map.
Definition: qgsmapcanvas.cpp:643
QgsMapLayer::autoRefreshInterval
int autoRefreshInterval
Definition: qgsmaplayer.h:77
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:83
QgsMapTool::canvasDoubleClickEvent
virtual void canvasDoubleClickEvent(QgsMapMouseEvent *e)
Mouse double-click event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:173
QgsMapCanvas::setProject
void setProject(QgsProject *project)
Sets the project linked to this canvas.
Definition: qgsmapcanvas.cpp:2533
QgsMapCanvas::setWheelFactor
void setWheelFactor(double factor)
Sets wheel zoom factor (should be greater than 1)
Definition: qgsmapcanvas.cpp:2391
QgsMapCanvas::isDrawing
bool isDrawing()
Find out whether rendering is in progress.
Definition: qgsmapcanvas.cpp:372
QgsMapToPixel::mapUnitsPerPixel
double mapUnitsPerPixel() const
Returns the current map units per pixel.
Definition: qgsmaptopixel.h:229
QgsMapSettings::readXml
void readXml(QDomNode &node)
Definition: qgsmapsettings.cpp:748
QgsRubberBand::ICON_CIRCLE
@ ICON_CIRCLE
A circle is used to highlight points (â—‹)
Definition: qgsrubberband.h:108
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:391
QgsSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Definition: qgssettings.cpp:161
QgsMapRendererCustomPainterJob::waitForFinished
void waitForFinished() override
Block until the job has finished.
Definition: qgsmaprenderercustompainterjob.cpp:187
QgsExpressionContextUtils::globalScope
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Definition: qgsexpressioncontextutils.cpp:40
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:249
QgsReadWriteContext
The class is used as a container of context for various read/write operations on other objects.
Definition: qgsreadwritecontext.h:34
QgsMapCanvas::destinationCrsChanged
void destinationCrsChanged()
Emitted when map CRS has changed.
QgsDataProvider
Abstract base class for spatial data provider implementations.
Definition: qgsdataprovider.h:40
QgsMapSettings::outputSize
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
Definition: qgsmapsettings.cpp:239
QgsMapSettings::setFlag
void setFlag(Qgis::MapSettingsFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
Definition: qgsmapsettings.cpp:382
QgsMapCanvas::zoomScale
void zoomScale(double scale, bool ignoreScaleLock=false)
Zooms the canvas to a specific scale.
Definition: qgsmapcanvas.cpp:2408
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:107
QgsMapCanvas::mapTool
QgsMapTool * mapTool()
Returns the currently active tool.
Definition: qgsmapcanvas.cpp:2769
qgsmapthemecollection.h
QgsMapCanvas::zoomByFactor
void zoomByFactor(double scaleFactor, const QgsPointXY *center=nullptr, bool ignoreScaleLock=false)
Zoom with the factor supplied.
Definition: qgsmapcanvas.cpp:3054
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:2402
QgsCoordinateReferenceSystem::userFriendlyIdentifier
QString userFriendlyIdentifier(IdentifierType type=MediumString) const
Returns a user friendly identifier for the CRS.
Definition: qgscoordinatereferencesystem.cpp:1212
QgsMapCanvas::zoomLastStatusChanged
void zoomLastStatusChanged(bool)
Emitted when zoom last status changed.
QgsMapCanvas::mouseLastXY
QPoint mouseLastXY()
returns last position of mouse cursor
Definition: qgsmapcanvas.cpp:2890
QgsReferencedRectangle
A QgsRectangle with associated coordinate reference system.
Definition: qgsreferencedgeometry.h:73
QgsRubberBand::updatePosition
void updatePosition() override
called on changed extent or resize event to update position of the item
Definition: qgsrubberband.cpp:691
QgsMapCanvas::mouseMoveEvent
void mouseMoveEvent(QMouseEvent *e) override
Definition: qgsmapcanvas.cpp:2443
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:680
QgsMapCanvas::mapSettings
const QgsMapSettings & mapSettings() const
Gets access to properties used for map rendering.
Definition: qgsmapcanvas.cpp:437
QgsMapCanvas::redrawAllLayers
void redrawAllLayers()
Clears all cached images and redraws all layers.
Definition: qgsmapcanvas.cpp:3172
QgsRubberBand
A class for drawing transient features (e.g. digitizing lines) on the map.
Definition: qgsrubberband.h:51
Qgis::MapSettingsFlag::DrawLabeling
@ DrawLabeling
Enable drawing of labels on top of the map.
QgsMapCanvas::antiAliasingEnabled
bool antiAliasingEnabled() const
true if antialiasing is enabled
Definition: qgsmapcanvas.cpp:324
QgsMapSettings::devicePixelRatio
float devicePixelRatio() const
Returns the device pixel ratio.
Definition: qgsmapsettings.cpp:251
QgsRectangle::center
QgsPointXY center() const SIP_HOLDGIL
Returns the center point of the rectangle.
Definition: qgsrectangle.h:251
QgsExpressionContextScope::readXml
void readXml(const QDomElement &element, const QgsReadWriteContext &context)
Reads scope variables from an XML element.
Definition: qgsexpressioncontext.cpp:204
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:129
QgsApplication::getThemeCursor
static QCursor getThemeCursor(Cursor cursor)
Helper to get a theme cursor.
Definition: qgsapplication.cpp:762
QgsTemporalRangeObject::setIsTemporal
void setIsTemporal(bool enabled)
Sets whether the temporal range is enabled (i.e.
Definition: qgstemporalrangeobject.cpp:25
QgsMapCanvas::messageEmitted
void messageEmitted(const QString &title, const QString &message, Qgis::MessageLevel=Qgis::MessageLevel::Info)
emit a message (usually to be displayed in a message bar)
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:1876
QgsRubberBand::strokeColor
QColor strokeColor
Definition: qgsrubberband.h:76
QgsMapCanvas::mouseReleaseEvent
void mouseReleaseEvent(QMouseEvent *e) override
Definition: qgsmapcanvas.cpp:2223
QgsMapThemeCollection::mapThemeChanged
void mapThemeChanged(const QString &theme)
Emitted when a map theme changes definition.
qgssymbollayerutils.h
QgsMapCanvas::temporalRangeChanged
void temporalRangeChanged()
Emitted when the map canvas temporal range changes.
QgsProjectionSelectionDialog
A generic dialog to prompt the user for a Coordinate Reference System.
Definition: qgsprojectionselectiondialog.h:170
qgsfeatureiterator.h
QgsMapRendererCache::clear
void clear()
Invalidates the cache contents, clearing all cached images.
Definition: qgsmaprenderercache.cpp:31
QgsRectangle::yMinimum
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:198
QgsCoordinateTransform::transformBoundingBox
QgsRectangle transformBoundingBox(const QgsRectangle &rectangle, Qgis::TransformDirection direction=Qgis::TransformDirection::Forward, bool handle180Crossover=false) const SIP_THROW(QgsCsException)
Transforms a rectangle from the source CRS to the destination CRS.
Definition: qgscoordinatetransform.cpp:560
QgsGeometry::fromPointXY
static QgsGeometry fromPointXY(const QgsPointXY &point) SIP_HOLDGIL
Creates a new geometry from a QgsPointXY object.
Definition: qgsgeometry.cpp:176
QgsMapSettings::hasValidSettings
bool hasValidSettings() const
Check whether the map settings are valid and can be used for rendering.
Definition: qgsmapsettings.cpp:406
QgsMapCanvas
Map canvas is a class for displaying all GIS data types on a canvas.
Definition: qgsmapcanvas.h:89
QgsMapCanvas::panActionEnd
void panActionEnd(QPoint releasePoint)
Ends pan action and redraws the canvas.
Definition: qgsmapcanvas.cpp:2779
QgsMapCanvas::setMagnificationFactor
void setMagnificationFactor(double factor, const QgsPointXY *center=nullptr)
Sets the factor of magnification to apply to the map canvas.
Definition: qgsmapcanvas.cpp:297
QgsMapSettings::fullExtent
QgsRectangle fullExtent() const
returns current extent of layer set
Definition: qgsmapsettings.cpp:689
QgsMapTool::deactivate
virtual void deactivate()
called when map tool is being deactivated
Definition: qgsmaptool.cpp:110
QgsMapSettings::setSegmentationToleranceType
void setSegmentationToleranceType(QgsAbstractGeometry::SegmentationToleranceType type)
Sets segmentation tolerance type (maximum angle or maximum difference between curve and approximation...
Definition: qgsmapsettings.h:640
QgsMapSettings::writeXml
void writeXml(QDomNode &node, QDomDocument &doc)
Definition: qgsmapsettings.cpp:783
QgsMapCanvas::center
QgsPointXY center() const
Gets map center, in geographical coordinates.
Definition: qgsmapcanvas.cpp:1461
QgsLabelingResults
Class that stores computed placement from labeling engine.
Definition: qgslabelingresults.h:32
QgsExpressionContextScope::writeXml
bool writeXml(QDomElement &element, QDomDocument &document, const QgsReadWriteContext &context) const
Writes scope variables to an XML element.
Definition: qgsexpressioncontext.cpp:216
qgsmapcanvasannotationitem.h
QgsFeature::geometry
QgsGeometry geometry
Definition: qgsfeature.h:71
QgsCoordinateReferenceSystem::axisOrdering
QList< Qgis::CrsAxisDirection > axisOrdering() const
Returns an ordered list of the axis directions reflecting the native axis order for the CRS.
Definition: qgscoordinatereferencesystem.cpp:804
qgstemporalnavigationobject.h
QgsProject::transformContext
QgsCoordinateTransformContext transformContext
Definition: qgsproject.h:110
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:1336
QgsMapSettings::mapUnitsPerPixel
double mapUnitsPerPixel() const
Returns the distance in geographical coordinates that equals to one pixel in the map.
Definition: qgsmapsettings.cpp:453
QgsMapCanvas::~QgsMapCanvas
~QgsMapCanvas() override
Definition: qgsmapcanvas.cpp:253
QgsMapCanvas::setRotation
void setRotation(double degrees)
Set the rotation of the map canvas in clockwise degrees.
Definition: qgsmapcanvas.cpp:1477
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:427
qgsmaprenderercustompainterjob.h
QgsRectangle::setMinimal
void setMinimal() SIP_HOLDGIL
Set a rectangle so that min corner is at max and max corner is at min.
Definition: qgsrectangle.h:172
QgsProject::instance
static QgsProject * instance()
Returns the QgsProject singleton instance.
Definition: qgsproject.cpp:480
QgsMapSettings::layerExtentToOutputExtent
QgsRectangle layerExtentToOutputExtent(const QgsMapLayer *layer, QgsRectangle extent) const
transform bounding box from layer's CRS to output CRS
Definition: qgsmapsettings.cpp:528
QgsRubberBand::setStrokeColor
void setStrokeColor(const QColor &color)
Sets the stroke color for the rubberband.
Definition: qgsrubberband.cpp:68
QgsMapCanvas::scale
double scale() const
Returns the last reported scale of the canvas.
Definition: qgsmapcanvas.cpp:367
QgsMapTool::Transient
@ Transient
Definition: qgsmaptool.h:110
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.
QgsSymbolLayerUtils::rendererFrameRate
static double rendererFrameRate(const QgsFeatureRenderer *renderer)
Calculates the frame rate (in frames per second) at which the given renderer must be redrawn.
Definition: qgssymbollayerutils.cpp:4957
QgsMapSettings::setFrameRate
void setFrameRate(double rate)
Sets the frame rate of the map (in frames per second), for maps which are part of an animation.
Definition: qgsmapsettings.cpp:873
QgsMapCanvas::zoomWithCenter
void zoomWithCenter(int x, int y, bool zoomIn)
Zooms in/out with a given center.
Definition: qgsmapcanvas.cpp:2413
QgsMapSettings::magnificationFactor
double magnificationFactor() const
Returns the magnification factor.
Definition: qgsmapsettings.cpp:70
QgsRubberBand::setFillColor
void setFillColor(const QColor &color)
Sets the fill color for the rubberband.
Definition: qgsrubberband.cpp:60
QgsMapSettings::layerStyleOverrides
QMap< QString, QString > layerStyleOverrides() const
Returns the map of map layer style overrides (key: layer ID, value: style name) where a different sty...
Definition: qgsmapsettings.cpp:340
QgsMapCanvas::zoomToProjectExtent
void zoomToProjectExtent()
Zoom to the full extent the project associated with this canvas.
Definition: qgsmapcanvas.cpp:1508
QgsSettings
This class is a composition of two QSettings instances:
Definition: qgssettings.h:61
QgsMapCanvas::writeProject
void writeProject(QDomDocument &)
called to write map canvas settings to project
Definition: qgsmapcanvas.cpp:3019
QgsMapCanvas::selectionChangedSlot
void selectionChangedSlot()
Receives signal about selection change, and pass it on with layer info.
Definition: qgsmapcanvas.cpp:3070
QgsMapLayer::reload
virtual Q_INVOKABLE void reload()
Synchronises with changes in the datasource.
Definition: qgsmaplayer.h:537
QgsMapCanvas::panAction
void panAction(QMouseEvent *event)
Called when mouse is moving and pan is activated.
Definition: qgsmapcanvas.cpp:2807
QgsMapSettings::setZRange
void setZRange(const QgsDoubleRange &range)
Sets the range of z-values which will be visible in the map.
Definition: qgsmapsettings.cpp:853
QgsExpressionContextScopeGenerator
Abstract interface for generating an expression context scope.
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:582
QgsRubberBand::fillColor
QColor fillColor
Definition: qgsrubberband.h:75
QgsMapCanvas::CanvasProperties::panSelectorDown
bool panSelectorDown
Flag to indicate the pan selector key is held down by user.
Definition: qgsmapcanvas.cpp:138
QgsMapSettings::setCurrentFrame
void setCurrentFrame(long long frame)
Sets the current frame of the map, for maps which are part of an animation.
Definition: qgsmapsettings.cpp:883
QgsMapCanvas::renderedItemResults
const QgsRenderedItemResults * renderedItemResults(bool allowOutdatedResults=true) const
Gets access to the rendered item results (may be nullptr), which includes the results of rendering an...
Definition: qgsmapcanvas.cpp:546
QgsMapCanvas::mapUnits
QgsUnitTypes::DistanceUnit mapUnits() const
Convenience function for returning the current canvas map units.
Definition: qgsmapcanvas.cpp:2633
QgsAbstractGeometry::SegmentationToleranceType
SegmentationToleranceType
Segmentation tolerance as maximum angle or maximum difference between approximation and circle.
Definition: qgsabstractgeometry.h:120
qgsmimedatautils.h
QgsMapSettings::setOutputDpi
void setOutputDpi(double dpi)
Sets the dpi (dots per inch) used for conversion between real world units (e.g.
Definition: qgsmapsettings.cpp:272
QgsMimeDataUtils::UriList
QList< QgsMimeDataUtils::Uri > UriList
Definition: qgsmimedatautils.h:164
QgsMapCanvas::dragEnterEvent
void dragEnterEvent(QDragEnterEvent *e) override
Definition: qgsmapcanvas.cpp:3081
QgsDebugMsg
#define QgsDebugMsg(str)
Definition: qgslogger.h:38
Qgis::CoordinateTransformationFlag::IgnoreImpossibleTransformations
@ IgnoreImpossibleTransformations
Indicates that impossible transformations (such as those which attempt to transform between two diffe...
qgsmaprenderercache.h
QgsUnitTypes::DistanceUnit
DistanceUnit
Units of distance.
Definition: qgsunittypes.h:67
QgsMapCanvas::paintEvent
void paintEvent(QPaintEvent *e) override
Definition: qgsmapcanvas.cpp:2319
QgsProject::mapLayer
Q_INVOKABLE QgsMapLayer * mapLayer(const QString &layerId) const
Retrieve a pointer to a registered layer by layer ID.
Definition: qgsproject.cpp:3680
QgsMapToPixel::toMapCoordinates
QgsPointXY toMapCoordinates(int x, int y) const
Transforms device coordinates to map (world) coordinates.
Definition: qgsmaptopixel.h:173
QgsRubberBand::secondaryStrokeColor
QColor secondaryStrokeColor
Definition: qgsrubberband.h:78
QgsMapCanvas::freeze
void freeze(bool frozen=true)
Freeze/thaw the map canvas.
Definition: qgsmapcanvas.cpp:2618
QgsMapCanvas::viewportEvent
bool viewportEvent(QEvent *event) override
Definition: qgsmapcanvas.cpp:3119
QgsMapTool::clean
virtual void clean()
convenient method to clean members
Definition: qgsmaptool.cpp:120
QgsMapTool::keyPressEvent
virtual void keyPressEvent(QKeyEvent *e)
Key event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:193
Qgis::CoordinateTransformationFlag::BallparkTransformsAreAppropriate
@ BallparkTransformsAreAppropriate
Indicates that approximate "ballpark" results are appropriate for this coordinate transform....
QgsMapCanvas::wheelEvent
void wheelEvent(QWheelEvent *e) override
Definition: qgsmapcanvas.cpp:2344
QgsMapCanvas::QgsMapCanvas
QgsMapCanvas(QWidget *parent=nullptr)
Constructor.
Definition: qgsmapcanvas.cpp:130
QgsMapSettings::setSegmentationTolerance
void setSegmentationTolerance(double tolerance)
Sets the segmentation tolerance applied when rendering curved geometries.
Definition: qgsmapsettings.h:632
QgsRectangle
A rectangle specified with double values.
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:3194
QgsMapRendererCache
This class is responsible for keeping cache of rendered images resulting from a map rendering job.
Definition: qgsmaprenderercache.h:47
QgsWkbTypes::PolygonGeometry
@ PolygonGeometry
Definition: qgswkbtypes.h:144
Qgis::MapSettingsFlag::Antialiasing
@ Antialiasing
Enable anti-aliasing for map rendering.
QgsVectorLayer::isEditable
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
Definition: qgsvectorlayer.cpp:3728
QgsProject
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition: qgsproject.h:103
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:2935
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:931
QgsMapCanvas::allowInteraction
bool allowInteraction(QgsMapCanvasInteractionBlocker::Interaction interaction) const
Returns true if the specified interaction is currently permitted on the canvas.
Definition: qgsmapcanvas.cpp:1230
qgsrubberband.h
QgsMapCanvas::scaleChanged
void scaleChanged(double)
Emitted when the scale of the map changes.
Qgis::MapSettingsFlag::RenderPreviewJob
@ RenderPreviewJob
Render is a 'canvas preview' render, and shortcuts should be taken to ensure fast rendering.
qgslabelingresults.h
QgsMapSettings::extent
QgsRectangle extent() const
Returns geographical coordinates of the rectangle that should be rendered.
Definition: qgsmapsettings.cpp:75
QgsMapCanvas::labelingResults
const QgsLabelingResults * labelingResults(bool allowOutdatedResults=true) const
Gets access to the labeling results (may be nullptr).
Definition: qgsmapcanvas.cpp:538
QgsProject::writeProject
void writeProject(QDomDocument &)
Emitted when the project is being written.
QgsMapCanvas::isParallelRenderingEnabled
bool isParallelRenderingEnabled() const
Check whether the layers are rendered in parallel or sequentially.
Definition: qgsmapcanvas.cpp:598
QgsMapRendererJob::renderingTime
int renderingTime() const
Returns the total time it took to finish the job (in milliseconds).
Definition: qgsmaprendererjob.h:407
qgsapplication.h
QgsMapLayerElevationProperties::hasElevation
virtual bool hasElevation() const
Returns true if the layer has an elevation or z component.
Definition: qgsmaplayerelevationproperties.cpp:29
QgsMapCanvas::scaleLockChanged
void scaleLockChanged(bool locked)
Emitted when the scale locked state of the map changes.
QgsPointXY::sqrDist
double sqrDist(double x, double y) const SIP_HOLDGIL
Returns the squared distance between this point a specified x, y coordinate.
Definition: qgspointxy.h:190
qgsprojectionselectiondialog.h
QgsTemporalNavigationObject::navigationModeChanged
void navigationModeChanged(QgsTemporalNavigationObject::NavigationMode mode)
Emitted whenever the navigation mode changes.
QgsMapTool
Abstract base class for all map tools. Map tools are user interactive tools for manipulating the map ...
Definition: qgsmaptool.h:70
QgsMapRendererJob::setLayerRenderingTimeHints
void setLayerRenderingTimeHints(const QHash< QString, int > &hints)
Sets approximate render times (in ms) for map layers.
QgsFeatureRequest::setFilterRect
QgsFeatureRequest & setFilterRect(const QgsRectangle &rectangle)
Sets the rectangle from which features will be taken.
Definition: qgsfeaturerequest.cpp:101
QgsMapCanvasSnappingUtils
Snapping utils instance that is connected to a canvas and updates the configuration (map settings + c...
Definition: qgsmapcanvassnappingutils.h:33
QgsMapCanvas::setCurrentLayer
void setCurrentLayer(QgsMapLayer *layer)
Definition: qgsmapcanvas.cpp:358
qgsmaptoolzoom.h
QgsMapRendererJob::errors
Errors errors() const
List of errors that happened during the rendering job - available when the rendering has been finishe...
QgsMapRendererParallelJob
Job implementation that renders all layers in parallel.
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
QgsRectangle::xMaximum
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:183
QgsMapCanvas::rotation
double rotation() const
Gets the current map canvas rotation in clockwise degrees.
Definition: qgsmapcanvas.cpp:1472
QgsRectangle::scale
void scale(double scaleFactor, const QgsPointXY *c=nullptr)
Scale the rectangle around its center point.
Definition: qgsrectangle.h:256
QgsCoordinateReferenceSystemUtils::defaultCoordinateOrderForCrs
static Qgis::CoordinateOrder defaultCoordinateOrderForCrs(const QgsCoordinateReferenceSystem &crs)
Returns the default coordinate order to use for the specified crs.
Definition: qgscoordinatereferencesystemutils.cpp:20
qgstemporalcontroller.h
QgsDistanceArea::setEllipsoid
bool setEllipsoid(const QString &ellipsoid)
Sets the ellipsoid by its acronym.
Definition: qgsdistancearea.cpp:89
QgsMapCanvas::zoomIn
void zoomIn()
Zoom in with fixed factor.
Definition: qgsmapcanvas.cpp:2396
QgsMapCanvas::readProject
void readProject(const QDomDocument &)
called to read map canvas settings from project
Definition: qgsmapcanvas.cpp:2951
QgsFeatureRequest
This class wraps a request for features to a vector layer (or directly its vector data provider).
Definition: qgsfeaturerequest.h:83
Qgis::MapSettingsFlag::DrawEditingInfo
@ DrawEditingInfo
Enable drawing of vertex markers for layers in editing mode.
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:291
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:318
QgsMapCanvas::showEvent
void showEvent(QShowEvent *event) override
Definition: qgsmapcanvas.cpp:2867
QgsCsException
Custom exception class for Coordinate Reference System related exceptions.
Definition: qgsexception.h:65
QgsMapCanvas::cancelJobs
void cancelJobs()
Cancel any rendering job, in a blocking way.
Definition: qgsmapcanvas.cpp:275
QgsMapRendererJob::start
void start()
Start the rendering job and immediately return.
QgsMapSettings::setBackgroundColor
void setBackgroundColor(const QColor &color)
Sets the background color of the map.
Definition: qgsmapsettings.h:381
QgsMapCanvas::setTemporalController
void setTemporalController(QgsTemporalController *controller)
Sets the temporal controller for this canvas.
Definition: qgsmapcanvas.cpp:484
QgsMapCanvasItem
An abstract class for items that can be placed on the map canvas.
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:49
QgsMapCanvas::setPreviewMode
void setPreviewMode(QgsPreviewEffect::PreviewMode mode)
Sets a preview mode for the map canvas.
Definition: qgsmapcanvas.cpp:2915
QgsMapRendererJob::perLayerRenderingTime
QHash< QgsMapLayer *, int > perLayerRenderingTime() const
Returns the render time (in ms) per layer.
QgsRubberBand::addGeometry
void addGeometry(const QgsGeometry &geometry, QgsMapLayer *layer, bool doUpdate=true)
Adds the geometry of an existing feature to a rubberband This is useful for multi feature highlightin...
Definition: qgsrubberband.cpp:288
QgsMapLayer::dataProvider
virtual Q_INVOKABLE QgsDataProvider * dataProvider()
Returns the layer's data provider, it may be nullptr.
Definition: qgsmaplayer.cpp:190
QgsMapCanvas::layerCount
int layerCount() const
Returns number of layers on the map.
Definition: qgsmapcanvas.cpp:2602
QgsMapSettings::transformContext
QgsCoordinateTransformContext transformContext() const
Returns the coordinate transform context, which stores various information regarding which datum tran...
Definition: qgsmapsettings.cpp:463
QgsMapSettings::rotation
double rotation() const
Returns the rotation of the resulting map image, in degrees clockwise.
Definition: qgsmapsettings.cpp:102
QgsMapSettings::layerIds
QStringList layerIds(bool expandGroupLayers=false) const
Returns the list of layer IDs which will be rendered in the map.
Definition: qgsmapsettings.cpp:289
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:2638
QgsMapSettings::testFlag
bool testFlag(Qgis::MapSettingsFlag flag) const
Check whether a particular flag is enabled.
Definition: qgsmapsettings.cpp:395
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
QgsCoordinateTransform::setBallparkTransformsAreAppropriate
void setBallparkTransformsAreAppropriate(bool appropriate)
Sets whether approximate "ballpark" results are appropriate for this coordinate transform.
Definition: qgscoordinatetransform.cpp:939
whileBlocking
QgsSignalBlocker< Object > whileBlocking(Object *object)
Temporarily blocks signals from a QObject while calling a single method from the object.
Definition: qgis.h:2191
QgsMapCanvas::canvasColor
QColor canvasColor() const
Read property of QColor bgColor.
Definition: qgsmapcanvas.cpp:2563
QgsLabelingEngineSettings
Stores global configuration for labeling engine.
Definition: qgslabelingenginesettings.h:31
QgsMapLayerElevationProperties::flags
virtual QgsMapLayerElevationProperties::Flags flags() const
Returns flags associated to the elevation properties.
Definition: qgsmaplayerelevationproperties.h:151
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:1597
QgsMapCanvas::defaultExpressionContextScope
QgsExpressionContextScope * defaultExpressionContextScope() const
Creates a new scope which contains default variables and functions relating to the map canvas.
Definition: qgsmapcanvas.cpp:619
QgsMapSettings::setDevicePixelRatio
void setDevicePixelRatio(float dpr)
Sets the device pixel ratio.
Definition: qgsmapsettings.cpp:256
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:2265
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:334
QgsProjectViewSettings::fullExtent
QgsReferencedRectangle fullExtent() const
Returns the full extent of the project, which represents the maximal limits of the project.
Definition: qgsprojectviewsettings.cpp:73
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:203
QgsMapSettings::mapUnits
QgsUnitTypes::DistanceUnit mapUnits() const
Returns the units of the map's geographical coordinates - used for scale calculation.
Definition: qgsmapsettings.cpp:400
QgsMapSettings::setMagnificationFactor
void setMagnificationFactor(double factor, const QgsPointXY *center=nullptr)
Set the magnification factor.
Definition: qgsmapsettings.cpp:49
QgsMapCanvas::keyReleaseEvent
void keyReleaseEvent(QKeyEvent *e) override
Definition: qgsmapcanvas.cpp:2055
qgsmaplayerutils.h
QgsApplication::coordinateReferenceSystemRegistry
static QgsCoordinateReferenceSystemRegistry * coordinateReferenceSystemRegistry()
Returns the application's coordinate reference system (CRS) registry, which handles known CRS definit...
Definition: qgsapplication.cpp:2355
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:298
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:3189
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:2326
QgsMapSettings::zRange
QgsDoubleRange zRange() const
Returns the range of z-values which will be visible in the map.
Definition: qgsmapsettings.cpp:848
QgsTemporalController
A controller base class for temporal objects, contains a signal for notifying updates of the objects ...
Definition: qgstemporalcontroller.h:41
QgsMapCanvas::mapRefreshCanceled
void mapRefreshCanceled()
Emitted when the pending map refresh has been canceled.
QgsDistanceArea::lengthUnits
QgsUnitTypes::DistanceUnit lengthUnits() const
Returns the units of distance for length calculations made by this object.
Definition: qgsdistancearea.cpp:790
QgsApplication::imageCache
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
Definition: qgsapplication.cpp:2365
QgsMapLayer::temporalProperties
virtual QgsMapLayerTemporalProperties * temporalProperties()
Returns the layer's temporal properties.
Definition: qgsmaplayer.h:1502
QgsMapRendererSequentialJob
Job implementation that renders everything sequentially in one thread.
Definition: qgsmaprenderersequentialjob.h:33
QgsDataProvider::PreviewContext
Stores settings related to the context in which a preview job runs.
Definition: qgsdataprovider.h:541
QgsMapCanvas::setTemporalRange
void setTemporalRange(const QgsDateTimeRange &range)
Set datetime range for the map canvas.
Definition: qgsmapcanvas.cpp:1197
QgsMapCanvas::mCanvasProperties
std::unique_ptr< CanvasProperties > mCanvasProperties
Handle pattern for implementation object.
Definition: qgsmapcanvas.h:1228
QgsMapSettings::setSelectionColor
void setSelectionColor(const QColor &color)
Sets the color that is used for drawing of selected vector features.
Definition: qgsmapsettings.h:395
QgsRectangle::setXMinimum
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
Definition: qgsrectangle.h:151
QgsMapRendererJob::takeRenderedItemResults
QgsRenderedItemResults * takeRenderedItemResults()
Takes the rendered item results from the map render job and returns them.
QgsMessageLog::logMessage
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
Definition: qgsmessagelog.cpp:27
qgsmaprendererjob.h
QgsMapCanvas::updateScale
void updateScale()
Emits signal scaleChanged to update scale in main window.
Definition: qgsmapcanvas.cpp:1490
QgsMapCanvas::theme
QString theme
Definition: qgsmapcanvas.h:102
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:442
QgsMapCanvas::setCanvasColor
void setCanvasColor(const QColor &_newVal)
Write property of QColor bgColor.
Definition: qgsmapcanvas.cpp:2538
QgsMapCanvas::setCenter
void setCenter(const QgsPointXY &center)
Set the center of the map canvas, in geographical coordinates.
Definition: qgsmapcanvas.cpp:1446
QgsMapCanvas::resizeEvent
void resizeEvent(QResizeEvent *e) override
Definition: qgsmapcanvas.cpp:2290
QgsMapLayer::id
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
Definition: qgsmaplayer.cpp:169
QgsMapCanvas::zRange
QgsDoubleRange zRange() const
Returns the range of z-values which will be visible in the map.
Definition: qgsmapcanvas.cpp:1665
QgsMapCanvas::labelingEngineSettings
const QgsLabelingEngineSettings & labelingEngineSettings() const
Returns global labeling engine settings from the internal map settings.
Definition: qgsmapcanvas.cpp:3230
qgscoordinatereferencesystemutils.h
QgsMapCanvas::enableMapTileRendering
void enableMapTileRendering(bool flag)
sets map tile rendering flag
Definition: qgsmapcanvas.cpp:329
QgsMapCanvas::zoomToFullExtent
void zoomToFullExtent()
Zoom to the full extent of all layers currently visible in the canvas.
Definition: qgsmapcanvas.cpp:1495
QgsMapCanvas::selectionColor
QColor selectionColor() const
Returns color for selected features.
Definition: qgsmapcanvas.cpp:2597
QgsMapToolPan
A map tool for panning the map.
Definition: qgsmaptoolpan.h:32
QgsGeometry::isNull
bool isNull
Definition: qgsgeometry.h:127
QgsMapSettings::scale
double scale() const
Returns the calculated map scale.
Definition: qgsmapsettings.cpp:458
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:279
QgsProject::mapThemeCollection
QgsMapThemeCollection mapThemeCollection
Definition: qgsproject.h:112
QgsDataProvider::PreviewContext::maxRenderingTimeMs
double maxRenderingTimeMs
Default maximum allowable render time, in ms.
Definition: qgsdataprovider.h:547
QgsMapCanvas::zoomToNextExtent
void zoomToNextExtent()
Zoom to the next extent (view)
Definition: qgsmapcanvas.cpp:1538
QgsMapCanvas::setReferencedExtent
bool setReferencedExtent(const QgsReferencedRectangle &extent) SIP_THROW(QgsCsException)
Sets the canvas to the specified extent.
Definition: qgsmapcanvas.cpp:1427
QgsRectangle::xMinimum
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:188
QgsMapLayerUtils::combinedExtent
static QgsRectangle combinedExtent(const QList< QgsMapLayer * > &layers, const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &transformContext)
Returns the combined extent of a list of layers.
Definition: qgsmaplayerutils.cpp:30
QgsMapCanvas::refreshAllLayers
void refreshAllLayers()
Reload all layers (including refreshing layer properties from their data sources),...
Definition: qgsmapcanvas.cpp:3160
QgsDistanceArea::setSourceCrs
void setSourceCrs(const QgsCoordinateReferenceSystem &crs, const QgsCoordinateTransformContext &context)
Sets source spatial reference system crs.
Definition: qgsdistancearea.cpp:83
QgsScopedQPainterState
Scoped object for saving and restoring a QPainter object's state.
Definition: qgsrendercontext.h:1336
QgsRenderedItemResults::transferResults
void transferResults(QgsRenderedItemResults *other, const QStringList &layerIds)
Transfers all results from an other QgsRenderedItemResults object where the items have layer IDs matc...
Definition: qgsrendereditemresults.cpp:158
QgsMapCanvas::setExtent
void setExtent(const QgsRectangle &r, bool magnified=false)
Sets the extent of the map canvas to the specified rectangle.
Definition: qgsmapcanvas.cpp:1359
qgsannotationlayer.h
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:2475
QgsMapCanvas::previewMode
QgsPreviewEffect::PreviewMode previewMode() const
Returns the current preview mode for the map canvas.
Definition: qgsmapcanvas.cpp:2925
QgsMapCanvas::getCoordinateTransform
const QgsMapToPixel * getCoordinateTransform()
Gets the current coordinate transform.
Definition: qgsmapcanvas.cpp:379
QgsMimeDataUtils::Uri
Definition: qgsmimedatautils.h:40
QgsFeatureRequest::setNoAttributes
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
Definition: qgsfeaturerequest.cpp:235
QgsMapCanvas::setParallelRenderingEnabled
void setParallelRenderingEnabled(bool enabled)
Set whether the layers are rendered in parallel or sequentially.
Definition: qgsmapcanvas.cpp:593
QgsMapCanvas::panToFeatureIds
void panToFeatureIds(QgsVectorLayer *layer, const QgsFeatureIds &ids, bool alwaysRecenter=true)
Centers canvas extent to feature ids.
Definition: qgsmapcanvas.cpp:1735
QgsAbstractGeometry::isEmpty
virtual bool isEmpty() const
Returns true if the geometry is empty.
Definition: qgsabstractgeometry.cpp:378
QgsGeometry::constGet
const QgsAbstractGeometry * constGet() const SIP_HOLDGIL
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
Definition: qgsgeometry.cpp:136
QgsFeatureIds
QSet< QgsFeatureId > QgsFeatureIds
Definition: qgsfeatureid.h:37
QgsMapLayer::rendererChanged
void rendererChanged()
Signal emitted when renderer is changed.
QgsMapTool::activate
virtual void activate()
called when set as currently active map tool
Definition: qgsmaptool.cpp:94
QgsMapCanvas::keyPressEvent
void keyPressEvent(QKeyEvent *e) override
Definition: qgsmapcanvas.cpp:1955
Qgis::MapSettingsFlag::HighQualityImageTransforms
@ HighQualityImageTransforms
Enable high quality image transformations, which results in better appearance of scaled or rotated ra...
QgsMapCanvas::zoomToFeatureExtent
void zoomToFeatureExtent(QgsRectangle &rect)
Zooms to feature extent.
Definition: qgsmapcanvas.cpp:1687
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:1265
QgsCoordinateReferenceSystem
This class represents a coordinate reference system (CRS).
Definition: qgscoordinatereferencesystem.h:211
QgsDataProvider::renderInPreview
virtual bool renderInPreview(const QgsDataProvider::PreviewContext &context)
Returns whether the layer must be rendered in preview jobs.
Definition: qgsdataprovider.cpp:76
QgsRectangle::setXMaximum
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
Definition: qgsrectangle.h:156
QgsTemporalNavigationObject
Implements a temporal controller based on a frame by frame navigation and animation.
Definition: qgstemporalnavigationobject.h:39
QgsSnappingUtils
This class has all the configuration of snapping and can return answers to snapping queries.
Definition: qgssnappingutils.h:50
QgsMapSettings::selectionColor
QColor selectionColor() const
Returns the color that is used for drawing of selected vector features.
Definition: qgsmapsettings.h:402
QgsMapSettingsUtils::worldFileContent
static QString worldFileContent(const QgsMapSettings &mapSettings)
Creates the content of a world file.
Definition: qgsmapsettingsutils.cpp:130
QgsMapCanvas::setRenderFlag
void setRenderFlag(bool flag)
Sets whether a user has disabled canvas renders via the GUI.
Definition: qgsmapcanvas.cpp:2674
QgsMapCanvas::mapUpdateInterval
int mapUpdateInterval() const
Find out how often map preview should be updated while it is being rendered (in milliseconds)
Definition: qgsmapcanvas.cpp:608
QgsExpressionContextScope
Single scope for storing variables and functions for use within a QgsExpressionContext....
Definition: qgsexpressioncontext.h:113
QgsApplication::svgCache
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
Definition: qgsapplication.cpp:2360
QgsMapSettings::setLabelingEngineSettings
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets the global configuration of the labeling engine.
Definition: qgsmapsettings.h:654
QgsMapSettings::setLayers
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers to render in the map.
Definition: qgsmapsettings.cpp:327
QgsMapCanvas::setScaleLocked
void setScaleLocked(bool isLocked)
Lock the scale, so zooming can be performed using magnication.
Definition: qgsmapcanvas.cpp:2434
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:1853
QgsMapTool::canvasToolTipEvent
virtual bool canvasToolTipEvent(QHelpEvent *e)
Tooltip event for overriding.
Definition: qgsmaptool.cpp:209
qgsvectorlayer.h
QgsPointXY
A class to represent a 2D point.
Definition: qgspointxy.h:58
QgsMapSettings::destinationCrs
QgsCoordinateReferenceSystem destinationCrs() const
Returns the destination coordinate reference system for the map render.
Definition: qgsmapsettings.cpp:358
qgsmaprenderersequentialjob.h
QgsMapRendererCustomPainterJob
Job implementation that renders everything sequentially using a custom painter.
Definition: qgsmaprenderercustompainterjob.h:63
QgsRectangle::setYMaximum
void setYMaximum(double y) SIP_HOLDGIL
Set the maximum y value.
Definition: qgsrectangle.h:166
qgsmapcanvassnappingutils.h
QgsGeometry::asPoint
QgsPointXY asPoint() const
Returns the contents of the geometry as a 2-dimensional point.
Definition: qgsgeometry.cpp:1662
QgsMapSettings::setDpiTarget
void setDpiTarget(double dpi)
Sets the target dpi (dots per inch) to be taken into consideration when rendering.
Definition: qgsmapsettings.cpp:284
QgsMapCanvas::removeInteractionBlocker
void removeInteractionBlocker(QgsMapCanvasInteractionBlocker *blocker)
Removes an interaction blocker from the canvas.
Definition: qgsmapcanvas.cpp:1225
QgsMapTool::canvasPressEvent
virtual void canvasPressEvent(QgsMapMouseEvent *e)
Mouse press event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:178
QgsMapCanvas::setMapUpdateInterval
void setMapUpdateInterval(int timeMilliseconds)
Set how often map preview should be updated while it is being rendered (in milliseconds)
Definition: qgsmapcanvas.cpp:603
QgsMapSettings::setExpressionContext
void setExpressionContext(const QgsExpressionContext &context)
Sets the expression context.
Definition: qgsmapsettings.h:479
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:1215
QgsMapMouseEvent
A QgsMapMouseEvent is the result of a user interaction with the mouse on a QgsMapCanvas....
Definition: qgsmapmouseevent.h:35
QgsMapCanvas::clearExtentHistory
void clearExtentHistory()
Clears the list of extents and sets current extent as first item.
Definition: qgsmapcanvas.cpp:1553
QgsMapTool::canvasMoveEvent
virtual void canvasMoveEvent(QgsMapMouseEvent *e)
Mouse move event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:168
QgsWkbTypes::LineGeometry
@ LineGeometry
Definition: qgswkbtypes.h:143
QgsMapCanvas::layers
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers shown within the map canvas.
Definition: qgsmapcanvas.cpp:2607
QgsMapRendererQImageJob
Intermediate base class adding functionality that allows client to query the rendered image.
Definition: qgsmaprendererjob.h:653
QgsWkbTypes::PointGeometry
@ PointGeometry
Definition: qgswkbtypes.h:142
QgsDoubleRange
QgsRange which stores a range of double values.
Definition: qgsrange.h:202
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:3134
QgsCoordinateReferenceSystem::mapUnits
QgsUnitTypes::DistanceUnit mapUnits
Definition: qgscoordinatereferencesystem.h:215
QgsRubberBand::setWidth
void setWidth(int width)
Sets the width of the line.
Definition: qgsrubberband.cpp:78
QgsRectangle::yMaximum
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:193
QgsMapRendererJob::settingsLogCanvasRefreshEvent
static const QgsSettingsEntryBool settingsLogCanvasRefreshEvent
Settings entry log canvas refresh event.
Definition: qgsmaprendererjob.h:452
QgsTemporaryCursorOverride::release
void release()
Releases the cursor override early (i.e.
Definition: qgsguiutils.cpp:348
QgsMapCanvas::setAnnotationsVisible
void setAnnotationsVisible(bool visible)
Sets whether annotations are visible in the canvas.
Definition: qgsmapcanvas.cpp:3215
QgsMapCanvas::canvasColorChanged
void canvasColorChanged()
Emitted when canvas background color changes.
QgsFeatureRenderer
Definition: qgsrenderer.h:101
QgsMimeDataUtils::decodeUriList
static UriList decodeUriList(const QMimeData *data)
Definition: qgsmimedatautils.cpp:229
QgsWkbTypes::GeometryType
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
Definition: qgswkbtypes.h:140
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:936
Qgis::CoordinateOrder::YX
@ YX
Northing/Easting (or Latitude/Longitude for geographic CRS)
QgsFeatureIterator::nextFeature
bool nextFeature(QgsFeature &f)
Definition: qgsfeatureiterator.h:399
QgsRectangle::setYMinimum
void setYMinimum(double y) SIP_HOLDGIL
Set the minimum y value.
Definition: qgsrectangle.h:161
QgsMapCanvas::themeChanged
void themeChanged(const QString &theme)
Emitted when the canvas has been assigned a different map theme.
QgsMapRendererJob::layersRedrawnFromCache
QStringList layersRedrawnFromCache() const
Returns a list of the layer IDs for all layers which were redrawn from cached images.
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
A geometry is the spatial representation of a feature.
Definition: qgsgeometry.h:124
QgsMapCanvas::previewJobsEnabled
bool previewJobsEnabled
Definition: qgsmapcanvas.h:103
QgsMapToPixel
Perform transforms between map coordinates and device coordinates.
Definition: qgsmaptopixel.h:38
QgsMapSettings::setLayerStyleOverrides
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Sets the map of map layer style overrides (key: layer ID, value: style name) where a different style ...
Definition: qgsmapsettings.cpp:345
QgsVectorLayer
Represents a vector layer which manages a vector based data sets.
Definition: qgsvectorlayer.h:391
QgsFeature::hasGeometry
bool hasGeometry() const
Returns true if the feature has an associated geometry.
Definition: qgsfeature.cpp:230
QgsRectangle::width
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
Definition: qgsrectangle.h:223
QgsFeatureRequest::setLimit
QgsFeatureRequest & setLimit(long long limit)
Set the maximum number of features to request.
Definition: qgsfeaturerequest.cpp:216
qgsimagecache.h
QgsMapCanvas::isCachingEnabled
bool isCachingEnabled() const
Check whether images of rendered layers are curerently being cached.
Definition: qgsmapcanvas.cpp:577
QgsMapCanvas::selectionChanged
void selectionChanged(QgsVectorLayer *layer)
Emitted when selection in any layer gets changed.
QgsMapTool::canvasReleaseEvent
virtual void canvasReleaseEvent(QgsMapMouseEvent *e)
Mouse release event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:183
QgsMapLayer
Base class for all map layer types. This is the base class for all map layer types (vector,...
Definition: qgsmaplayer.h:72
QgsMapCanvas::isFrozen
bool isFrozen() const
Returns true if canvas is frozen.
Definition: qgsmapcanvas.cpp:2623
QgsMapCanvas::project
QgsProject * project()
Returns the project linked to this canvas.
Definition: qgsmapcanvas.cpp:2774
QgsVector
A class to represent a vector. Currently no Z axis / 2.5D support is implemented.
Definition: qgsvector.h:29
QgsMapCanvas::magnificationChanged
void magnificationChanged(double)
Emitted when the scale of the map changes.
QgsPointXY::x
double x
Definition: qgspointxy.h:62
QgsMapCanvas::zoomOutFactor
double zoomOutFactor() const
Returns the zoom in factor.
Definition: qgsmapcanvas.cpp:3374
QgsCustomDropHandler
Abstract base class that may be implemented to handle new types of data to be dropped in QGIS.
Definition: qgscustomdrophandler.h:47
qgsmapoverviewcanvas.h
QgsScopedRuntimeProfile
Scoped object for logging of the runtime for a single operation or group of operations.
Definition: qgsruntimeprofiler.h:327
qgssettings.h
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:2905
QgsProjectViewSettings::defaultRotation
double defaultRotation() const
Returns the default map rotation (in clockwise degrees) for maps in the project.
Definition: qgsprojectviewsettings.cpp:134
QgsMapSettings::setFlags
void setFlags(Qgis::MapSettingsFlags flags)
Sets combination of flags that will be used for rendering.
Definition: qgsmapsettings.cpp:377
QgsMapCanvas::setPreviewModeEnabled
void setPreviewModeEnabled(bool previewEnabled)
Enables a preview mode for the map canvas.
Definition: qgsmapcanvas.cpp:2895
QgsMapRendererCache::clearCacheImage
void clearCacheImage(const QString &cacheKey)
Removes an image from the cache with matching cacheKey.
Definition: qgsmaprenderercache.cpp:310
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.
QgsRubberBand::setIcon
void setIcon(IconType icon)
Sets the icon type to highlight point geometries.
Definition: qgsrubberband.cpp:83
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:2515
QgsWkbTypes::geometryType
static GeometryType geometryType(Type type) SIP_HOLDGIL
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
Definition: qgswkbtypes.h:968
qgsdatumtransformdialog.h
QgsMapCanvas::mousePressEvent
void mousePressEvent(QMouseEvent *e) override
Definition: qgsmapcanvas.cpp:2170
QgsTemporalNavigationObject::NavigationOff
@ NavigationOff
Temporal navigation is disabled.
Definition: qgstemporalnavigationobject.h:53
QgsExpressionContextUtils::atlasScope
static QgsExpressionContextScope * atlasScope(const QgsLayoutAtlas *atlas)
Creates a new scope which contains variables and functions relating to a QgsLayoutAtlas.
Definition: qgsexpressioncontextutils.cpp:660
QgsMapCanvas::renderComplete
void renderComplete(QPainter *)
Emitted when the canvas has rendered.
QgsMapCanvas::CanvasProperties
Deprecated to be deleted, stuff from here should be moved elsewhere.
Definition: qgsmapcanvas.cpp:106
qgscustomdrophandler.h
QgsTemporalRangeObject::setTemporalRange
void setTemporalRange(const QgsDateTimeRange &range)
Sets the temporal range for the object.
Definition: qgstemporalrangeobject.cpp:35
qgssettingsregistrygui.h
QgsGeometry::boundingBox
QgsRectangle boundingBox() const
Returns the bounding box of the geometry.
Definition: qgsgeometry.cpp:1080
QgsDistanceArea
A general purpose distance and area calculator, capable of performing ellipsoid based calculations.
Definition: qgsdistancearea.h:52
QgsMapTool::wheelEvent
virtual void wheelEvent(QWheelEvent *e)
Mouse wheel event for overriding. Default implementation does nothing.
Definition: qgsmaptool.cpp:188
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
QgsCoordinateReferenceSystemUtils::axisDirectionToAbbreviatedString
static QString axisDirectionToAbbreviatedString(Qgis::CrsAxisDirection axis)
Returns a translated abbreviation representing an axis direction.
Definition: qgscoordinatereferencesystemutils.cpp:82
QgsFeature
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
Definition: qgsfeature.h:55
QgsMapCanvas::magnificationFactor
double magnificationFactor() const
Returns the magnification factor.
Definition: qgsmapcanvas.cpp:313
QgsPreviewEffect
A graphics effect which can be applied to a widget to simulate various printing and color blindness m...
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:614
QgsApplication::getThemeIcon
static QIcon getThemeIcon(const QString &name, const QColor &fillColor=QColor(), const QColor &strokeColor=QColor())
Helper to get a theme icon.
Definition: qgsapplication.cpp:693
QgsMapCanvas::setSnappingUtils
void setSnappingUtils(QgsSnappingUtils *utils)
Assign an instance of snapping utils to the map canvas.
Definition: qgsmapcanvas.cpp:2946
QgsMapThemeCollection::hasMapTheme
bool hasMapTheme(const QString &name) const
Returns whether a map theme with a matching name exists.
Definition: qgsmapthemecollection.cpp:257
QgsMapCanvas::contextMenuAboutToShow
void contextMenuAboutToShow(QMenu *menu, QgsMapMouseEvent *event)
Emitted before the map canvas context menu will be shown.
QgsDataProvider::PreviewContext::lastRenderingTimeMs
double lastRenderingTimeMs
Previous rendering time for the layer, in ms.
Definition: qgsdataprovider.h:544
QgsMapCanvas::zoomToFeatureIds
void zoomToFeatureIds(QgsVectorLayer *layer, const QgsFeatureIds &ids)
Set canvas extent to the bounding box of a set of features.
Definition: qgsmapcanvas.cpp:1711
QgsMapRendererJob::Errors
QList< QgsMapRendererJob::Error > Errors
Definition: qgsmaprendererjob.h:365
QgsMapCanvas::createExpressionContext
QgsExpressionContext createExpressionContext() const override
This method needs to be reimplemented in all classes which implement this interface and return an exp...
Definition: qgsmapcanvas.cpp:626
QgsImageCache::remoteImageFetched
void remoteImageFetched(const QString &url)
Emitted when the cache has finished retrieving an image file from a remote url.
QgsSettingsRegistryGui::settingsRespectScreenDPI
static const QgsSettingsEntryBool settingsRespectScreenDPI
Settings entry respect screen dpi.
Definition: qgssettingsregistrygui.h:49
QgsMapTool::AllowZoomRect
@ AllowZoomRect
Allow zooming by rectangle (by holding shift and dragging) while the tool is active.
Definition: qgsmaptool.h:114
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:3616
QgsRenderedItemResults
Stores collated details of rendered items during a map rendering operation.
Definition: qgsrendereditemresults.h:42
qgsmaprendererparalleljob.h
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:282
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:2031
QgsMapCanvas::setZRange
void setZRange(const QgsDoubleRange &range)
Sets the range of z-values which will be visible in the map.
Definition: qgsmapcanvas.cpp:1670
QgsMapCanvas::setLayers
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers that should be shown in the canvas.
Definition: qgsmapcanvas.cpp:384
QgsMapSettings::setOutputSize
void setOutputSize(QSize size)
Sets the size of the resulting map image, in pixels.
Definition: qgsmapsettings.cpp:244
QgsMapCanvas::installInteractionBlocker
void installInteractionBlocker(QgsMapCanvasInteractionBlocker *blocker)
Installs an interaction blocker onto the canvas, which may prevent certain map canvas interactions fr...
Definition: qgsmapcanvas.cpp:1220
qgslogger.h
QgsMapCanvas::panActionStart
void panActionStart(QPoint releasePoint)
Starts a pan action.
Definition: qgsmapcanvas.cpp:2798
qgsmapcanvasmap.h
QgsMapLayerElevationProperties::FlagDontInvalidateCachedRendersWhenRangeChanges
@ FlagDontInvalidateCachedRendersWhenRangeChanges
Any cached rendering will not be invalidated when z range context is modified.
Definition: qgsmaplayerelevationproperties.h:94
QgsMapCanvas::mapUnitsPerPixel
double mapUnitsPerPixel() const
Returns the mapUnitsPerPixel (map units per pixel) for the canvas.
Definition: qgsmapcanvas.cpp:2628
QgsMapSettings::setPathResolver
void setPathResolver(const QgsPathResolver &resolver)
Sets the path resolver for conversion between relative and absolute paths during rendering operations...
Definition: qgsmapsettings.h:525
Qgis::RendererUsage::View
@ View
Renderer used for displaying on screen.
QgsMapSettings
The QgsMapSettings class contains configuration for rendering of the map. The rendering itself is don...
Definition: qgsmapsettings.h:88
QgsMapSettings::visibleExtent
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
Definition: qgsmapsettings.cpp:411
QgsCoordinateReferenceSystem::updateDefinition
void updateDefinition()
Updates the definition and parameters of the coordinate reference system to their latest values.
Definition: qgscoordinatereferencesystem.cpp:1498
QgsMapRendererCache::invalidateCacheForLayer
void invalidateCacheForLayer(QgsMapLayer *layer)
Invalidates cached images which relate to the specified map layer.
Definition: qgsmaprenderercache.cpp:288
QgsCoordinateTransform
Class for doing transforms between two map coordinate systems.
Definition: qgscoordinatetransform.h:57
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:3199
QgsFeatureIterator
Wrapper for iterator of features from vector data provider or vector layer.
Definition: qgsfeatureiterator.h:289
QgsMapSettings::layerToMapCoordinates
QgsPointXY layerToMapCoordinates(const QgsMapLayer *layer, QgsPointXY point) const
transform point coordinates from layer's CRS to output CRS
Definition: qgsmapsettings.cpp:578
QgsMapSettings::setExtent
void setExtent(const QgsRectangle &rect, bool magnified=true)
Sets the coordinates of the rectangle which should be rendered.
Definition: qgsmapsettings.cpp:80
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:73
QgsRectangle::isEmpty
bool isEmpty() const
Returns true if the rectangle is empty.
Definition: qgsrectangle.h:469
QgsMapTool::EditTool
@ EditTool
Map tool is an edit tool, which can only be used when layer is editable.
Definition: qgsmaptool.h:113
QgsCoordinateReferenceSystem::MediumString
@ MediumString
A medium-length string, recommended for general purpose use.
Definition: qgscoordinatereferencesystem.h:633
qgscoordinatereferencesystemregistry.h
QgsMapTool::ShowContextMenu
@ ShowContextMenu
Show a context menu when right-clicking with the tool (since QGIS 3.14). See populateContextMenu().
Definition: qgsmaptool.h:115
QgsMapSettings::mapToPixel
const QgsMapToPixel & mapToPixel() const
Definition: qgsmapsettings.h:527
QgsRectangle::isNull
bool isNull() const
Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
Definition: qgsrectangle.h:479
QgsTemporalProperty::FlagDontInvalidateCachedRendersWhenRangeChanges
@ FlagDontInvalidateCachedRendersWhenRangeChanges
Any cached rendering will not be invalidated when temporal range context is modified.
Definition: qgstemporalproperty.h:46
qgsproject.h
QgsTemporalNavigationObject::FixedRange
@ FixedRange
Temporal navigation relies on a fixed datetime range.
Definition: qgstemporalnavigationobject.h:55
QgsMapLayer::elevationProperties
virtual QgsMapLayerElevationProperties * elevationProperties()
Returns the layer's elevation properties.
Definition: qgsmaplayer.h:1509
QgsMapCanvas::setLayerStyleOverrides
void setLayerStyleOverrides(const QMap< QString, QString > &overrides)
Sets the stored overrides of styles for rendering layers.
Definition: qgsmapcanvas.cpp:2643
QgsMapLayer::autoRefreshIntervalChanged
void autoRefreshIntervalChanged(int interval)
Emitted when the auto refresh interval changes.
QgsDistanceArea::bearing
double bearing(const QgsPointXY &p1, const QgsPointXY &p2) const SIP_THROW(QgsCsException)
Computes the bearing (in radians) between two points.
Definition: qgsdistancearea.cpp:843
QgsMapCanvas::setMapSettingsFlags
void setMapSettingsFlags(Qgis::MapSettingsFlags flags)
Resets the flags for the canvas' map settings.
Definition: qgsmapcanvas.cpp:531
QgsMapSettings::layers
QList< QgsMapLayer * > layers(bool expandGroupLayers=false) const
Returns the list of layers which will be rendered in the map.
Definition: qgsmapsettings.cpp:299
QgsTemporaryCursorOverride
Temporarily sets a cursor override for the QApplication for the lifetime of the object.
Definition: qgsguiutils.h:220
QgsMapCanvas::zoomInFactor
double zoomInFactor() const
Returns the zoom in factor.
Definition: qgsmapcanvas.cpp:3361
qgsmaplayerelevationproperties.h
QgsMimeDataUtils::isUriList
static bool isUriList(const QMimeData *data)
Definition: qgsmimedatautils.cpp:215
qgsrendereditemresults.h
QgsPreviewEffect::mode
PreviewMode mode() const
Returns the mode used for the preview effect.
Definition: qgsprevieweffect.h:74
QgsCoordinateReferenceSystemRegistry::userCrsChanged
void userCrsChanged(const QString &id)
Emitted whenever an existing user CRS definition is changed.
QgsMapCanvas::setCachingEnabled
void setCachingEnabled(bool enabled)
Set whether to cache images of rendered layers.
Definition: qgsmapcanvas.cpp:554
QgsMapCanvas::setLabelingEngineSettings
void setLabelingEngineSettings(const QgsLabelingEngineSettings &settings)
Sets global labeling engine settings in the internal map settings.
Definition: qgsmapcanvas.cpp:3225
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:526
Qgis::MapSettingsFlag::RenderMapTile
@ RenderMapTile
Draw map such that there are no problems between adjacent tiles.
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:2568
QgsMapCanvas::layerStateChange
void layerStateChange()
This slot is connected to the visibility change of one or more layers.
Definition: qgsmapcanvas.cpp:2612
QgsMapCanvas::stopRendering
void stopRendering()
stop rendering (if there is any right now)
Definition: qgsmapcanvas.cpp:1249
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:102
QgsMapTool::populateContextMenuWithEvent
virtual bool populateContextMenuWithEvent(QMenu *menu, QgsMapMouseEvent *event)
Allows the tool to populate and customize the given menu, prior to showing it in response to a right-...
Definition: qgsmaptool.cpp:255