QGIS API Documentation 3.41.0-Master (cea29feecf2)
Loading...
Searching...
No Matches
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 <QSGSimpleTextureNode>
18#include <QScreen>
19
20#include "qgis.h"
21#include "qgsannotationlayer.h"
23#include "qgsgrouplayer.h"
24#include "qgslabelingresults.h"
27#include "qgsmaprenderercache.h"
29#include "qgsmessagelog.h"
30#include "qgspallabeling.h"
31#include "qgsproject.h"
32#include "qgssymbollayerutils.h"
33#include "qgsvectorlayer.h"
34
36#include "moc_qgsquickmapcanvasmap.cpp"
37#include "qgsquickmapsettings.h"
38
39
41 : QQuickItem( parent )
42 , mMapSettings( std::make_unique<QgsQuickMapSettings>() )
43 , mCache( std::make_unique<QgsMapRendererCache>() )
44{
45 connect( this, &QQuickItem::windowChanged, this, &QgsQuickMapCanvasMap::onWindowChanged );
46 connect( &mRefreshTimer, &QTimer::timeout, this, [=] { refreshMap(); } );
47 connect( &mMapUpdateTimer, &QTimer::timeout, this, &QgsQuickMapCanvasMap::renderJobUpdated );
48
49 connect( mMapSettings.get(), &QgsQuickMapSettings::extentChanged, this, &QgsQuickMapCanvasMap::onExtentChanged );
50 connect( mMapSettings.get(), &QgsQuickMapSettings::layersChanged, this, &QgsQuickMapCanvasMap::onLayersChanged );
51 connect( mMapSettings.get(), &QgsQuickMapSettings::temporalStateChanged, this, &QgsQuickMapCanvasMap::onTemporalStateChanged );
52 connect( mMapSettings.get(), &QgsQuickMapSettings::zRangeChanged, this, &QgsQuickMapCanvasMap::onzRangeChanged );
53
56
57 mMapUpdateTimer.setSingleShot( false );
58 mMapUpdateTimer.setInterval( 250 );
59 mRefreshTimer.setSingleShot( true );
60 setTransformOrigin( QQuickItem::TopLeft );
61 setFlags( QQuickItem::ItemHasContents );
62}
63
65
67{
68 return mMapSettings.get();
69}
70
71void QgsQuickMapCanvasMap::zoom( QPointF center, qreal scale )
72{
73 QgsRectangle extent = mMapSettings->extent();
74 QgsPoint oldCenter( extent.center() );
75 QgsPoint mousePos( mMapSettings->screenToCoordinate( center ) );
76
77 QgsPointXY newCenter( mousePos.x() + ( ( oldCenter.x() - mousePos.x() ) * scale ), mousePos.y() + ( ( oldCenter.y() - mousePos.y() ) * scale ) );
78
79 // same as zoomWithCenter (no coordinate transformations are needed)
80 extent.scale( scale, &newCenter );
81 mMapSettings->setExtent( extent );
82}
83
84void QgsQuickMapCanvasMap::pan( QPointF oldPos, QPointF newPos )
85{
86 QgsPoint start = mMapSettings->screenToCoordinate( oldPos.toPoint() );
87 QgsPoint end = mMapSettings->screenToCoordinate( newPos.toPoint() );
88
89 double dx = end.x() - start.x();
90 double dy = end.y() - start.y();
91
92 // modify the extent
93 QgsRectangle extent = mMapSettings->extent();
94
95 extent.setXMinimum( extent.xMinimum() + dx );
96 extent.setXMaximum( extent.xMaximum() + dx );
97 extent.setYMaximum( extent.yMaximum() + dy );
98 extent.setYMinimum( extent.yMinimum() + dy );
99
100 mMapSettings->setExtent( extent );
101}
102
103void QgsQuickMapCanvasMap::refreshMap()
104{
105 stopRendering(); // if any...
106
107 if ( mCacheInvalidations.testFlag( CacheInvalidationType::Temporal ) )
108 {
109 clearTemporalCache();
110 mCacheInvalidations &= ~( static_cast<int>( CacheInvalidationType::Temporal ) );
111 }
112 if ( mCacheInvalidations.testFlag( CacheInvalidationType::Elevation ) )
113 {
114 clearElevationCache();
115 mCacheInvalidations &= ~( static_cast<int>( CacheInvalidationType::Elevation ) );
116 }
117
118 QgsMapSettings mapSettings = mMapSettings->mapSettings();
119 if ( !mapSettings.hasValidSettings() )
120 return;
121
122 //build the expression context
123 QgsExpressionContext expressionContext;
124 expressionContext << QgsExpressionContextUtils::globalScope()
126
127 QgsProject *project = mMapSettings->project();
128 if ( project )
129 {
130 expressionContext << QgsExpressionContextUtils::projectScope( project );
131
132 mapSettings.setLabelingEngineSettings( project->labelingEngineSettings() );
133
134 // render main annotation layer above all other layers
135 QList<QgsMapLayer *> allLayers = mapSettings.layers();
136 allLayers.insert( 0, project->mainAnnotationLayer() );
137 mapSettings.setLayers( allLayers );
138 }
139
140 mapSettings.setExpressionContext( expressionContext );
141
142 // enables on-the-fly simplification of geometries to spend less time rendering
144 // with incremental rendering - enables updates of partially rendered layers (good for WMTS, XYZ layers)
145 mapSettings.setFlag( Qgis::MapSettingsFlag::RenderPartialOutput, mIncrementalRendering );
146
147 // create the renderer job
148 Q_ASSERT( !mJob );
150
151 if ( mIncrementalRendering )
152 mMapUpdateTimer.start();
153
154 connect( mJob, &QgsMapRendererJob::renderingLayersFinished, this, &QgsQuickMapCanvasMap::renderJobUpdated );
155 connect( mJob, &QgsMapRendererJob::finished, this, &QgsQuickMapCanvasMap::renderJobFinished );
156 mJob->setCache( mCache.get() );
157
158 mJob->start();
159
160 if ( !mSilentRefresh )
161 {
162 emit renderStarting();
163 }
164}
165
166void QgsQuickMapCanvasMap::renderJobUpdated()
167{
168 if ( !mJob )
169 return;
170
171 mImage = mJob->renderedImage();
172 mImageMapSettings = mJob->mapSettings();
173 mDirty = true;
174 // Temporarily freeze the canvas, we only need to reset the geometry but not trigger a repaint
175 bool freeze = mFreeze;
176 mFreeze = true;
177 updateTransform();
178 mFreeze = freeze;
179
180 update();
181}
182
183void QgsQuickMapCanvasMap::renderJobFinished()
184{
185 if ( !mJob )
186 return;
187
188 const QgsMapRendererJob::Errors errors = mJob->errors();
189 for ( const QgsMapRendererJob::Error &error : errors )
190 {
191 QgsMessageLog::logMessage( QStringLiteral( "%1 :: %2" ).arg( error.layerID, error.message ), tr( "Rendering" ) );
192 }
193
194 // take labeling results before emitting renderComplete, so labeling map tools
195 // connected to signal work with correct results
196 delete mLabelingResults;
197 mLabelingResults = mJob->takeLabelingResults();
198
199 mImage = mJob->renderedImage();
200 mImageMapSettings = mJob->mapSettings();
201
202 // now we are in a slot called from mJob - do not delete it immediately
203 // so the class is still valid when the execution returns to the class
204 mJob->deleteLater();
205 mJob = nullptr;
206 mDirty = true;
207 mMapUpdateTimer.stop();
208
209 // Temporarily freeze the canvas, we only need to reset the geometry but not trigger a repaint
210 bool freeze = mFreeze;
211 mFreeze = true;
212 updateTransform();
213 mFreeze = freeze;
214
215 update();
216 if ( !mSilentRefresh )
217 {
218 emit mapCanvasRefreshed();
219 }
220 else
221 {
222 mSilentRefresh = false;
223 }
224
225 if ( mDeferredRefreshPending )
226 {
227 mDeferredRefreshPending = false;
228 mSilentRefresh = true;
229 refresh();
230 }
231}
232
233void QgsQuickMapCanvasMap::layerRepaintRequested( bool deferred )
234{
235 if ( mMapSettings->outputSize().isNull() )
236 return; // the map image size has not been set yet
237
238 if ( !mFreeze )
239 {
240 if ( deferred )
241 {
242 if ( !mJob )
243 {
244 mSilentRefresh = true;
245 refresh();
246 }
247 else
248 {
249 mDeferredRefreshPending = true;
250 }
251 }
252 else
253 {
254 refresh();
255 }
256 }
257}
258
259void QgsQuickMapCanvasMap::onWindowChanged( QQuickWindow *window )
260{
261 if ( mWindow == window )
262 return;
263
264 if ( mWindow )
265 disconnect( mWindow, &QQuickWindow::screenChanged, this, &QgsQuickMapCanvasMap::onScreenChanged );
266
267 if ( window )
268 {
269 connect( window, &QQuickWindow::screenChanged, this, &QgsQuickMapCanvasMap::onScreenChanged );
270 onScreenChanged( window->screen() );
271 }
272
273 mWindow = window;
274}
275
276void QgsQuickMapCanvasMap::onScreenChanged( QScreen *screen )
277{
278 if ( screen )
279 {
280 if ( screen->devicePixelRatio() > 0 )
281 {
282 mMapSettings->setDevicePixelRatio( screen->devicePixelRatio() );
283 }
284 mMapSettings->setOutputDpi( screen->physicalDotsPerInch() );
285 }
286}
287
288void QgsQuickMapCanvasMap::onExtentChanged()
289{
290 updateTransform();
291
292 // And trigger a new rendering job
293 refresh();
294}
295
296void QgsQuickMapCanvasMap::onTemporalStateChanged()
297{
298 mCacheInvalidations |= CacheInvalidationType::Temporal;
299
300 // And trigger a new rendering job
301 refresh();
302}
303
304void QgsQuickMapCanvasMap::onzRangeChanged()
305{
306 mCacheInvalidations |= CacheInvalidationType::Elevation;
307
308 // And trigger a new rendering job
309 refresh();
310}
311
312void QgsQuickMapCanvasMap::updateTransform()
313{
314 QgsRectangle imageExtent = mImageMapSettings.visibleExtent();
315 QgsRectangle newExtent = mMapSettings->mapSettings().visibleExtent();
316 setScale( imageExtent.width() / newExtent.width() );
317
318 QgsPointXY pixelPt = mMapSettings->coordinateToScreen( QgsPoint( imageExtent.xMinimum(), imageExtent.yMaximum() ) );
319 setX( pixelPt.x() );
320 setY( pixelPt.y() );
321}
322
324{
325 return mMapUpdateTimer.interval();
326}
327
329{
330 if ( mMapUpdateTimer.interval() == mapUpdateInterval )
331 return;
332
333 mMapUpdateTimer.setInterval( mapUpdateInterval );
334
336}
337
339{
340 return mIncrementalRendering;
341}
342
343void QgsQuickMapCanvasMap::setIncrementalRendering( bool incrementalRendering )
344{
345 if ( incrementalRendering == mIncrementalRendering )
346 return;
347
348 mIncrementalRendering = incrementalRendering;
350}
351
353{
354 return mFreeze;
355}
356
358{
359 if ( freeze == mFreeze )
360 return;
361
362 mFreeze = freeze;
363
364 if ( mFreeze )
366 else
367 refresh();
368
369 emit freezeChanged();
370}
371
373{
374 return mJob;
375}
376
377QSGNode *QgsQuickMapCanvasMap::updatePaintNode( QSGNode *oldNode, QQuickItem::UpdatePaintNodeData * )
378{
379 if ( mDirty )
380 {
381 delete oldNode;
382 oldNode = nullptr;
383 mDirty = false;
384 }
385
386 if ( mImage.isNull() )
387 {
388 return nullptr;
389 }
390
391 QSGSimpleTextureNode *node = static_cast<QSGSimpleTextureNode *>( oldNode );
392 if ( !node )
393 {
394 node = new QSGSimpleTextureNode();
395 QSGTexture *texture = window()->createTextureFromImage( mImage );
396 node->setTexture( texture );
397 node->setOwnsTexture( true );
398 }
399
400 QRectF rect( boundingRect() );
401 QSizeF size = mImage.size();
402 if ( !size.isEmpty() )
403 size /= mMapSettings->devicePixelRatio();
404
405 // Check for resizes that change the w/h ratio
406 if ( !rect.isEmpty() && !size.isEmpty() && !qgsDoubleNear( rect.width() / rect.height(), ( size.width() ) / static_cast<double>( size.height() ), 3 ) )
407 {
408 if ( qgsDoubleNear( rect.height(), mImage.height() ) )
409 {
410 rect.setHeight( rect.width() / size.width() * size.height() );
411 }
412 else
413 {
414 rect.setWidth( rect.height() / size.height() * size.width() );
415 }
416 }
417
418 node->setRect( rect );
419
420 return node;
421}
422
423#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 )
424void QgsQuickMapCanvasMap::geometryChanged( const QRectF &newGeometry, const QRectF &oldGeometry )
425{
426 QQuickItem::geometryChanged( newGeometry, oldGeometry );
427#else
428void QgsQuickMapCanvasMap::geometryChange( const QRectF &newGeometry, const QRectF &oldGeometry )
429{
430 QQuickItem::geometryChange( newGeometry, oldGeometry );
431#endif
432 if ( newGeometry.size() != oldGeometry.size() )
433 {
434 mMapSettings->setOutputSize( newGeometry.size().toSize() );
435 refresh();
436 }
437}
438
439void QgsQuickMapCanvasMap::onLayersChanged()
440{
441 if ( mMapSettings->extent().isEmpty() )
442 zoomToFullExtent();
443
444 for ( const QMetaObject::Connection &conn : std::as_const( mLayerConnections ) )
445 {
446 disconnect( conn );
447 }
448 mLayerConnections.clear();
449
450 const QList<QgsMapLayer *> layers = mMapSettings->layers();
451 for ( QgsMapLayer *layer : layers )
452 {
453 mLayerConnections << connect( layer, &QgsMapLayer::repaintRequested, this, &QgsQuickMapCanvasMap::layerRepaintRequested );
454 }
455
456 refresh();
457}
458
459void QgsQuickMapCanvasMap::destroyJob( QgsMapRendererJob *job )
460{
461 job->cancel();
462 job->deleteLater();
463}
464
466{
467 if ( mJob )
468 {
469 disconnect( mJob, &QgsMapRendererJob::renderingLayersFinished, this, &QgsQuickMapCanvasMap::renderJobUpdated );
470 disconnect( mJob, &QgsMapRendererJob::finished, this, &QgsQuickMapCanvasMap::renderJobFinished );
471
472 mJob->cancelWithoutBlocking();
473 mJob = nullptr;
474 }
475}
476
477void QgsQuickMapCanvasMap::zoomToFullExtent()
478{
479 QgsRectangle extent;
480 const QList<QgsMapLayer *> layers = mMapSettings->layers();
481 for ( QgsMapLayer *layer : layers )
482 {
483 if ( mMapSettings->destinationCrs() != layer->crs() )
484 {
485 QgsCoordinateTransform transform( layer->crs(), mMapSettings->destinationCrs(), mMapSettings->transformContext() );
486 try
487 {
488 extent.combineExtentWith( transform.transformBoundingBox( layer->extent() ) );
489 }
490 catch ( const QgsCsException &exp )
491 {
492 // Ignore extent if it can't be transformed
493 }
494 }
495 else
496 {
497 extent.combineExtentWith( layer->extent() );
498 }
499 }
500 mMapSettings->setExtent( extent );
501
502 refresh();
503}
504
506{
507 if ( mMapSettings->outputSize().isNull() )
508 return; // the map image size has not been set yet
509
510 if ( !mFreeze )
511 mRefreshTimer.start( 1 );
512}
513
515{
516 if ( mCache )
517 mCache->clear();
518}
519
520void QgsQuickMapCanvasMap::clearTemporalCache()
521{
522 if ( mCache )
523 {
524 bool invalidateLabels = false;
525 const QList<QgsMapLayer *> layerList = mMapSettings->mapSettings().layers();
526 for ( QgsMapLayer *layer : layerList )
527 {
528 bool alreadyInvalidatedThisLayer = false;
529 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer ) )
530 {
531 if ( vl->renderer() && QgsSymbolLayerUtils::rendererFrameRate( vl->renderer() ) > -1 )
532 {
533 // layer has an animated symbol assigned, so we have to redraw it regardless of whether
534 // or not it has temporal settings
535 mCache->invalidateCacheForLayer( layer );
536 alreadyInvalidatedThisLayer = true;
537 // we can't shortcut and "continue" here, as we still need to check whether the layer
538 // will cause label invalidation using the logic below
539 }
540 }
541
542 if ( layer->temporalProperties() && layer->temporalProperties()->isActive() )
543 {
544 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer ) )
545 {
546 if ( vl->labelsEnabled() || vl->diagramsEnabled() )
547 invalidateLabels = true;
548 }
549
550 if ( layer->temporalProperties()->flags() & QgsTemporalProperty::FlagDontInvalidateCachedRendersWhenRangeChanges )
551 continue;
552
553 if ( !alreadyInvalidatedThisLayer )
554 mCache->invalidateCacheForLayer( layer );
555 }
556 else if ( QgsGroupLayer *gl = qobject_cast<QgsGroupLayer *>( layer ) )
557 {
558 const QList<QgsMapLayer *> childLayerList = gl->childLayers();
559 for ( QgsMapLayer *childLayer : childLayerList )
560 {
561 if ( childLayer->temporalProperties() && childLayer->temporalProperties()->isActive() )
562 {
563 if ( childLayer->temporalProperties()->flags() & QgsTemporalProperty::FlagDontInvalidateCachedRendersWhenRangeChanges )
564 continue;
565
566 mCache->invalidateCacheForLayer( layer );
567 break;
568 }
569 }
570 }
571 }
572
573 if ( invalidateLabels )
574 {
575 mCache->clearCacheImage( QStringLiteral( "_labels_" ) );
576 mCache->clearCacheImage( QStringLiteral( "_preview_labels_" ) );
577 }
578 }
579}
580
581void QgsQuickMapCanvasMap::clearElevationCache()
582{
583 if ( mCache )
584 {
585 bool invalidateLabels = false;
586 const QList<QgsMapLayer *> layerList = mMapSettings->mapSettings().layers();
587 for ( QgsMapLayer *layer : layerList )
588 {
589 if ( layer->elevationProperties() && layer->elevationProperties()->hasElevation() )
590 {
591 if ( QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer ) )
592 {
593 if ( vl->labelsEnabled() || vl->diagramsEnabled() )
594 invalidateLabels = true;
595 }
596
598 continue;
599
600 mCache->invalidateCacheForLayer( layer );
601 }
602 else if ( QgsGroupLayer *gl = qobject_cast<QgsGroupLayer *>( layer ) )
603 {
604 const QList<QgsMapLayer *> childLayerList = gl->childLayers();
605 for ( QgsMapLayer *childLayer : childLayerList )
606 {
607 if ( childLayer->elevationProperties() && childLayer->elevationProperties()->hasElevation() )
608 {
609 if ( childLayer->elevationProperties()->flags() & QgsMapLayerElevationProperties::FlagDontInvalidateCachedRendersWhenRangeChanges )
610 continue;
611
612 mCache->invalidateCacheForLayer( layer );
613 break;
614 }
615 }
616 }
617 }
618
619 if ( invalidateLabels )
620 {
621 mCache->clearCacheImage( QStringLiteral( "_labels_" ) );
622 mCache->clearCacheImage( QStringLiteral( "_preview_labels_" ) );
623 }
624 }
625}
@ UseRenderingOptimization
Enable vector simplification and other rendering optimizations.
@ RenderPartialOutput
Whether to make extra effort to update map image with partially rendered layers (better for interacti...
Class for doing transforms between two map coordinate systems.
Custom exception class for Coordinate Reference System related exceptions.
static QgsExpressionContextScope * projectScope(const QgsProject *project)
Creates a new scope which contains variables and functions relating to a QGIS project.
static QgsExpressionContextScope * mapSettingsScope(const QgsMapSettings &mapSettings)
Creates a new scope which contains variables and functions relating to a QgsMapSettings object.
static QgsExpressionContextScope * globalScope()
Creates a new scope which contains variables and functions relating to the global QGIS context.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
A map layer which consists of a set of child layers, where all component layers are rendered as a sin...
@ FlagDontInvalidateCachedRendersWhenRangeChanges
Any cached rendering will not be invalidated when z range context is modified.
Base class for all map layer types.
Definition qgsmaplayer.h:76
void repaintRequested(bool deferredUpdate=false)
By emitting this signal the layer tells that either appearance or content have been changed and any v...
This class is responsible for keeping cache of rendered images resulting from a map rendering job.
Abstract base class for map rendering implementations.
void setCache(QgsMapRendererCache *cache)
Assign a cache to be used for reading and storing rendered images of individual layers.
Errors errors() const
List of errors that happened during the rendering job - available when the rendering has been finishe...
void renderingLayersFinished()
Emitted when the layers are rendered.
const QgsMapSettings & mapSettings() const
Returns map settings with which this job was started.
void finished()
emitted when asynchronous rendering is finished (or canceled).
void start()
Start the rendering job and immediately return.
QList< QgsMapRendererJob::Error > Errors
virtual void cancel()=0
Stop the rendering job - does not return until the job has terminated.
Job implementation that renders all layers in parallel.
QgsLabelingResults * takeLabelingResults() override
Gets pointer to internal labeling engine (in order to get access to the results).
void cancelWithoutBlocking() override
Triggers cancellation of the rendering job without blocking.
QImage renderedImage() override
Gets a preview/resulting image.
The QgsMapSettings class contains configuration for rendering of the map.
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes output image size into account.
static void logMessage(const QString &message, const QString &tag=QString(), Qgis::MessageLevel level=Qgis::MessageLevel::Warning, bool notifyUser=true)
Adds a message to the log instance (and creates it if necessary).
A class to represent a 2D point.
Definition qgspointxy.h:60
double y
Definition qgspointxy.h:64
double x
Definition qgspointxy.h:63
Point geometry type, with support for z-dimension and m-values.
Definition qgspoint.h:49
double x
Definition qgspoint.h:52
double y
Definition qgspoint.h:53
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
Definition qgsproject.h:107
QgsAnnotationLayer * mainAnnotationLayer()
Returns the main annotation layer associated with the project.
const QgsLabelingEngineSettings & labelingEngineSettings() const
Returns project's global labeling engine settings.
void freezeChanged()
When freeze property is set to true, the map canvas does not refresh.
bool isRendering
The isRendering property is set to true while a rendering job is pending for this map canvas map.
void mapCanvasRefreshed()
Signal is emitted when a canvas is refreshed.
void incrementalRenderingChanged()
When the incrementalRendering property is set to true, the automatic refresh of map canvas during ren...
int mapUpdateInterval
Interval in milliseconds after which the map canvas will be updated while a rendering job is ongoing.
void setMapUpdateInterval(int mapUpdateInterval)
Interval in milliseconds after which the map canvas will be updated while a rendering job is ongoing.
void pan(QPointF oldPos, QPointF newPos)
Set map setting's extent (pan the map) based on the difference of positions.
void renderStarting()
Signal is emitted when a rendering is starting.
void stopRendering()
Stop map rendering.
void zoom(QPointF center, qreal scale)
Set map setting's extent (zoom the map) on the center by given scale.
void setIncrementalRendering(bool incrementalRendering)
When the incrementalRendering property is set to true, the automatic refresh of map canvas during ren...
void clearCache()
Clears rendering cache.
void setFreeze(bool freeze)
When freeze property is set to true, the map canvas does not refresh.
QgsQuickMapSettings * mapSettings
The mapSettings property contains configuration for rendering of the map.
void refresh()
Refresh the map canvas.
QSGNode * updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *) override
void mapUpdateIntervalChanged()
Interval in milliseconds after which the map canvas will be updated while a rendering job is ongoing.
bool incrementalRendering
When the incrementalRendering property is set to true, the automatic refresh of map canvas during ren...
bool freeze
When freeze property is set to true, the map canvas does not refresh.
void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override
QgsQuickMapCanvasMap(QQuickItem *parent=nullptr)
Create map canvas map.
void isRenderingChanged()
The isRendering property is set to true while a rendering job is pending for this map canvas map.
The QgsQuickMapSettings class encapsulates QgsMapSettings class to offer settings of configuration of...
void extentChanged()
Geographical coordinates of the rectangle that should be rendered.
void layersChanged()
Set list of layers for map rendering.
void temporalStateChanged()
Emitted when the temporal state has changed.
void setLayers(const QList< QgsMapLayer * > &layers)
Sets the list of layers to render in the map.
QList< QgsMapLayer * > layers
Set list of layers for map rendering.
void zRangeChanged()
Emitted when the Z range has changed.
A rectangle specified with double values.
void scale(double scaleFactor, const QgsPointXY *c=nullptr)
Scale the rectangle around its center point.
double xMinimum
double yMinimum
double xMaximum
void setYMinimum(double y)
Set the minimum y value.
void setXMinimum(double x)
Set the minimum x value.
void setYMaximum(double y)
Set the maximum y value.
void setXMaximum(double x)
Set the maximum x value.
double yMaximum
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
QgsPointXY center
static double rendererFrameRate(const QgsFeatureRenderer *renderer)
Calculates the frame rate (in frames per second) at which the given renderer must be redrawn.
@ FlagDontInvalidateCachedRendersWhenRangeChanges
Any cached rendering will not be invalidated when temporal range context is modified.
Represents a vector layer which manages a vector based data sets.
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Definition qgis.h:6024