33#include <QElapsedTimer> 
   38  , mLayerName( layer->name() )
 
   40  , mRenderer( layer->renderer()->clone() )
 
   41  , mLayerBlendMode( layer->blendMode() )
 
   42  , mDrawTileBoundaries( layer->isTileBorderRenderingEnabled() )
 
   43  , mLabelsEnabled( layer->labelsEnabled() )
 
   45  , mSelectedFeatures( layer->selectedFeatures() )
 
   46  , mLayerOpacity( layer->opacity() )
 
   47  , mTileMatrixSet( layer->tileMatrixSet() )
 
   48  , mEnableProfile( context.flags() & 
Qgis::RenderContextFlag::RecordProfile )
 
   60        engine->addProvider( mLabelProvider );
 
   67  mDataProvider->moveToThread( 
nullptr );
 
   69  mPreparationTime = timer.elapsed();
 
 
   76  std::unique_ptr< QgsScopedRuntimeProfile > profile;
 
   79    profile = std::make_unique< QgsScopedRuntimeProfile >( mLayerName, QStringLiteral( 
"rendering" ), 
layerId() );
 
   80    if ( mPreparationTime > 0 )
 
   89  std::unique_ptr< QgsScopedRuntimeProfile > preparingProfile;
 
   92    preparingProfile = std::make_unique< QgsScopedRuntimeProfile >( QObject::tr( 
"Preparing render" ), QStringLiteral( 
"rendering" ) );
 
   95  mDataProvider->moveToThread( QThread::currentThread() );
 
   99  if ( !mClippingRegions.empty() )
 
  101    bool needsPainterClipPath = 
false;
 
  103    if ( needsPainterClipPath )
 
  107  QElapsedTimer tTotal;
 
  112  QgsDebugMsgLevel( QStringLiteral( 
"Vector tiles map scale 1 : %1" ).arg( tileRenderScale ), 2 );
 
  115  QgsDebugMsgLevel( QStringLiteral( 
"Vector tiles zoom level: %1" ).arg( mTileZoomToFetch ), 2 );
 
  116  mTileZoomToRender = mTileMatrixSet.
scaleToZoomLevel( tileRenderScale, 
false );
 
  117  QgsDebugMsgLevel( QStringLiteral( 
"Render zoom level: %1" ).arg( mTileZoomToRender ), 2 );
 
  119  mTileMatrix = mTileMatrixSet.
tileMatrix( mTileZoomToFetch );
 
  122  QgsDebugMsgLevel( QStringLiteral( 
"Vector tiles range X: %1 - %2  Y: %3 - %4" )
 
  135  preparingProfile.reset();
 
  136  std::unique_ptr< QgsScopedRuntimeProfile > renderingProfile;
 
  137  if ( mEnableProfile )
 
  139    renderingProfile = std::make_unique< QgsScopedRuntimeProfile >( QObject::tr( 
"Rendering" ), QStringLiteral( 
"rendering" ) );
 
  142  std::unique_ptr<QgsVectorTileLoader> asyncLoader;
 
  143  QList<QgsVectorTileRawData> rawTiles;
 
  144  if ( !mDataProvider->supportsAsync() )
 
  146    QElapsedTimer tFetch;
 
  149    QgsDebugMsgLevel( QStringLiteral( 
"Tile fetching time: %1" ).arg( tFetch.elapsed() / 1000. ), 2 );
 
  150    QgsDebugMsgLevel( QStringLiteral( 
"Fetched tiles: %1" ).arg( rawTiles.count() ), 2 );
 
  154    asyncLoader.reset( 
new QgsVectorTileLoader( mDataProvider.get(), mTileMatrixSet, mTileRange, mTileZoomToFetch, viewCenter, mFeedback.get(), 
renderContext()->rendererUsage() ) );
 
  157      QgsDebugMsgLevel( QStringLiteral( 
"Got tile asynchronously: " ) + rawTile.id.toString(), 2 );
 
  158      if ( !rawTile.data.isEmpty() )
 
  159        decodeAndDrawTile( rawTile );
 
  168  scope->
setVariable( QStringLiteral( 
"zoom_level" ), mTileZoomToRender, 
true );
 
  169  scope->
setVariable( QStringLiteral( 
"vector_tile_zoom" ), mTileMatrixSet.
scaleToZoom( tileRenderScale ), 
true );
 
  172  mRenderer->startRender( *
renderContext(), mTileZoomToRender, mTileRange );
 
  175  mRenderer->renderBackground( ctx );
 
  177  QMap<QString, QSet<QString> > requiredFields = mRenderer->usedAttributes( ctx );
 
  179  if ( mLabelProvider )
 
  181    const QMap<QString, QSet<QString> > requiredFieldsLabeling = mLabelProvider->
usedAttributes( ctx, mTileZoomToRender );
 
  182    for ( 
auto it = requiredFieldsLabeling.begin(); it != requiredFieldsLabeling.end(); ++it )
 
  184      requiredFields[it.key()].unite( it.value() );
 
  188  for ( 
auto it = requiredFields.constBegin(); it != requiredFields.constEnd(); ++it )
 
  191  mRequiredLayers = mRenderer->requiredLayers( ctx, mTileZoomToRender );
 
  193  if ( mLabelProvider )
 
  195    mLabelProvider->
setFields( mPerLayerFields );
 
  196    QSet<QString> attributeNames;  
 
  197    if ( !mLabelProvider->
prepare( ctx, attributeNames ) )
 
  200      mLabelProvider = 
nullptr; 
 
  204      mRequiredLayers.unite( mLabelProvider->
requiredLayers( ctx, mTileZoomToRender ) );
 
  208  if ( !mDataProvider->supportsAsync() )
 
  215      decodeAndDrawTile( rawTile );
 
  222    asyncLoader->downloadBlocking();
 
  223    if ( !asyncLoader->error().isEmpty() )
 
  224      mErrors.append( asyncLoader->error() );
 
  228    mRenderer->renderSelectedFeatures( mSelectedFeatures, ctx );
 
  230  mRenderer->stopRender( ctx );
 
  232  QgsDebugMsgLevel( QStringLiteral( 
"Total time for decoding: %1" ).arg( mTotalDecodeTime / 1000. ), 2 );
 
  233  QgsDebugMsgLevel( QStringLiteral( 
"Drawing time: %1" ).arg( mTotalDrawTime / 1000. ), 2 );
 
  234  QgsDebugMsgLevel( QStringLiteral( 
"Total time: %1" ).arg( tTotal.elapsed() / 1000. ), 2 );
 
 
  247  if ( mLayerBlendMode != QPainter::CompositionMode_SourceOver )
 
 
  264  if ( !decoder.decode( rawTile ) )
 
  276  tile.setRenderZoomLevel( mTileZoomToRender );
 
  278  tile.setFields( mPerLayerFields );
 
  279  tile.setFeatures( decoder.layerFeatures( mPerLayerFields, ct, &mRequiredLayers ) );
 
  291  mTotalDecodeTime += tLoad.elapsed();
 
  303    ctx.
painter()->setClipRegion( QRegion( tile.tilePolygon() ), Qt::IntersectClip );
 
  308    mRenderer->renderTile( tile, ctx );
 
  309    mTotalDrawTime += tDraw.elapsed();
 
  312  if ( mLabelProvider )
 
  315  if ( mDrawTileBoundaries )
 
  318    ctx.
painter()->setClipping( 
false );
 
  322    QBrush brush( QColor( 255, 0, 0, 40 ), Qt::BrushStyle::Dense3Pattern );
 
  325    ctx.
painter()->setBrush( brush );
 
  326    ctx.
painter()->drawPolygon( tile.tilePolygon() );
 
  329    format.
setColor( QColor( 255, 0, 0 ) );
 
The Qgis class provides global constants for use throughout the application.
 
@ VectorTile
Vector tile layer. Added in QGIS 3.14.
 
@ DrawSelection
Whether vector selections should be shown in the rendered map.
 
@ UseAdvancedEffects
Enable layer opacity and blending effects.
 
@ VerticalCenter
Center align.
 
static QgsRuntimeProfiler * profiler()
Returns the application runtime profiler.
 
Custom exception class for Coordinate Reference System related exceptions.
 
RAII class to pop scope from an expression context on destruction.
 
Single scope for storing variables and functions for use within a QgsExpressionContext.
 
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.
 
Base class for feedback objects to be used for cancellation of something running in a worker thread.
 
The QgsLabelingEngine class provides map labeling functionality.
 
void removeProvider(QgsAbstractLabelProvider *provider)
Remove provider if the provider's initialization failed. Provider instance is deleted.
 
static QPainterPath calculatePainterClipRegion(const QList< QgsMapClippingRegion > ®ions, const QgsRenderContext &context, Qgis::LayerType layerType, bool &shouldClip)
Returns a QPainterPath representing the intersection of clipping regions from context which should be...
 
static QList< QgsMapClippingRegion > collectClippingRegionsForLayer(const QgsRenderContext &context, const QgsMapLayer *layer)
Collects the list of map clipping regions from a context which apply to a map layer.
 
Base class for utility classes that encapsulate information necessary for rendering of map layers.
 
QString layerId() const
Gets access to the ID of the layer rendered by this class.
 
QgsRenderContext * renderContext()
Returns the render context associated with the renderer.
 
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
 
QgsPointXY center() const
Returns the center point of the rectangle.
 
Contains information about the context of a rendering operation.
 
QPainter * painter()
Returns the destination QPainter for the render operation.
 
QgsExpressionContext & expressionContext()
Gets the expression context.
 
QSize outputSize() const
Returns the size of the resulting rendered image, in pixels.
 
const QgsRectangle & extent() const
When rendering a map layer, calling this method returns the "clipping" extent for the layer (in the l...
 
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
 
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
 
QgsLabelingEngine * labelingEngine() const
Gets access to new labeling engine (may be nullptr).
 
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
 
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
 
void record(const QString &name, double time, const QString &group="startup", const QString &id=QString())
Manually adds a profile event with the given name and total time (in seconds).
 
Scoped object for saving and restoring a QPainter object's state.
 
void setEnabled(bool enabled)
Sets whether the text buffer will be drawn.
 
Container for all settings relating to text rendering.
 
void setColor(const QColor &color)
Sets the color that text will be rendered in.
 
QgsTextBufferSettings & buffer()
Returns a reference to the text buffer settings.
 
static void drawText(const QRectF &rect, double rotation, Qgis::TextHorizontalAlignment alignment, const QStringList &textLines, QgsRenderContext &context, const QgsTextFormat &format, bool drawAsOutlines=true, Qgis::TextVerticalAlignment vAlignment=Qgis::TextVerticalAlignment::Top, Qgis::TextRendererFlags flags=Qgis::TextRendererFlags(), Qgis::TextLayoutMode mode=Qgis::TextLayoutMode::Rectangle)
Draws text within a rectangle using the specified settings.
 
double scaleForRenderContext(const QgsRenderContext &context) const
Calculates the correct scale to use for the tiles when rendered using the specified render context.
 
double scaleToZoom(double scale) const
Calculates a fractional zoom level given a map scale denominator.
 
QgsTileMatrix tileMatrix(int zoom) const
Returns the tile matrix corresponding to the specified zoom.
 
int scaleToZoomLevel(double scale, bool clamp=true) const
Finds the best fitting (integer) zoom level given a map scale denominator.
 
QPointF mapToTileCoordinates(const QgsPointXY &mapPoint) const
Returns row/column coordinates (floating point number) from the given point in map coordinates.
 
QgsTileRange tileRangeFromExtent(const QgsRectangle &mExtent) const
Returns tile range that fully covers the given extent.
 
int endColumn() const
Returns index of the last column in the range.
 
int endRow() const
Returns index of the last row in the range.
 
int startRow() const
Returns index of the first row in the range.
 
int startColumn() const
Returns index of the first column in the range.
 
bool isValid() const
Returns whether the range is valid (when all row/column numbers are not negative)
 
QString toString() const
Returns tile coordinates in a formatted string.
 
int zoomLevel() const
Returns tile's zoom level (Z)
 
virtual bool prepare(QgsRenderContext &context, QSet< QString > &attributeNames)
Prepare for registration of features.
 
Base class for vector tile layer data providers.
 
virtual QMap< QString, QSet< QString > > usedAttributes(const QgsRenderContext &context, int tileZoom) const =0
Returns field names for each sub-layer that are required for labeling.
 
virtual void setFields(const QMap< QString, QgsFields > &perLayerFields)=0
Sets fields for each sub-layer.
 
virtual QSet< QString > requiredLayers(QgsRenderContext &context, int tileZoom) const
Returns a list of the layers required for labeling.
 
virtual void registerTileFeatures(const QgsVectorTileRendererData &tile, QgsRenderContext &context)=0
Registers label features for given tile to the labeling engine.
 
virtual QgsVectorTileLabelProvider * provider(QgsVectorTileLayer *layer) const SIP_SKIP
Factory for label provider implementation.
 
bool forceRasterRender() const override
Returns true if the renderer must be rendered to a raster paint device (e.g.
 
~QgsVectorTileLayerRenderer() override
 
QgsVectorTileLayerRenderer(QgsVectorTileLayer *layer, QgsRenderContext &context)
Creates the renderer. Always called from main thread, should copy whatever necessary from the layer.
 
virtual bool render() override
Do the rendering (based on data stored in the class).
 
Implements a map layer that is dedicated to rendering of vector tiles.
 
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
 
QgsVectorTileLabeling * labeling() const
Returns currently assigned labeling.
 
The loader class takes care of loading raw vector tile data from a tile source.
 
void tileRequestFinished(const QgsVectorTileRawData &rawTile)
Emitted when a tile request has finished. If a tile request has failed, the returned raw tile byte ar...
 
static QList< QgsVectorTileRawData > blockingFetchTileRawData(const QgsVectorTileDataProvider *provider, const QgsTileMatrixSet &tileMatrixSet, const QPointF &viewCenter, const QgsTileRange &range, int zoomLevel, QgsFeedback *feedback=nullptr, Qgis::RendererUsage usage=Qgis::RendererUsage::Unknown)
Returns raw tile data for the specified range of tiles. Blocks the caller until all tiles are fetched...
 
This class is responsible for decoding raw tile data written with Mapbox Vector Tiles encoding.
 
Keeps track of raw tile data from one or more sources that need to be decoded.
 
QgsTileXYZ id
Tile position in tile matrix set.
 
Contains decoded features of a single vector tile and any other data necessary for rendering of it.
 
static QPolygon tilePolygon(QgsTileXYZ id, const QgsCoordinateTransform &ct, const QgsTileMatrix &tm, const QgsMapToPixel &mtp)
Returns polygon (made by four corners of the tile) in screen coordinates.
 
static QgsFields makeQgisFields(const QSet< QString > &flds)
Returns QgsFields instance based on the set of field names.
 
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
 
#define QgsDebugMsgLevel(str, level)