16#include <QQuickWindow> 
   17#include <QSGSimpleTextureNode> 
   36#include "moc_qgsquickmapcanvasmap.cpp" 
   41  : QQuickItem( parent )
 
   45  connect( 
this, &QQuickItem::windowChanged, 
this, &QgsQuickMapCanvasMap::onWindowChanged );
 
   46  connect( &mRefreshTimer, &QTimer::timeout, 
this, [
this] { refreshMap(); } );
 
   47  connect( &mMapUpdateTimer, &QTimer::timeout, 
this, &QgsQuickMapCanvasMap::renderJobUpdated );
 
   57  mMapUpdateTimer.setSingleShot( 
false );
 
   58  mMapUpdateTimer.setInterval( 250 );
 
   59  mRefreshTimer.setSingleShot( 
true );
 
   60  setTransformOrigin( QQuickItem::TopLeft );
 
   61  setFlags( QQuickItem::ItemHasContents );
 
 
   68  return mMapSettings.get();
 
 
   75  QgsPoint mousePos( mMapSettings->screenToCoordinate( center ) );
 
   77  QgsPointXY newCenter( mousePos.
x() + ( ( oldCenter.
x() - mousePos.
x() ) * scale ), mousePos.
y() + ( ( oldCenter.
y() - mousePos.
y() ) * scale ) );
 
   80  extent.
scale( scale, &newCenter );
 
   81  mMapSettings->setExtent( extent );
 
 
   86  QgsPoint start = mMapSettings->screenToCoordinate( oldPos.toPoint() );
 
   87  QgsPoint end = mMapSettings->screenToCoordinate( newPos.toPoint() );
 
   89  double dx = end.
x() - start.
x();
 
   90  double dy = end.
y() - start.
y();
 
  100  mMapSettings->setExtent( extent );
 
 
  103void QgsQuickMapCanvasMap::refreshMap()
 
  107  if ( mCacheInvalidations.testFlag( CacheInvalidationType::Temporal ) )
 
  109    clearTemporalCache();
 
  110    mCacheInvalidations &= ~( 
static_cast<int>( CacheInvalidationType::Temporal ) );
 
  112  if ( mCacheInvalidations.testFlag( CacheInvalidationType::Elevation ) )
 
  114    clearElevationCache();
 
  115    mCacheInvalidations &= ~( 
static_cast<int>( CacheInvalidationType::Elevation ) );
 
  127  QgsProject *project = mMapSettings->project();
 
  140  mapSettings.setExpressionContext( expressionContext );
 
  151  if ( mIncrementalRendering )
 
  152    mMapUpdateTimer.start();
 
  160  if ( !mSilentRefresh )
 
  166void QgsQuickMapCanvasMap::renderJobUpdated()
 
  183void QgsQuickMapCanvasMap::renderJobFinished()
 
  196  delete mLabelingResults;
 
  207  mMapUpdateTimer.stop();
 
  216  if ( !mSilentRefresh )
 
  222    mSilentRefresh = 
false;
 
  225  if ( mDeferredRefreshPending )
 
  227    mDeferredRefreshPending = 
false;
 
  228    mSilentRefresh = 
true;
 
  233void QgsQuickMapCanvasMap::layerRepaintRequested( 
bool deferred )
 
  235  if ( mMapSettings->outputSize().isNull() )
 
  244        mSilentRefresh = 
true;
 
  249        mDeferredRefreshPending = 
true;
 
  259void QgsQuickMapCanvasMap::onWindowChanged( QQuickWindow *window )
 
  261  if ( mWindow == window )
 
  265    disconnect( mWindow, &QQuickWindow::screenChanged, 
this, &QgsQuickMapCanvasMap::onScreenChanged );
 
  269    connect( window, &QQuickWindow::screenChanged, 
this, &QgsQuickMapCanvasMap::onScreenChanged );
 
  270    onScreenChanged( window->screen() );
 
  276void QgsQuickMapCanvasMap::onScreenChanged( QScreen *screen )
 
  280    if ( screen->devicePixelRatio() > 0 )
 
  282      mMapSettings->setDevicePixelRatio( screen->devicePixelRatio() );
 
  284    mMapSettings->setOutputDpi( screen->physicalDotsPerInch() );
 
  288void QgsQuickMapCanvasMap::onExtentChanged()
 
  296void QgsQuickMapCanvasMap::onTemporalStateChanged()
 
  298  mCacheInvalidations |= CacheInvalidationType::Temporal;
 
  304void QgsQuickMapCanvasMap::onzRangeChanged()
 
  306  mCacheInvalidations |= CacheInvalidationType::Elevation;
 
  312void QgsQuickMapCanvasMap::updateTransform()
 
  315  QgsRectangle newExtent = mMapSettings->mapSettings().visibleExtent();
 
  316  setScale( imageExtent.
width() / newExtent.
width() );
 
  325  return mMapUpdateTimer.interval();
 
 
  340  return mIncrementalRendering;
 
 
  386  if ( mImage.isNull() )
 
  391  QSGSimpleTextureNode *node = 
static_cast<QSGSimpleTextureNode *
>( oldNode );
 
  394    node = 
new QSGSimpleTextureNode();
 
  395    QSGTexture *texture = window()->createTextureFromImage( mImage );
 
  396    node->setTexture( texture );
 
  397    node->setOwnsTexture( 
true );
 
  400  QRectF rect( boundingRect() );
 
  401  QSizeF size = mImage.size();
 
  402  if ( !size.isEmpty() )
 
  403    size /= mMapSettings->devicePixelRatio();
 
  406  if ( !rect.isEmpty() && !size.isEmpty() && !
qgsDoubleNear( rect.width() / rect.height(), ( size.width() ) / 
static_cast<double>( size.height() ), 3 ) )
 
  410      rect.setHeight( rect.width() / size.width() * size.height() );
 
  414      rect.setWidth( rect.height() / size.height() * size.width() );
 
  418  node->setRect( rect );
 
 
  423#if QT_VERSION < QT_VERSION_CHECK( 6, 0, 0 ) 
  424void QgsQuickMapCanvasMap::geometryChanged( 
const QRectF &newGeometry, 
const QRectF &oldGeometry )
 
  426  QQuickItem::geometryChanged( newGeometry, oldGeometry );
 
  430  QQuickItem::geometryChange( newGeometry, oldGeometry );
 
  432  if ( newGeometry.size() != oldGeometry.size() )
 
  434    mMapSettings->setOutputSize( newGeometry.size().toSize() );
 
 
  439void QgsQuickMapCanvasMap::onLayersChanged()
 
  441  if ( mMapSettings->extent().isEmpty() )
 
  444  for ( 
const QMetaObject::Connection &conn : std::as_const( mLayerConnections ) )
 
  448  mLayerConnections.clear();
 
  450  const QList<QgsMapLayer *> layers = mMapSettings->layers();
 
  477void QgsQuickMapCanvasMap::zoomToFullExtent()
 
  480  const QList<QgsMapLayer *> layers = mMapSettings->layers();
 
  483    if ( mMapSettings->destinationCrs() != layer->crs() )
 
  485      QgsCoordinateTransform transform( layer->crs(), mMapSettings->destinationCrs(), mMapSettings->transformContext() );
 
  500  mMapSettings->setExtent( extent );
 
  507  if ( mMapSettings->outputSize().isNull() )
 
  511    mRefreshTimer.start( 1 );
 
 
  520void QgsQuickMapCanvasMap::clearTemporalCache()
 
  524    bool invalidateLabels = 
false;
 
  525    const QList<QgsMapLayer *> layerList = mMapSettings->mapSettings().layers();
 
  528      bool alreadyInvalidatedThisLayer = 
false;
 
  529      if ( 
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer ) )
 
  535          mCache->invalidateCacheForLayer( layer );
 
  536          alreadyInvalidatedThisLayer = 
true;
 
  542      if ( layer->temporalProperties() && layer->temporalProperties()->isActive() )
 
  544        if ( 
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer ) )
 
  546          if ( vl->labelsEnabled() || vl->diagramsEnabled() )
 
  547            invalidateLabels = 
true;
 
  553        if ( !alreadyInvalidatedThisLayer )
 
  554          mCache->invalidateCacheForLayer( layer );
 
  556      else if ( 
QgsGroupLayer *gl = qobject_cast<QgsGroupLayer *>( layer ) )
 
  558        const QList<QgsMapLayer *> childLayerList = gl->childLayers();
 
  561          if ( childLayer->temporalProperties() && childLayer->temporalProperties()->isActive() )
 
  566            mCache->invalidateCacheForLayer( layer );
 
  573    if ( invalidateLabels )
 
  575      mCache->clearCacheImage( QStringLiteral( 
"_labels_" ) );
 
  576      mCache->clearCacheImage( QStringLiteral( 
"_preview_labels_" ) );
 
  581void QgsQuickMapCanvasMap::clearElevationCache()
 
  585    bool invalidateLabels = 
false;
 
  586    const QList<QgsMapLayer *> layerList = mMapSettings->mapSettings().layers();
 
  589      if ( layer->elevationProperties() && layer->elevationProperties()->hasElevation() )
 
  591        if ( 
QgsVectorLayer *vl = qobject_cast<QgsVectorLayer *>( layer ) )
 
  593          if ( vl->labelsEnabled() || vl->diagramsEnabled() )
 
  594            invalidateLabels = 
true;
 
  600        mCache->invalidateCacheForLayer( layer );
 
  602      else if ( 
QgsGroupLayer *gl = qobject_cast<QgsGroupLayer *>( layer ) )
 
  604        const QList<QgsMapLayer *> childLayerList = gl->childLayers();
 
  607          if ( childLayer->elevationProperties() && childLayer->elevationProperties()->hasElevation() )
 
  612            mCache->invalidateCacheForLayer( layer );
 
  619    if ( invalidateLabels )
 
  621      mCache->clearCacheImage( QStringLiteral( 
"_labels_" ) );
 
  622      mCache->clearCacheImage( QStringLiteral( 
"_preview_labels_" ) );
 
@ 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...
 
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.
 
void repaintRequested(bool deferredUpdate=false)
By emitting this signal the layer tells that either appearance or content have been changed and any v...
 
Responsible for keeping a 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.
 
Contains configuration for rendering maps.
 
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, const char *file=__builtin_FILE(), const char *function=__builtin_FUNCTION(), int line=__builtin_LINE())
Adds a message to the log instance (and creates it if necessary).
 
Point geometry type, with support for z-dimension and m-values.
 
Encapsulates a QGIS project, including sets of map layers and their styles, layouts,...
 
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.
 
Encapsulates QgsMapSettings class to offer settings of configuration of map rendering via QML propert...
 
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.
 
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.
 
void combineExtentWith(const QgsRectangle &rect)
Expands the rectangle so that it covers both the original rectangle and the given rectangle.
 
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 dataset.
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)