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