QGIS API Documentation  3.14.0-Pi (9f7028fd23)
qgsquickmapcanvasmap.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsquickmapcanvasmap.cpp
3  --------------------------------------
4  Date : 10.12.2014
5  Copyright : (C) 2014 by Matthias Kuhn
6  Email : matthias (at) opengis.ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include <QQuickWindow>
17 #include <QScreen>
18 #include <QSGSimpleTextureNode>
19 #include <QtConcurrent>
20 
22 #include "qgsmessagelog.h"
23 #include "qgspallabeling.h"
24 #include "qgsproject.h"
25 #include "qgsvectorlayer.h"
26 #include "qgis.h"
27 
28 #include "qgsquickmapcanvasmap.h"
29 #include "qgsquickmapsettings.h"
31 
32 
34  : QQuickItem( parent )
35  , mMapSettings( new QgsQuickMapSettings() )
36 {
37  connect( this, &QQuickItem::windowChanged, this, &QgsQuickMapCanvasMap::onWindowChanged );
38  connect( &mRefreshTimer, &QTimer::timeout, this, &QgsQuickMapCanvasMap::refreshMap );
39  connect( &mMapUpdateTimer, &QTimer::timeout, this, &QgsQuickMapCanvasMap::renderJobUpdated );
40 
41  connect( mMapSettings.get(), &QgsQuickMapSettings::extentChanged, this, &QgsQuickMapCanvasMap::onExtentChanged );
42  connect( mMapSettings.get(), &QgsQuickMapSettings::layersChanged, this, &QgsQuickMapCanvasMap::onLayersChanged );
43 
46 
47  mMapUpdateTimer.setSingleShot( false );
48  mMapUpdateTimer.setInterval( 250 );
49  mRefreshTimer.setSingleShot( true );
50  setTransformOrigin( QQuickItem::TopLeft );
51  setFlags( QQuickItem::ItemHasContents );
52 }
53 
55 {
56  return mMapSettings.get();
57 }
58 
59 void QgsQuickMapCanvasMap::zoom( QPointF center, qreal scale )
60 {
61  QgsRectangle extent = mMapSettings->extent();
62  QgsPoint oldCenter( extent.center() );
63  QgsPoint mousePos( mMapSettings->screenToCoordinate( center ) );
64  QgsPointXY newCenter( mousePos.x() + ( ( oldCenter.x() - mousePos.x() ) * scale ),
65  mousePos.y() + ( ( oldCenter.y() - mousePos.y() ) * scale ) );
66 
67  // same as zoomWithCenter (no coordinate transformations are needed)
68  extent.scale( scale, &newCenter );
69  mMapSettings->setExtent( extent );
70  mNeedsRefresh = true;
71 }
72 
73 void QgsQuickMapCanvasMap::pan( QPointF oldPos, QPointF newPos )
74 {
75  QgsPoint start = mMapSettings->screenToCoordinate( oldPos.toPoint() );
76  QgsPoint end = mMapSettings->screenToCoordinate( newPos.toPoint() );
77 
78  double dx = end.x() - start.x();
79  double dy = end.y() - start.y();
80 
81  // modify the extent
82  QgsRectangle extent = mMapSettings->extent();
83 
84  extent.setXMinimum( extent.xMinimum() + dx );
85  extent.setXMaximum( extent.xMaximum() + dx );
86  extent.setYMaximum( extent.yMaximum() + dy );
87  extent.setYMinimum( extent.yMinimum() + dy );
88 
89  mMapSettings->setExtent( extent );
90  mNeedsRefresh = true;
91 }
92 
93 void QgsQuickMapCanvasMap::refreshMap()
94 {
95  stopRendering(); // if any...
96 
97  QgsMapSettings mapSettings = mMapSettings->mapSettings();
98 
99  //build the expression context
100  QgsExpressionContext expressionContext;
101  expressionContext << QgsExpressionContextUtils::globalScope()
103 
104  QgsProject *project = mMapSettings->project();
105  if ( project )
106  {
107  expressionContext << QgsExpressionContextUtils::projectScope( project );
108 
109  mapSettings.setLabelingEngineSettings( project->labelingEngineSettings() );
110  }
111 
112  mapSettings.setExpressionContext( expressionContext );
113 
114  // enables on-the-fly simplification of geometries to spend less time rendering
116  // with incremental rendering - enables updates of partially rendered layers (good for WMTS, XYZ layers)
117  mapSettings.setFlag( QgsMapSettings::RenderPartialOutput, mIncrementalRendering );
118 
119  // create the renderer job
120  Q_ASSERT( !mJob );
122 
123  if ( mIncrementalRendering )
124  mMapUpdateTimer.start();
125 
126  connect( mJob, &QgsMapRendererJob::renderingLayersFinished, this, &QgsQuickMapCanvasMap::renderJobUpdated );
127  connect( mJob, &QgsMapRendererJob::finished, this, &QgsQuickMapCanvasMap::renderJobFinished );
128  mJob->setCache( mCache );
129 
130  mJob->start();
131 
132  emit renderStarting();
133 }
134 
135 void QgsQuickMapCanvasMap::renderJobUpdated()
136 {
137  mImage = mJob->renderedImage();
138  mImageMapSettings = mJob->mapSettings();
139  mDirty = true;
140  // Temporarily freeze the canvas, we only need to reset the geometry but not trigger a repaint
141  bool freeze = mFreeze;
142  mFreeze = true;
143  updateTransform();
144  mFreeze = freeze;
145 
146  update();
147  emit mapCanvasRefreshed();
148 }
149 
150 void QgsQuickMapCanvasMap::renderJobFinished()
151 {
152  const QgsMapRendererJob::Errors errors = mJob->errors();
153  for ( const QgsMapRendererJob::Error &error : errors )
154  {
155  QgsMessageLog::logMessage( QStringLiteral( "%1 :: %2" ).arg( error.layerID, error.message ), tr( "Rendering" ) );
156  }
157 
158  // take labeling results before emitting renderComplete, so labeling map tools
159  // connected to signal work with correct results
160  delete mLabelingResults;
161  mLabelingResults = mJob->takeLabelingResults();
162 
163  mImage = mJob->renderedImage();
164  mImageMapSettings = mJob->mapSettings();
165 
166  // now we are in a slot called from mJob - do not delete it immediately
167  // so the class is still valid when the execution returns to the class
168  mJob->deleteLater();
169  mJob = nullptr;
170  mDirty = true;
171  mMapUpdateTimer.stop();
172 
173  // Temporarily freeze the canvas, we only need to reset the geometry but not trigger a repaint
174  bool freeze = mFreeze;
175  mFreeze = true;
176  updateTransform();
177  mFreeze = freeze;
178 
179  update();
180  emit mapCanvasRefreshed();
181 }
182 
183 void QgsQuickMapCanvasMap::onWindowChanged( QQuickWindow *window )
184 {
185  // FIXME? the above disconnect is done potentially on a nullptr
186  // cppcheck-suppress nullPointerRedundantCheck
187  disconnect( window, &QQuickWindow::screenChanged, this, &QgsQuickMapCanvasMap::onScreenChanged );
188  if ( window )
189  {
190  connect( window, &QQuickWindow::screenChanged, this, &QgsQuickMapCanvasMap::onScreenChanged );
191  onScreenChanged( window->screen() );
192  }
193 }
194 
195 void QgsQuickMapCanvasMap::onScreenChanged( QScreen *screen )
196 {
197  if ( screen )
198  mMapSettings->setOutputDpi( screen->physicalDotsPerInch() );
199 }
200 
201 void QgsQuickMapCanvasMap::onExtentChanged()
202 {
203  updateTransform();
204 
205  // And trigger a new rendering job
206  refresh();
207 }
208 
209 void QgsQuickMapCanvasMap::updateTransform()
210 {
211  QgsMapSettings currentMapSettings = mMapSettings->mapSettings();
212  QgsMapToPixel mtp = currentMapSettings.mapToPixel();
213 
214  QgsRectangle imageExtent = mImageMapSettings.visibleExtent();
215  QgsRectangle newExtent = currentMapSettings.visibleExtent();
216  QgsPointXY pixelPt = mtp.transform( imageExtent.xMinimum(), imageExtent.yMaximum() );
217  setScale( imageExtent.width() / newExtent.width() );
218 
219  setX( pixelPt.x() );
220  setY( pixelPt.y() );
221 }
222 
224 {
225  return mMapUpdateTimer.interval();
226 }
227 
228 void QgsQuickMapCanvasMap::setMapUpdateInterval( int mapUpdateInterval )
229 {
230  if ( mMapUpdateTimer.interval() == mapUpdateInterval )
231  return;
232 
233  mMapUpdateTimer.setInterval( mapUpdateInterval );
234 
236 }
237 
239 {
240  return mIncrementalRendering;
241 }
242 
243 void QgsQuickMapCanvasMap::setIncrementalRendering( bool incrementalRendering )
244 {
245  if ( incrementalRendering == mIncrementalRendering )
246  return;
247 
248  mIncrementalRendering = incrementalRendering;
250 }
251 
252 bool QgsQuickMapCanvasMap::freeze() const
253 {
254  return mFreeze;
255 }
256 
258 {
259  if ( freeze == mFreeze )
260  return;
261 
262  mFreeze = freeze;
263 
264  if ( !mFreeze && mNeedsRefresh )
265  {
266  refresh();
267  }
268 
269  // we are freezing or unfreezing - either way we can reset "needs refresh"
270  mNeedsRefresh = false;
271 
272  emit freezeChanged();
273 }
274 
276 {
277  return mJob;
278 }
279 
280 QSGNode *QgsQuickMapCanvasMap::updatePaintNode( QSGNode *oldNode, QQuickItem::UpdatePaintNodeData * )
281 {
282  if ( mDirty )
283  {
284  delete oldNode;
285  oldNode = nullptr;
286  mDirty = false;
287  }
288 
289  QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>( oldNode );
290  if ( !node )
291  {
292  node = new QSGSimpleTextureNode();
293  QSGTexture *texture = window()->createTextureFromImage( mImage );
294  node->setTexture( texture );
295  node->setOwnsTexture( true );
296  }
297 
298  QRectF rect( boundingRect() );
299 
300  // Check for resizes that change the w/h ratio
301  if ( !rect.isEmpty() &&
302  !mImage.size().isEmpty() &&
303  !qgsDoubleNear( rect.width() / rect.height(), mImage.width() / mImage.height() ) )
304  {
305  if ( qgsDoubleNear( rect.height(), mImage.height() ) )
306  {
307  rect.setHeight( rect.width() / mImage.width() * mImage.height() );
308  }
309  else
310  {
311  rect.setWidth( rect.height() / mImage.height() * mImage.width() );
312  }
313  }
314 
315  node->setRect( rect );
316 
317  return node;
318 }
319 
320 void QgsQuickMapCanvasMap::geometryChanged( const QRectF &newGeometry, const QRectF &oldGeometry )
321 {
322  Q_UNUSED( oldGeometry )
323  // The Qt documentation advices to call the base method here.
324  // However, this introduces instabilities and heavy performance impacts on Android.
325  // It seems on desktop disabling it prevents us from downsizing the window...
326  // Be careful when re-enabling it.
327  // QQuickItem::geometryChanged( newGeometry, oldGeometry );
328 
329  mMapSettings->setOutputSize( newGeometry.size().toSize() );
330  refresh();
331 }
332 
333 void QgsQuickMapCanvasMap::onLayersChanged()
334 {
335  if ( mMapSettings->extent().isEmpty() )
336  zoomToFullExtent();
337 
338  for ( const QMetaObject::Connection &conn : qgis::as_const( mLayerConnections ) )
339  {
340  disconnect( conn );
341  }
342  mLayerConnections.clear();
343 
344  const QList<QgsMapLayer *> layers = mMapSettings->layers();
345  for ( QgsMapLayer *layer : layers )
346  {
347  mLayerConnections << connect( layer, &QgsMapLayer::repaintRequested, this, &QgsQuickMapCanvasMap::refresh );
348  }
349 
350  refresh();
351 }
352 
353 void QgsQuickMapCanvasMap::destroyJob( QgsMapRendererJob *job )
354 {
355  job->cancel();
356  job->deleteLater();
357 }
358 
360 {
361  if ( mJob )
362  {
363  disconnect( mJob, &QgsMapRendererJob::renderingLayersFinished, this, &QgsQuickMapCanvasMap::renderJobUpdated );
364  disconnect( mJob, &QgsMapRendererJob::finished, this, &QgsQuickMapCanvasMap::renderJobFinished );
365 
366  mJob->cancelWithoutBlocking();
367  mJob = nullptr;
368  }
369 }
370 
371 void QgsQuickMapCanvasMap::zoomToFullExtent()
372 {
373  QgsRectangle extent;
374  const QList<QgsMapLayer *> layers = mMapSettings->layers();
375  for ( QgsMapLayer *layer : layers )
376  {
377  if ( mMapSettings->destinationCrs() != layer->crs() )
378  {
379  QgsCoordinateTransform transform( layer->crs(), mMapSettings->destinationCrs(), mMapSettings->transformContext() );
380  extent.combineExtentWith( transform.transformBoundingBox( layer->extent() ) );
381  }
382  else
383  {
384  extent.combineExtentWith( layer->extent() );
385  }
386  }
387  mMapSettings->setExtent( extent );
388 
389  refresh();
390 }
391 
393 {
394  if ( mMapSettings->outputSize().isNull() )
395  return; // the map image size has not been set yet
396 
397  if ( !mFreeze )
398  mRefreshTimer.start( 1 );
399 }
QgsExpressionContext
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
Definition: qgsexpressioncontext.h:369
qgsexpressioncontextutils.h
QgsQuickMapCanvasMap::freeze
bool freeze
When freeze property is set to true, the map canvas does not refresh.
Definition: qgsquickmapcanvasmap.h:70
QgsPointXY::y
double y
Definition: qgspointxy.h:48
QgsMapRendererJob::Error
Definition: qgsmaprendererjob.h:250
qgspallabeling.h
QgsQuickMapCanvasMap::isRenderingChanged
void isRenderingChanged()
The isRendering property is set to true while a rendering job is pending for this map canvas map.
QgsMapRendererJob::mapSettings
const QgsMapSettings & mapSettings() const
Returns map settings with which this job was started.
QgsQuickMapSettings::extentChanged
void extentChanged()
Geographical coordinates of the rectangle that should be rendered.
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
QgsExpressionContextUtils::globalScope
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Definition: qgsexpressioncontextutils.cpp:33
QgsPoint
Point geometry type, with support for z-dimension and m-values.
Definition: qgspoint.h:37
QgsRectangle::setXMinimum
void setXMinimum(double x)
Set the minimum x value.
Definition: qgsrectangle.h:130
QgsMapRendererJob::renderingLayersFinished
void renderingLayersFinished()
Emitted when the layers are rendered.
QgsQuickMapCanvasMap::zoom
void zoom(QPointF center, qreal scale)
Set map setting's extent (zoom the map) on the center by given scale.
Definition: qgsquickmapcanvasmap.cpp:59
QgsQuickMapCanvasMap::mapUpdateInterval
int mapUpdateInterval
Interval in milliseconds after which the map canvas will be updated while a rendering job is ongoing.
Definition: qgsquickmapcanvasmap.h:84
QgsRectangle::xMaximum
double xMaximum() const
Returns the x maximum value (right side of rectangle).
Definition: qgsrectangle.h:162
QgsQuickMapCanvasMap::mapUpdateIntervalChanged
void mapUpdateIntervalChanged()
Interval in milliseconds after which the map canvas will be updated while a rendering job is ongoing.
qgis.h
QgsExpressionContextUtils::mapSettingsScope
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
Definition: qgsexpressioncontextutils.cpp:356
QgsMapSettings::RenderPartialOutput
@ RenderPartialOutput
Whether to make extra effort to update map image with partially rendered layers (better for interacti...
Definition: qgsmapsettings.h:311
QgsQuickMapCanvasMap::geometryChanged
void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override
Definition: qgsquickmapcanvasmap.cpp:320
QgsQuickMapCanvasMap::mapCanvasRefreshed
void mapCanvasRefreshed()
Emitted when the canvas is refreshed.
QgsQuickMapSettings::layersChanged
void layersChanged()
Set list of layers for map rendering.
QgsRectangle
Definition: qgsrectangle.h:41
QgsProject
Definition: qgsproject.h:92
qgsquickmapcanvasmap.h
QgsProject::labelingEngineSettings
const QgsLabelingEngineSettings & labelingEngineSettings() const
Returns project's global labeling engine settings.
Definition: qgsproject.cpp:1752
QgsQuickMapSettings
Definition: qgsquickmapsettings.h:46
QgsMapRendererJob::errors
Errors errors() const
List of errors that happened during the rendering job - available when the rendering has been finishe...
QgsQuickMapCanvasMap::setIncrementalRendering
void setIncrementalRendering(bool incrementalRendering)
When the incrementalRendering property is set to true, the automatic refresh of map canvas during ren...
Definition: qgsquickmapcanvasmap.cpp:243
QgsMapRendererParallelJob
Definition: qgsmaprendererparalleljob.h:32
QgsRectangle::scale
void scale(double scaleFactor, const QgsPointXY *c=nullptr)
Scale the rectangle around its center point.
Definition: qgsrectangle.h:235
QgsPoint::y
double y
Definition: qgspoint.h:59
QgsExpressionContextUtils::projectScope
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
Definition: qgsexpressioncontextutils.cpp:221
QgsMapRendererParallelJob::start
void start() override
Start the rendering job and immediately return.
Definition: qgsmaprendererparalleljob.cpp:43
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
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...
QgsMapRendererJob::setCache
void setCache(QgsMapRendererCache *cache)
Assign a cache to be used for reading and storing rendered images of individual layers.
QgsQuickMapCanvasMap::renderStarting
void renderStarting()
Emitted when a rendering is starting.
QgsQuickMapCanvasMap::pan
void pan(QPointF oldPos, QPointF newPos)
Set map setting's extent (pan the map) based on the difference of positions.
Definition: qgsquickmapcanvasmap.cpp:73
QgsRectangle::setXMaximum
void setXMaximum(double x)
Set the maximum x value.
Definition: qgsrectangle.h:135
QgsQuickMapCanvasMap::incrementalRenderingChanged
void incrementalRenderingChanged()
When the incrementalRendering property is set to true, the automatic refresh of map canvas during ren...
QgsQuickMapCanvasMap::incrementalRendering
bool incrementalRendering
When the incrementalRendering property is set to true, the automatic refresh of map canvas during ren...
Definition: qgsquickmapcanvasmap.h:89
QgsQuickMapCanvasMap::QgsQuickMapCanvasMap
QgsQuickMapCanvasMap(QQuickItem *parent=nullptr)
Create map canvas map.
Definition: qgsquickmapcanvasmap.cpp:33
QgsQuickMapCanvasMap::stopRendering
void stopRendering()
Stop map rendering.
Definition: qgsquickmapcanvasmap.cpp:359
QgsQuickMapCanvasMap::setMapUpdateInterval
void setMapUpdateInterval(int mapUpdateInterval)
Interval in milliseconds after which the map canvas will be updated while a rendering job is ongoing.
Definition: qgsquickmapcanvasmap.cpp:228
QgsMapToPixel::transform
QgsPointXY transform(const QgsPointXY &p) const
Transform the point from map (world) coordinates to device coordinates.
Definition: qgsmaptopixel.cpp:217
QgsRectangle::yMaximum
double yMaximum() const
Returns the y maximum value (top side of rectangle).
Definition: qgsrectangle.h:172
qgsvectorlayer.h
QgsMapRendererParallelJob::takeLabelingResults
QgsLabelingResults * takeLabelingResults() override
Gets pointer to internal labeling engine (in order to get access to the results).
Definition: qgsmaprendererparalleljob.cpp:202
QgsPointXY
Definition: qgspointxy.h:43
QgsMapSettings::UseRenderingOptimization
@ UseRenderingOptimization
Enable vector simplification and other rendering optimizations.
Definition: qgsmapsettings.h:307
QgsRectangle::center
QgsPointXY center() const
Returns the center point of the rectangle.
Definition: qgsrectangle.h:230
QgsMapToPixel
Definition: qgsmaptopixel.h:37
QgsMapLayer
Definition: qgsmaplayer.h:81
QgsPointXY::x
double x
Definition: qgspointxy.h:47
QgsQuickMapCanvasMap::freezeChanged
void freezeChanged()
When freeze property is set to true, the map canvas does not refresh.
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
QgsMapRendererJob
Definition: qgsmaprendererjob.h:186
QgsRectangle::yMinimum
double yMinimum() const
Returns the y minimum value (bottom side of rectangle).
Definition: qgsrectangle.h:177
QgsQuickMapCanvasMap::setFreeze
void setFreeze(bool freeze)
When freeze property is set to true, the map canvas does not refresh.
Definition: qgsquickmapcanvasmap.cpp:257
QgsQuickMapCanvasMap::updatePaintNode
QSGNode * updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) override
Definition: qgsquickmapcanvasmap.cpp:280
QgsMapRendererJob::Errors
QList< QgsMapRendererJob::Error > Errors
Definition: qgsmaprendererjob.h:261
qgsmaprendererparalleljob.h
QgsMapRendererJob::cancel
virtual void cancel()=0
Stop the rendering job - does not return until the job has terminated.
QgsQuickMapCanvasMap::isRendering
bool isRendering
The isRendering property is set to true while a rendering job is pending for this map canvas map.
Definition: qgsquickmapcanvasmap.h:77
QgsMapSettings
Definition: qgsmapsettings.h:86
QgsMapSettings::visibleExtent
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes takes output image size into accou...
Definition: qgsmapsettings.cpp:370
QgsCoordinateTransform
Definition: qgscoordinatetransform.h:52
QgsQuickMapCanvasMap::mapSettings
QgsQuickMapSettings mapSettings
The mapSettings property contains configuration for rendering of the map.
Definition: qgsquickmapcanvasmap.h:64
QgsMapRendererParallelJob::renderedImage
QImage renderedImage() override
Gets a preview/resulting image.
Definition: qgsmaprendererparalleljob.cpp:210
QgsMapRendererParallelJob::cancelWithoutBlocking
void cancelWithoutBlocking() override
Triggers cancellation of the rendering job without blocking.
Definition: qgsmaprendererparalleljob.cpp:120
qgsquickmapsettings.h
QgsMapSettings::mapToPixel
const QgsMapToPixel & mapToPixel() const
Definition: qgsmapsettings.h:433
QgsPoint::x
double x
Definition: qgspoint.h:58
qgsproject.h
QgsRectangle::width
double width() const
Returns the width of the rectangle.
Definition: qgsrectangle.h:202
QgsRectangle::setYMinimum
void setYMinimum(double y)
Set the minimum y value.
Definition: qgsrectangle.h:140
QgsRectangle::setYMaximum
void setYMaximum(double y)
Set the maximum y value.
Definition: qgsrectangle.h:145
QgsRectangle::xMinimum
double xMinimum() const
Returns the x minimum value (left side of rectangle).
Definition: qgsrectangle.h:167
qgsmessagelog.h
QgsMapRendererJob::finished
void finished()
emitted when asynchronous rendering is finished (or canceled).
QgsQuickMapCanvasMap::refresh
void refresh()
Refresh the map canvas.
Definition: qgsquickmapcanvasmap.cpp:392