19 #include <QElapsedTimer>
21 #include <QtConcurrentMap>
52 bool LayerRenderJob::imageCanBeComposed()
const
54 if ( imageInitialized )
58 return renderer->isReadyToCompose();
72 : mSettings( settings )
96 QHash<QgsMapLayer *, int> result;
99 if (
auto &&lKey = it.key() )
100 result.insert( lKey, it.value() );
120 QSet< QgsMapLayer * > labeledLayers;
127 switch ( ml->type() )
192 static const double SPLIT_COORD = 180.0;
204 QgsDebugMsgLevel( QStringLiteral(
"\n0:%1 %2x%3\n1:%4\n2:%5 %6x%7 (w:%8 h:%9)" )
207 .arg( std::fabs( 1.0 - extent2.
width() / extent.
width() ) )
208 .arg( std::fabs( 1.0 - extent2.
height() / extent.
height() ) )
242 if ( ll.
x() > ur.
x() )
271 extent =
QgsRectangle( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
280 QgsDebugMsg( QStringLiteral(
"Transform error caught" ) );
281 extent =
QgsRectangle( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
282 r2 =
QgsRectangle( std::numeric_limits<double>::lowest(), std::numeric_limits<double>::lowest(), std::numeric_limits<double>::max(), std::numeric_limits<double>::max() );
289 QImage *QgsMapRendererJob::allocateImage( QString layerId )
294 if ( image->isNull() )
303 QPainter *QgsMapRendererJob::allocateImageAndPainter( QString layerId, QImage *&image )
305 QPainter *painter =
nullptr;
306 image = allocateImage( layerId );
309 painter =
new QPainter( image );
311 #if QT_VERSION >= QT_VERSION_CHECK(5, 13, 0)
320 LayerRenderJobs layerJobs;
329 Q_UNUSED( cacheValid )
330 QgsDebugMsgLevel( QStringLiteral(
"CACHE VALID: %1" ).arg( cacheValid ), 4 );
335 while ( li.hasPrevious() )
339 QgsDebugMsgLevel( QStringLiteral(
"layer %1: minscale:%2 maxscale:%3 scaledepvis:%4 blendmode:%5 isValid:%6" )
356 QgsDebugMsgLevel( QStringLiteral(
"Layer not rendered because it is not within the defined visibility scale range" ), 3 );
362 QgsDebugMsgLevel( QStringLiteral(
"Layer not rendered because it is not visible within the map's time range" ), 3 );
368 QgsDebugMsgLevel( QStringLiteral(
"Layer not rendered because it is not visible within the map's z range" ), 3 );
377 bool haveExtentInLayerCrs =
true;
380 haveExtentInLayerCrs = reprojectToLayerExtent( ml, ct, r1, r2 );
385 mErrors.append( Error( ml->
id(), tr(
"There was a problem transforming the layer's extent. Layer skipped." ) ) );
396 if ( ( vl && vl->
isEditable() ) || requiresLabeling )
402 layerJobs.append( LayerRenderJob() );
403 LayerRenderJob &job = layerJobs.last();
407 job.layerId = ml->
id();
409 job.renderingTime = -1;
413 job.context.setPainter( painter );
414 job.context.setLabelingEngine( labelingEngine2 );
415 job.context.setCoordinateTransform( ct );
416 job.context.setExtent( r1 );
417 if ( !haveExtentInLayerCrs )
420 if ( mFeatureFilterProvider )
421 job.context.setFeatureFilterProvider( mFeatureFilterProvider );
437 job.imageInitialized =
true;
440 job.renderer =
nullptr;
441 job.context.setPainter(
nullptr );
445 QElapsedTimer layerTime;
454 if (
mCache || ( !painter && !deferredPainterSet ) || ( job.renderer && job.renderer->forceRasterRender() ) )
457 job.context.setPainter( allocateImageAndPainter( ml->
id(), job.img ) );
461 job.renderer =
nullptr;
462 layerJobs.removeLast();
467 job.renderingTime = layerTime.elapsed();
475 LayerRenderJobs secondPassJobs;
478 QHash<QString, LayerRenderJob *> layerJobMapping;
481 QSet<QString> layerHasMask;
488 MaskSource(
const QString &layerId_,
const QString &labelRuleId_,
int labelMaskId_ ):
489 layerId( layerId_ ), labelRuleId( labelRuleId_ ), labelMaskId( labelMaskId_ ) {}
494 QHash<QString, QPair<QSet<QgsSymbolLayerId>, QList<MaskSource>>> maskedSymbolLayers;
496 for ( LayerRenderJob &job : firstPassJobs )
502 layerJobMapping[job.layer->id()] = &job;
505 auto collectMasks = [&]( QHash<QString, QSet<QgsSymbolLayerId>> *masks, QString sourceLayerId, QString ruleId = QString(),
int labelMaskId = -1 )
507 for (
auto it = masks->begin(); it != masks->end(); ++it )
509 auto lit = maskedSymbolLayers.find( it.key() );
510 if ( lit == maskedSymbolLayers.end() )
512 maskedSymbolLayers[it.key()] = qMakePair( it.value(), QList<MaskSource>() << MaskSource( sourceLayerId, ruleId, labelMaskId ) );
516 if ( lit->first != it.value() )
518 QgsLogger::warning( QStringLiteral(
"Layer %1 : Different sets of symbol layers are masked by different sources ! Only one (arbitrary) set will be retained !" ).arg( it.key() ) );
521 lit->second.push_back( MaskSource( sourceLayerId, ruleId, labelMaskId ) );
524 if ( ! masks->isEmpty() )
525 layerHasMask.insert( sourceLayerId );
530 for (
auto it = labelMasks.begin(); it != labelMasks.end(); it++ )
532 QString labelRule = it.key();
533 QHash<QString, QSet<QgsSymbolLayerId>> masks = it.value();
536 QSet<QgsSymbolLayerReference> slRefs;
537 for (
auto mit = masks.begin(); mit != masks.end(); mit++ )
539 for (
auto slIt = mit.value().begin(); slIt != mit.value().end(); slIt++ )
545 int labelMaskId = labelJob.maskIdProvider.insertLabelLayer( vl->
id(), it.key(), slRefs );
548 collectMasks( &masks, vl->
id(), labelRule, labelMaskId );
553 collectMasks( &symbolLayerMasks, vl->
id() );
556 if ( maskedSymbolLayers.isEmpty() )
557 return secondPassJobs;
561 for ( LayerRenderJob &job : firstPassJobs )
565 if ( job.img ==
nullptr )
567 job.context.setPainter( allocateImageAndPainter( ml->
id(), job.img ) );
569 if ( layerHasMask.contains( ml->
id() ) )
572 job.context.setMaskPainter( allocateImageAndPainter( ml->
id(), job.maskImage ) );
573 job.maskImage->fill( 0 );
578 if ( labelJob.img ==
nullptr )
580 labelJob.img = allocateImage( QStringLiteral(
"labels" ) );
584 for (
int maskId = 0; maskId < labelJob.maskIdProvider.size(); maskId++ )
587 labelJob.context.setMaskPainter( allocateImageAndPainter( QStringLiteral(
"label mask" ), maskImage ), maskId );
588 maskImage->fill( 0 );
589 labelJob.maskImages.push_back( maskImage );
591 labelJob.context.setMaskIdProvider( &labelJob.maskIdProvider );
594 for ( LayerRenderJob &job : firstPassJobs )
598 auto it = maskedSymbolLayers.find( ml->
id() );
599 if ( it == maskedSymbolLayers.end() )
602 QList<MaskSource> &sourceList = it->second;
603 const QSet<QgsSymbolLayerId> &symbolList = it->first;
606 secondPassJobs.append( LayerRenderJob() );
607 LayerRenderJob &job2 = secondPassJobs.last();
610 job2.firstPassJob = &job;
611 QgsVectorLayer *vl1 = qobject_cast<QgsVectorLayer *>( job.layer );
614 job2.context.setMaskPainter(
nullptr );
615 job2.context.setPainter( allocateImageAndPainter( vl1->
id(), job2.img ) );
618 secondPassJobs.removeLast();
623 for ( MaskSource &source : sourceList )
625 if ( source.labelMaskId != -1 )
626 job2.maskJobs.push_back( qMakePair(
nullptr, source.labelMaskId ) );
628 job2.maskJobs.push_back( qMakePair( layerJobMapping[source.layerId], -1 ) );
634 job2.renderer = mapRenderer;
641 return secondPassJobs;
648 job.context.setPainter( painter );
649 job.context.setLabelingEngine( labelingEngine2 );
651 job.context.setFeatureFilterProvider( mFeatureFilterProvider );
661 job.context.setPainter(
nullptr );
665 if ( canUseLabelCache && (
mCache || !painter ) )
667 job.img = allocateImage( QStringLiteral(
"labels" ) );
677 for ( LayerRenderJobs::iterator it = jobs.begin(); it != jobs.end(); ++it )
679 LayerRenderJob &job = *it;
682 delete job.context.painter();
683 job.context.setPainter(
nullptr );
685 if (
mCache && !job.cached && job.completed && job.layer )
687 QgsDebugMsgLevel( QStringLiteral(
"caching image for %1" ).arg( job.layerId ), 2 );
699 delete job.context.maskPainter();
700 job.context.setMaskPainter(
nullptr );
701 delete job.maskImage;
706 const auto constErrors = job.renderer->errors();
707 for (
const QString &message : constErrors )
708 mErrors.append( Error( job.renderer->layerId(), message ) );
711 job.renderer =
nullptr;
723 for (
auto &job : jobs )
727 delete job.context.painter();
728 job.context.setPainter(
nullptr );
737 job.renderer =
nullptr;
751 if (
mCache && !job.cached && !job.context.renderingStopped() )
762 for (
int maskId = 0; maskId < job.maskImages.size(); maskId++ )
764 delete job.context.maskPainter( maskId );
765 job.context.setMaskPainter(
nullptr, maskId );
766 delete job.maskImages[maskId];
771 #define DEBUG_RENDERING 0
775 const LayerRenderJobs &jobs,
776 const LabelRenderJob &labelJob,
782 image.setDotsPerMeterX(
static_cast<int>( settings.
outputDpi() * 39.37 ) );
783 image.setDotsPerMeterY(
static_cast<int>( settings.
outputDpi() * 39.37 ) );
786 QPainter painter( &image );
791 for ( LayerRenderJobs::const_iterator it = jobs.constBegin(); it != jobs.constEnd(); ++it )
793 const LayerRenderJob &job = *it;
795 if ( job.layer && job.layer->customProperty( QStringLiteral(
"rendering/renderAboveLabels" ) ).toBool() )
802 painter.setCompositionMode( job.blendMode );
803 painter.setOpacity( job.opacity );
806 img.save( QString(
"/tmp/final_%1.png" ).arg( i ) );
810 painter.drawImage( 0, 0, img );
816 if ( labelJob.img && labelJob.complete )
818 painter.setCompositionMode( QPainter::CompositionMode_SourceOver );
819 painter.setOpacity( 1.0 );
820 painter.drawImage( 0, 0, *labelJob.img );
828 painter.setCompositionMode( QPainter::CompositionMode_SourceOver );
829 painter.setOpacity( 1.0 );
830 painter.drawImage( 0, 0, labelCacheImage );
834 for ( LayerRenderJobs::const_iterator it = jobs.constBegin(); it != jobs.constEnd(); ++it )
836 const LayerRenderJob &job = *it;
838 if ( !job.layer || !job.layer->customProperty( QStringLiteral(
"rendering/renderAboveLabels" ) ).toBool() )
845 painter.setCompositionMode( job.blendMode );
846 painter.setOpacity( job.opacity );
848 painter.drawImage( 0, 0, img );
853 image.save(
"/tmp/final.png" );
860 const LayerRenderJob &job,
864 if ( job.imageCanBeComposed() )
871 if ( cache && cache->
hasAnyCacheImage( job.layerId + QStringLiteral(
"_preview" ) ) )
886 for ( LayerRenderJob &job : secondPassJobs )
890 job.img->save( QString(
"/tmp/second_%1.png" ).arg( i ) );
895 if ( job.maskJobs.size() > 1 )
897 QPainter *maskPainter =
nullptr;
898 for ( QPair<LayerRenderJob *, int> p : job.maskJobs )
900 QImage *maskImage = p.first ? p.first->maskImage : labelJob.maskImages[p.second];
902 maskImage->save( QString(
"/tmp/mask_%1_%2.png" ).arg( i ).arg( mask++ ) );
906 maskPainter = p.first ? p.first->context.maskPainter() : labelJob.context.maskPainter( p.second );
910 maskPainter->drawImage( 0, 0, *maskImage );
915 if ( ! job.maskJobs.isEmpty() )
918 QPair<LayerRenderJob *, int> p = *job.maskJobs.begin();
919 QImage *maskImage = p.first ? p.first->maskImage : labelJob.maskImages[p.second];
921 maskImage->save( QString(
"/tmp/mask_%1.png" ).arg( i ) );
925 QPainter *painter = job.context.painter();
926 painter->setCompositionMode( QPainter::CompositionMode_DestinationIn );
931 QImage maskBinAlpha = maskImage->createMaskFromColor( 0 );
932 QVector<QRgb> mswTable;
933 mswTable.push_back( qRgba( 0, 0, 0, 255 ) );
934 mswTable.push_back( qRgba( 0, 0, 0, 0 ) );
935 maskBinAlpha.setColorTable( mswTable );
936 painter->drawImage( 0, 0, maskBinAlpha );
938 job.img->save( QString(
"/tmp/second_%1_a.png" ).arg( i ) );
943 QPainter tempPainter;
946 QPainter *painter1 = job.firstPassJob->context.painter();
949 tempPainter.begin( job.firstPassJob->img );
950 painter1 = &tempPainter;
953 job.firstPassJob->img->save( QString(
"/tmp/second_%1_first_pass_1.png" ).arg( i ) );
956 painter1->setCompositionMode( QPainter::CompositionMode_DestinationOut );
957 painter1->drawImage( 0, 0, *maskImage );
960 job.firstPassJob->img->save( QString(
"/tmp/second_%1_first_pass_2.png" ).arg( i ) );
963 painter1->setCompositionMode( QPainter::CompositionMode_DestinationOver );
964 painter1->drawImage( 0, 0, *job.img );
966 job.img->save( QString(
"/tmp/second_%1_b.png" ).arg( i ) );
967 if ( job.firstPassJob )
968 job.firstPassJob->img->save( QString(
"/tmp/second_%1_first_pass_3.png" ).arg( i ) );
978 if ( !settings.
value( QStringLiteral(
"Map/logCanvasRefreshEvent" ),
false ).toBool() )
981 QMultiMap<int, QString> elapsed;
982 const auto constJobs = jobs;
983 for (
const LayerRenderJob &job : constJobs )
984 elapsed.insert( job.renderingTime, job.layerId );
985 const auto constSecondPassJobs = secondPassJobs;
986 for (
const LayerRenderJob &job : constSecondPassJobs )
987 elapsed.insert( job.renderingTime, job.layerId + QString(
" (second pass)" ) );
989 elapsed.insert( labelJob.renderingTime, tr(
"Labeling" ) );
991 QList<int> tt( elapsed.uniqueKeys() );
992 std::sort( tt.begin(), tt.end(), std::greater<int>() );
993 const auto constTt = tt;
994 for (
int t : constTt )
996 QgsMessageLog::logMessage( tr(
"%1 ms: %2" ).arg( t ).arg( QStringList( elapsed.values( t ) ).join( QLatin1String(
", " ) ) ), tr(
"Rendering" ) );
1009 painter->setCompositionMode( QPainter::CompositionMode_SourceOver );
1013 if ( labelingEngine2 )
1015 labelingEngine2->
run( renderContext );
1018 QgsDebugMsgLevel( QStringLiteral(
"Draw labeling took (seconds): %1" ).arg( t.elapsed() / 1000. ), 2 );
1023 Q_UNUSED( settings )
1025 drawLabeling( renderContext, labelingEngine2, painter );
virtual bool requiresAdvancedEffects() const =0
Returns true if drawing labels requires advanced effects like composition modes, which could prevent ...
Custom exception class for Coordinate Reference System related exceptions.
bool isInfinite() const
Returns true if the range consists of all possible values.
static QgsExpressionContextScope * layerScope(const QgsMapLayer *layer)
Creates a new scope which contains variables and functions relating to a QgsMapLayer.
The QgsLabelingEngine class provides map labeling functionality.
virtual void run(QgsRenderContext &context)=0
Runs the labeling job.
static void warning(const QString &msg)
Goes to qWarning.
virtual bool isVisibleInZRange(const QgsDoubleRange &range) const
Returns true if the layer should be visible and rendered for the specified z range.
virtual void setLayerRenderingTimeHint(int time)
Sets approximate render time (in ms) for the layer to render.
Restore overridden layer style on destruction.
virtual bool isVisibleInTemporalRange(const QgsDateTimeRange &range) const
Returns true if the layer should be visible and rendered for the specified time range.
Base class for all map layer types.
bool isInScaleRange(double scale) const
Tests whether the layer should be visible at the specified scale.
QgsCoordinateReferenceSystem crs
QString id() const
Returns the layer's unique ID, which is used to access this layer from QgsProject.
QPainter::CompositionMode blendMode() const
Returns the current blending mode for a layer.
virtual QgsMapLayerRenderer * createMapRenderer(QgsRenderContext &rendererContext)=0
Returns new instance of QgsMapLayerRenderer that will be used for rendering of given context.
bool hasScaleBasedVisibility() const
Returns whether scale based visibility is enabled for the layer.
double minimumScale() const
Returns the minimum map scale (i.e.
virtual QgsMapLayerElevationProperties * elevationProperties()
Returns the layer's elevation properties.
virtual QgsMapLayerTemporalProperties * temporalProperties()
Returns the layer's temporal properties.
double maximumScale() const
Returns the maximum map scale (i.e.
This class is responsible for keeping cache of rendered images resulting from a map rendering job.
bool updateParameters(const QgsRectangle &extent, const QgsMapToPixel &mtp)
Sets extent and scale parameters.
QList< QgsMapLayer * > dependentLayers(const QString &cacheKey) const
Returns a list of map layers on which an image in the cache depends.
bool hasCacheImage(const QString &cacheKey) const
Returns true if the cache contains an image with the specified cacheKey that has the same extent and ...
QImage cacheImage(const QString &cacheKey) const
Returns the cached image for the specified cacheKey.
bool hasAnyCacheImage(const QString &cacheKey, double minimumScaleThreshold=0, double maximumScaleThreshold=0) const
Returns true if the cache contains an image with the specified cacheKey with any cache's parameters (...
void setCacheImageWithParameters(const QString &cacheKey, const QImage &image, const QgsRectangle &extent, const QgsMapToPixel &mapToPixel, const QList< QgsMapLayer * > &dependentLayers=QList< QgsMapLayer * >())
Set the cached image for a particular cacheKey, using a specific extent and mapToPixel (which may dif...
void clearCacheImage(const QString &cacheKey)
Removes an image from the cache with matching cacheKey.
QImage transformedCacheImage(const QString &cacheKey, const QgsMapToPixel &mtp) const
Returns the cached image for the specified cacheKey transformed to the particular extent and scale.
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.
void cleanupSecondPassJobs(LayerRenderJobs &jobs)
QHash< QgsMapLayer *, int > perLayerRenderingTime() const
Returns the render time (in ms) per layer.
static QImage layerImageToBeComposed(const QgsMapSettings &settings, const LayerRenderJob &job, const QgsMapRendererCache *cache)
LayerRenderJobs prepareSecondPassJobs(LayerRenderJobs &firstPassJobs, LabelRenderJob &labelJob)
Prepares jobs for a second pass, if selective masks exist (from labels or symbol layers).
QHash< QString, int > mLayerRenderingTimeHints
Approximate expected layer rendering time per layer, by layer ID.
void logRenderingTime(const LayerRenderJobs &jobs, const LayerRenderJobs &secondPassJobs, const LabelRenderJob &labelJob)
Errors errors() const
List of errors that happened during the rendering job - available when the rendering has been finishe...
static Q_DECL_DEPRECATED void drawLabeling(const QgsMapSettings &settings, QgsRenderContext &renderContext, QgsLabelingEngine *labelingEngine2, QPainter *painter)
LayerRenderJobs prepareJobs(QPainter *painter, QgsLabelingEngine *labelingEngine2, bool deferredPainterSet=false)
Creates a list of layer rendering jobs and prepares them for later render.
static const QString LABEL_PREVIEW_CACHE_ID
QgsMapRendererCache ID string for cached label image during preview compositions only.
const QgsMapSettings & mapSettings() const
Returns map settings with which this job was started.
static void composeSecondPass(LayerRenderJobs &secondPassJobs, LabelRenderJob &labelJob)
Compose second pass images into first pass images.
QgsMapRendererCache * mCache
static QImage composeImage(const QgsMapSettings &settings, const LayerRenderJobs &jobs, const LabelRenderJob &labelJob, const QgsMapRendererCache *cache=nullptr)
QgsMapRendererJob(const QgsMapSettings &settings)
QList< QgsMapRendererJob::Error > Errors
static const QString LABEL_CACHE_ID
QgsMapRendererCache ID string for cached label image.
QHash< QgsWeakMapLayerPointer, int > mPerLayerRenderingTime
Render time (in ms) per layer, by layer ID.
LabelRenderJob prepareLabelingJob(QPainter *painter, QgsLabelingEngine *labelingEngine2, bool canUseLabelCache=true)
Prepares a labeling job.
void setLayerRenderingTimeHints(const QHash< QString, int > &hints)
Sets approximate render times (in ms) for map layers.
void cleanupLabelJob(LabelRenderJob &job)
Handles clean up tasks for a label job, including deletion of images and storing cached label results...
void cleanupJobs(LayerRenderJobs &jobs)
bool prepareLabelCache() const
Prepares the cache for storing the result of labeling.
QgsMapRendererQImageJob(const QgsMapSettings &settings)
The QgsMapSettings class contains configuration for rendering of the map.
QSize deviceOutputSize() const
Returns the device output size of the map render.
double scale() const
Returns the calculated map scale.
QgsCoordinateTransform layerTransform(const QgsMapLayer *layer) const
Returns the coordinate transform from layer's CRS to destination CRS.
QgsDoubleRange zRange() const
Returns the range of z-values which will be visible in the map.
bool testFlag(Flag flag) const
Check whether a particular flag is enabled.
@ LosslessImageRendering
Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some...
@ Antialiasing
Enable anti-aliasing for map rendering.
QColor backgroundColor() const
Returns the background color of the map.
float devicePixelRatio() const
Returns the device pixel ratio.
QSize outputSize() const
Returns the size of the resulting map image, in pixels.
QImage::Format outputImageFormat() const
format of internal QImage, default QImage::Format_ARGB32_Premultiplied
double extentBuffer() const
Returns the buffer in map units to use around the visible extent for rendering symbols whose correspo...
const QgsMapToPixel & mapToPixel() const
QgsRectangle visibleExtent() const
Returns the actual extent derived from requested extent that takes takes output image size into accou...
QList< QgsMapLayer * > layers() const
Returns the list of layers which will be rendered in the map.
double outputDpi() const
Returns the DPI (dots per inch) used for conversion between real world units (e.g.
QMap< QString, QString > layerStyleOverrides() const
Returns the map of map layer style overrides (key: layer ID, value: style name) where a different sty...
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).
static bool staticWillUseLayer(const QgsMapLayer *layer)
Called to find out whether a specified layer is used for labeling.
A class to represent a 2D point.
QString toString(int precision=-1) const
Returns a string representation of the point (x, y) with a preset precision.
A rectangle specified with double values.
QString toString(int precision=16) const
Returns a string representation of form xmin,ymin : xmax,ymax Coordinates will be truncated to the sp...
double yMaximum() const SIP_HOLDGIL
Returns the y maximum value (top side of rectangle).
double xMaximum() const SIP_HOLDGIL
Returns the x maximum value (right side of rectangle).
double xMinimum() const SIP_HOLDGIL
Returns the x minimum value (left side of rectangle).
double yMinimum() const SIP_HOLDGIL
Returns the y minimum value (bottom side of rectangle).
void setXMaximum(double x) SIP_HOLDGIL
Set the maximum x value.
void setXMinimum(double x) SIP_HOLDGIL
Set the minimum x value.
double height() const SIP_HOLDGIL
Returns the height of the rectangle.
void grow(double delta)
Grows the rectangle in place by the specified amount.
double width() const SIP_HOLDGIL
Returns the width of the rectangle.
bool isFinite() const
Returns true if the rectangle has finite boundaries.
Contains information about the context of a rendering operation.
@ ApplyClipAfterReprojection
Feature geometry clipping to mapExtent() must be performed after the geometries are transformed using...
void setPainter(QPainter *p)
Sets the destination QPainter for the render operation.
static QgsRenderContext fromMapSettings(const QgsMapSettings &mapSettings)
create initialized QgsRenderContext instance from given QgsMapSettings
This class is a composition of two QSettings instances:
QVariant value(const QString &key, const QVariant &defaultValue=QVariant(), Section section=NoSection) const
Returns the value for setting key.
Type used to refer to a specific symbol layer in a symbol of a layer.
static QSet< const QgsSymbolLayer * > toSymbolLayerPointers(QgsFeatureRenderer *renderer, const QSet< QgsSymbolLayerId > &symbolLayerIds)
Converts a set of symbol layer id to a set of pointers to actual symbol layers carried by the feature...
const QgsDateTimeRange & temporalRange() const
Returns the datetime range for the object.
bool isTemporal() const
Returns true if the object's temporal range is enabled, and the object will be filtered when renderin...
Implementation of threaded rendering for vector layers.
QgsFeatureRenderer * featureRenderer()
Returns the feature renderer.
static QHash< QString, QHash< QString, QSet< QgsSymbolLayerId > > > labelMasks(const QgsVectorLayer *)
Returns masks defined in labeling options of a layer.
static QHash< QString, QSet< QgsSymbolLayerId > > symbolLayerMasks(const QgsVectorLayer *)
Returns all masks that may be defined on symbol layers for a given vector layer.
Represents a vector layer which manages a vector based data sets.
bool labelsEnabled() const
Returns whether the layer contains labels which are enabled and should be drawn.
QgsMapLayerRenderer * createMapRenderer(QgsRenderContext &rendererContext) FINAL
Returns new instance of QgsMapLayerRenderer that will be used for rendering of given context.
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
const QgsAbstractVectorLayerLabeling * labeling() const
Access to const labeling configuration.
@ PointCloudLayer
Added in 3.18.
@ VectorTileLayer
Added in 3.14.
@ AnnotationLayer
Contains freeform, georeferenced annotations. Added in QGIS 3.16.
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)