Skip to content
Permalink
Browse files
Merge pull request #46648 from nirvn/maprenderer_labelsink
Add a couple of symbol/label API features to map renderer jobs
  • Loading branch information
nirvn committed Dec 29, 2021
2 parents 488255d + d4fceb2 commit 6c6e011b185c5723b92857f5d6a7d501b2dce7bb
@@ -831,7 +831,10 @@
QgsMapSettings.HighQualityImageTransforms = Qgis.MapSettingsFlag.HighQualityImageTransforms
QgsMapSettings.HighQualityImageTransforms.is_monkey_patched = True
QgsMapSettings.HighQualityImageTransforms.__doc__ = "Enable high quality image transformations, which results in better appearance of scaled or rotated raster components of a map (since QGIS 3.24)"
Qgis.MapSettingsFlag.__doc__ = 'Flags which adjust the way maps are rendered.\n\n.. versionadded:: 3.22\n\n' + '* ``Antialiasing``: ' + Qgis.MapSettingsFlag.Antialiasing.__doc__ + '\n' + '* ``DrawEditingInfo``: ' + Qgis.MapSettingsFlag.DrawEditingInfo.__doc__ + '\n' + '* ``ForceVectorOutput``: ' + Qgis.MapSettingsFlag.ForceVectorOutput.__doc__ + '\n' + '* ``UseAdvancedEffects``: ' + Qgis.MapSettingsFlag.UseAdvancedEffects.__doc__ + '\n' + '* ``DrawLabeling``: ' + Qgis.MapSettingsFlag.DrawLabeling.__doc__ + '\n' + '* ``UseRenderingOptimization``: ' + Qgis.MapSettingsFlag.UseRenderingOptimization.__doc__ + '\n' + '* ``DrawSelection``: ' + Qgis.MapSettingsFlag.DrawSelection.__doc__ + '\n' + '* ``DrawSymbolBounds``: ' + Qgis.MapSettingsFlag.DrawSymbolBounds.__doc__ + '\n' + '* ``RenderMapTile``: ' + Qgis.MapSettingsFlag.RenderMapTile.__doc__ + '\n' + '* ``RenderPartialOutput``: ' + Qgis.MapSettingsFlag.RenderPartialOutput.__doc__ + '\n' + '* ``RenderPreviewJob``: ' + Qgis.MapSettingsFlag.RenderPreviewJob.__doc__ + '\n' + '* ``RenderBlocking``: ' + Qgis.MapSettingsFlag.RenderBlocking.__doc__ + '\n' + '* ``LosslessImageRendering``: ' + Qgis.MapSettingsFlag.LosslessImageRendering.__doc__ + '\n' + '* ``Render3DMap``: ' + Qgis.MapSettingsFlag.Render3DMap.__doc__ + '\n' + '* ``HighQualityImageTransforms``: ' + Qgis.MapSettingsFlag.HighQualityImageTransforms.__doc__
QgsMapSettings.SkipSymbolRendering = Qgis.MapSettingsFlag.SkipSymbolRendering
QgsMapSettings.SkipSymbolRendering.is_monkey_patched = True
QgsMapSettings.SkipSymbolRendering.__doc__ = "Disable symbol rendering while still drawing labels if enabled (since QGIS 3.24)"
Qgis.MapSettingsFlag.__doc__ = 'Flags which adjust the way maps are rendered.\n\n.. versionadded:: 3.22\n\n' + '* ``Antialiasing``: ' + Qgis.MapSettingsFlag.Antialiasing.__doc__ + '\n' + '* ``DrawEditingInfo``: ' + Qgis.MapSettingsFlag.DrawEditingInfo.__doc__ + '\n' + '* ``ForceVectorOutput``: ' + Qgis.MapSettingsFlag.ForceVectorOutput.__doc__ + '\n' + '* ``UseAdvancedEffects``: ' + Qgis.MapSettingsFlag.UseAdvancedEffects.__doc__ + '\n' + '* ``DrawLabeling``: ' + Qgis.MapSettingsFlag.DrawLabeling.__doc__ + '\n' + '* ``UseRenderingOptimization``: ' + Qgis.MapSettingsFlag.UseRenderingOptimization.__doc__ + '\n' + '* ``DrawSelection``: ' + Qgis.MapSettingsFlag.DrawSelection.__doc__ + '\n' + '* ``DrawSymbolBounds``: ' + Qgis.MapSettingsFlag.DrawSymbolBounds.__doc__ + '\n' + '* ``RenderMapTile``: ' + Qgis.MapSettingsFlag.RenderMapTile.__doc__ + '\n' + '* ``RenderPartialOutput``: ' + Qgis.MapSettingsFlag.RenderPartialOutput.__doc__ + '\n' + '* ``RenderPreviewJob``: ' + Qgis.MapSettingsFlag.RenderPreviewJob.__doc__ + '\n' + '* ``RenderBlocking``: ' + Qgis.MapSettingsFlag.RenderBlocking.__doc__ + '\n' + '* ``LosslessImageRendering``: ' + Qgis.MapSettingsFlag.LosslessImageRendering.__doc__ + '\n' + '* ``Render3DMap``: ' + Qgis.MapSettingsFlag.Render3DMap.__doc__ + '\n' + '* ``HighQualityImageTransforms``: ' + Qgis.MapSettingsFlag.HighQualityImageTransforms.__doc__ + '\n' + '* ``SkipSymbolRendering``: ' + Qgis.MapSettingsFlag.SkipSymbolRendering.__doc__
# --
QgsMapSettings.Flags = Qgis.MapSettingsFlags
Qgis.MapSettingsFlag.baseClass = Qgis
@@ -891,7 +894,10 @@
QgsRenderContext.HighQualityImageTransforms = Qgis.RenderContextFlag.HighQualityImageTransforms
QgsRenderContext.HighQualityImageTransforms.is_monkey_patched = True
QgsRenderContext.HighQualityImageTransforms.__doc__ = "Enable high quality image transformations, which results in better appearance of scaled or rotated raster components of a map (since QGIS 3.24)"
Qgis.RenderContextFlag.__doc__ = 'Flags which affect rendering operations.\n\n.. versionadded:: 3.22\n\n' + '* ``DrawEditingInfo``: ' + Qgis.RenderContextFlag.DrawEditingInfo.__doc__ + '\n' + '* ``ForceVectorOutput``: ' + Qgis.RenderContextFlag.ForceVectorOutput.__doc__ + '\n' + '* ``UseAdvancedEffects``: ' + Qgis.RenderContextFlag.UseAdvancedEffects.__doc__ + '\n' + '* ``UseRenderingOptimization``: ' + Qgis.RenderContextFlag.UseRenderingOptimization.__doc__ + '\n' + '* ``DrawSelection``: ' + Qgis.RenderContextFlag.DrawSelection.__doc__ + '\n' + '* ``DrawSymbolBounds``: ' + Qgis.RenderContextFlag.DrawSymbolBounds.__doc__ + '\n' + '* ``RenderMapTile``: ' + Qgis.RenderContextFlag.RenderMapTile.__doc__ + '\n' + '* ``Antialiasing``: ' + Qgis.RenderContextFlag.Antialiasing.__doc__ + '\n' + '* ``RenderPartialOutput``: ' + Qgis.RenderContextFlag.RenderPartialOutput.__doc__ + '\n' + '* ``RenderPreviewJob``: ' + Qgis.RenderContextFlag.RenderPreviewJob.__doc__ + '\n' + '* ``RenderBlocking``: ' + Qgis.RenderContextFlag.RenderBlocking.__doc__ + '\n' + '* ``RenderSymbolPreview``: ' + Qgis.RenderContextFlag.RenderSymbolPreview.__doc__ + '\n' + '* ``LosslessImageRendering``: ' + Qgis.RenderContextFlag.LosslessImageRendering.__doc__ + '\n' + '* ``ApplyScalingWorkaroundForTextRendering``: ' + Qgis.RenderContextFlag.ApplyScalingWorkaroundForTextRendering.__doc__ + '\n' + '* ``Render3DMap``: ' + Qgis.RenderContextFlag.Render3DMap.__doc__ + '\n' + '* ``ApplyClipAfterReprojection``: ' + Qgis.RenderContextFlag.ApplyClipAfterReprojection.__doc__ + '\n' + '* ``RenderingSubSymbol``: ' + Qgis.RenderContextFlag.RenderingSubSymbol.__doc__ + '\n' + '* ``HighQualityImageTransforms``: ' + Qgis.RenderContextFlag.HighQualityImageTransforms.__doc__
QgsRenderContext.SkipSymbolRendering = Qgis.RenderContextFlag.SkipSymbolRendering
QgsRenderContext.SkipSymbolRendering.is_monkey_patched = True
QgsRenderContext.SkipSymbolRendering.__doc__ = "Disable symbol rendering while still drawing labels if enabled (since QGIS 3.24)"
Qgis.RenderContextFlag.__doc__ = 'Flags which affect rendering operations.\n\n.. versionadded:: 3.22\n\n' + '* ``DrawEditingInfo``: ' + Qgis.RenderContextFlag.DrawEditingInfo.__doc__ + '\n' + '* ``ForceVectorOutput``: ' + Qgis.RenderContextFlag.ForceVectorOutput.__doc__ + '\n' + '* ``UseAdvancedEffects``: ' + Qgis.RenderContextFlag.UseAdvancedEffects.__doc__ + '\n' + '* ``UseRenderingOptimization``: ' + Qgis.RenderContextFlag.UseRenderingOptimization.__doc__ + '\n' + '* ``DrawSelection``: ' + Qgis.RenderContextFlag.DrawSelection.__doc__ + '\n' + '* ``DrawSymbolBounds``: ' + Qgis.RenderContextFlag.DrawSymbolBounds.__doc__ + '\n' + '* ``RenderMapTile``: ' + Qgis.RenderContextFlag.RenderMapTile.__doc__ + '\n' + '* ``Antialiasing``: ' + Qgis.RenderContextFlag.Antialiasing.__doc__ + '\n' + '* ``RenderPartialOutput``: ' + Qgis.RenderContextFlag.RenderPartialOutput.__doc__ + '\n' + '* ``RenderPreviewJob``: ' + Qgis.RenderContextFlag.RenderPreviewJob.__doc__ + '\n' + '* ``RenderBlocking``: ' + Qgis.RenderContextFlag.RenderBlocking.__doc__ + '\n' + '* ``RenderSymbolPreview``: ' + Qgis.RenderContextFlag.RenderSymbolPreview.__doc__ + '\n' + '* ``LosslessImageRendering``: ' + Qgis.RenderContextFlag.LosslessImageRendering.__doc__ + '\n' + '* ``ApplyScalingWorkaroundForTextRendering``: ' + Qgis.RenderContextFlag.ApplyScalingWorkaroundForTextRendering.__doc__ + '\n' + '* ``Render3DMap``: ' + Qgis.RenderContextFlag.Render3DMap.__doc__ + '\n' + '* ``ApplyClipAfterReprojection``: ' + Qgis.RenderContextFlag.ApplyClipAfterReprojection.__doc__ + '\n' + '* ``RenderingSubSymbol``: ' + Qgis.RenderContextFlag.RenderingSubSymbol.__doc__ + '\n' + '* ``HighQualityImageTransforms``: ' + Qgis.RenderContextFlag.HighQualityImageTransforms.__doc__ + '\n' + '* ``SkipSymbolRendering``: ' + Qgis.RenderContextFlag.SkipSymbolRendering.__doc__
# --
QgsRenderContext.Flags = Qgis.RenderContextFlags
Qgis.RenderContextFlag.baseClass = Qgis
@@ -12,7 +12,6 @@




class QgsMapRendererJob : QObject /Abstract/
{
%Docstring(signature="appended")
@@ -158,6 +157,8 @@ Assign a cache to be used for reading and storing rendered images of individual
Does not take ownership of the object.
%End



int renderingTime() const;
%Docstring
Returns the total time it took to finish the job (in milliseconds).
@@ -577,6 +577,7 @@ The development version
LosslessImageRendering,
Render3DMap,
HighQualityImageTransforms,
SkipSymbolRendering,
};
typedef QFlags<Qgis::MapSettingsFlag> MapSettingsFlags;

@@ -601,6 +602,7 @@ The development version
ApplyClipAfterReprojection,
RenderingSubSymbol,
HighQualityImageTransforms,
SkipSymbolRendering,
};
typedef QFlags<Qgis::RenderContextFlag> RenderContextFlags;

@@ -352,6 +352,7 @@ exactly 2mm thick when a map is rendered at 1:1000, or 1mm thick when rendered a
%End



QColor selectionColor() const;
%Docstring
Returns the color to use when rendering selected features.
@@ -539,6 +540,7 @@ of any faster raster shortcuts.
%End



void setSelectionColor( const QColor &color );
%Docstring
Sets the ``color`` to use when rendering selected features.
@@ -495,6 +495,7 @@ std::vector<LayerRenderJob> QgsMapRendererJob::prepareJobs( QPainter *painter, Q
job.context()->expressionContext().appendScope( QgsExpressionContextUtils::layerScope( ml ) );
job.context()->setPainter( painter );
job.context()->setLabelingEngine( labelingEngine2 );
job.context()->setLabelSink( labelSink() );
job.context()->setCoordinateTransform( ct );
job.context()->setExtent( r1 );
if ( !haveExtentInLayerCrs )
@@ -26,7 +26,7 @@
#include <QElapsedTimer>

#include "qgsrendercontext.h"

#include "qgslabelsink.h"
#include "qgsmapsettings.h"
#include "qgsmaskidprovider.h"
#include "qgssettingsentry.h"
@@ -352,6 +352,22 @@ class CORE_EXPORT QgsMapRendererJob : public QObject SIP_ABSTRACT
*/
void setCache( QgsMapRendererCache *cache );

/**
* Returns the label sink associated to this rendering job.
* \note Not available in Python bindings.
* \since QGIS 3.24
*/
QgsLabelSink *labelSink() const { return mLabelSink; } SIP_SKIP

/**
* Assigns the label sink which will take over responsibility for handling labels
* during the rendering job.
* \note Ownership is not transferred and the sink must exist for the lifetime of the map rendering job.
* \note Not available in Python bindings.
* \since QGIS 3.24
*/
void setLabelSink( QgsLabelSink *sink ) { mLabelSink = sink; } SIP_SKIP

/**
* Returns the total time it took to finish the job (in milliseconds).
* \see perLayerRenderingTime()
@@ -559,6 +575,8 @@ class CORE_EXPORT QgsMapRendererJob : public QObject SIP_ABSTRACT
*/
virtual void startPrivate() = 0;

QgsLabelSink *mLabelSink = nullptr;

};


@@ -66,6 +66,7 @@ void QgsMapRendererSequentialJob::startPrivate()
mPainter = new QPainter( &mImage );

mInternalJob = new QgsMapRendererCustomPainterJob( mSettings, mPainter );
mInternalJob->setLabelSink( labelSink() );
mInternalJob->setCache( mCache );

connect( mInternalJob, &QgsMapRendererJob::finished, this, &QgsMapRendererSequentialJob::internalFinished );
@@ -935,6 +935,7 @@ class CORE_EXPORT Qgis
LosslessImageRendering = 0x1000, //!< Render images losslessly whenever possible, instead of the default lossy jpeg rendering used for some destination devices (e.g. PDF). This flag only works with builds based on Qt 5.13 or later.
Render3DMap = 0x2000, //!< Render is for a 3D map
HighQualityImageTransforms = 0x4000, //!< Enable high quality image transformations, which results in better appearance of scaled or rotated raster components of a map (since QGIS 3.24)
SkipSymbolRendering = 0x8000, //!< Disable symbol rendering while still drawing labels if enabled (since QGIS 3.24)
};
//! Map settings flags
Q_DECLARE_FLAGS( MapSettingsFlags, MapSettingsFlag ) SIP_MONKEYPATCH_FLAGS_UNNEST( QgsMapSettings, Flags )
@@ -965,6 +966,7 @@ class CORE_EXPORT Qgis
ApplyClipAfterReprojection = 0x8000, //!< Feature geometry clipping to mapExtent() must be performed after the geometries are transformed using coordinateTransform(). Usually feature geometry clipping occurs using the extent() in the layer's CRS prior to geometry transformation, but in some cases when extent() could not be accurately calculated it is necessary to clip geometries to mapExtent() AFTER transforming them using coordinateTransform().
RenderingSubSymbol = 0x10000, //!< Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol and symbol layer rendering to determine whether the symbol being rendered is a subsymbol. (Since QGIS 3.24)
HighQualityImageTransforms = 0x20000, //!< Enable high quality image transformations, which results in better appearance of scaled or rotated raster components of a map (since QGIS 3.24)
SkipSymbolRendering = 0x40000, //!< Disable symbol rendering while still drawing labels if enabled (since QGIS 3.24)
};
//! Render context flags
Q_DECLARE_FLAGS( RenderContextFlags, RenderContextFlag ) SIP_MONKEYPATCH_FLAGS_UNNEST( QgsRenderContext, Flags )
@@ -56,6 +56,7 @@ QgsRenderContext::QgsRenderContext( const QgsRenderContext &rh )
, mRendererScale( rh.mRendererScale )
, mSymbologyReferenceScale( rh.mSymbologyReferenceScale )
, mLabelingEngine( rh.mLabelingEngine )
, mLabelSink( rh.mLabelSink )
, mSelectionColor( rh.mSelectionColor )
, mVectorSimplifyMethod( rh.mVectorSimplifyMethod )
, mExpressionContext( rh.mExpressionContext )
@@ -99,6 +100,7 @@ QgsRenderContext &QgsRenderContext::operator=( const QgsRenderContext &rh )
mRendererScale = rh.mRendererScale;
mSymbologyReferenceScale = rh.mSymbologyReferenceScale;
mLabelingEngine = rh.mLabelingEngine;
mLabelSink = rh.mLabelSink;
mSelectionColor = rh.mSelectionColor;
mVectorSimplifyMethod = rh.mVectorSimplifyMethod;
mExpressionContext = rh.mExpressionContext;
@@ -245,6 +247,7 @@ QgsRenderContext QgsRenderContext::fromMapSettings( const QgsMapSettings &mapSet
ctx.setFlag( Qgis::RenderContextFlag::LosslessImageRendering, mapSettings.testFlag( Qgis::MapSettingsFlag::LosslessImageRendering ) );
ctx.setFlag( Qgis::RenderContextFlag::Render3DMap, mapSettings.testFlag( Qgis::MapSettingsFlag::Render3DMap ) );
ctx.setFlag( Qgis::RenderContextFlag::HighQualityImageTransforms, mapSettings.testFlag( Qgis::MapSettingsFlag::HighQualityImageTransforms ) );
ctx.setFlag( Qgis::RenderContextFlag::SkipSymbolRendering, mapSettings.testFlag( Qgis::MapSettingsFlag::SkipSymbolRendering ) );
ctx.setScaleFactor( mapSettings.outputDpi() / 25.4 ); // = pixels per mm
ctx.setDpiTarget( mapSettings.dpiTarget() >= 0.0 ? mapSettings.dpiTarget() : -1.0 );
ctx.setRendererScale( mapSettings.scale() );
@@ -27,6 +27,7 @@
#include "qgscoordinatetransform.h"
#include "qgsexpressioncontext.h"
#include "qgsfeaturefilterprovider.h"
#include "qgslabelsink.h"
#include "qgsmaptopixel.h"
#include "qgsmapunitscale.h"
#include "qgsrectangle.h"
@@ -360,11 +361,18 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
double symbologyReferenceScale() const { return mSymbologyReferenceScale; }

/**
* Gets access to new labeling engine (may be NULLPTR)
* \note not available in Python bindings
* Gets access to new labeling engine (may be NULLPTR).
* \note Not available in Python bindings.
*/
QgsLabelingEngine *labelingEngine() const { return mLabelingEngine; } SIP_SKIP

/**
* Returns the associated label sink, or NULLPTR if not set.
* \note Not available in Python bindings.
* \since QGIS 3.24
*/
QgsLabelSink *labelSink() const { return mLabelSink; } SIP_SKIP

/**
* Returns the color to use when rendering selected features.
*
@@ -531,11 +539,19 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
void setForceVectorOutput( bool force );

/**
* Assign new labeling engine
* \note not available in Python bindings
* Assigns the labeling engine
* \note Not available in Python bindings.
*/
void setLabelingEngine( QgsLabelingEngine *engine ) { mLabelingEngine = engine; } SIP_SKIP

/**
* Assigns the label sink which will take over responsibility for handling labels.
* \note Ownership is not transferred and the sink must exist for the lifetime of the map rendering job.
* \note Not available in Python bindings.
* \since QGIS 3.24
*/
void setLabelSink( QgsLabelSink *sink ) { mLabelSink = sink; } SIP_SKIP

/**
* Sets the \a color to use when rendering selected features.
*
@@ -1024,9 +1040,12 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject

double mSymbologyReferenceScale = -1;

//! Newer labeling engine implementation (can be NULLPTR)
//! Labeling engine implementation (can be NULLPTR)
QgsLabelingEngine *mLabelingEngine = nullptr;

//! Label sink (can be NULLPTR)
QgsLabelSink *mLabelSink = nullptr;

//! Color used for features that are marked as selected
QColor mSelectionColor;

@@ -34,6 +34,7 @@
#include "qgspainteffect.h"
#include "qgsfeaturefilterprovider.h"
#include "qgsexception.h"
#include "qgslabelsink.h"
#include "qgslogger.h"
#include "qgssettingsregistrycore.h"
#include "qgsexpressioncontextutils.h"
@@ -459,7 +460,15 @@ void QgsVectorLayerRenderer::drawRenderer( QgsFeatureRenderer *renderer, QgsFeat
bool drawMarker = isMainRenderer && ( mDrawVertexMarkers && context.drawEditingInformation() && ( !mVertexMarkerOnlyForSelection || sel ) );

// render feature
bool rendered = renderer->renderFeature( fet, context, -1, sel, drawMarker );
bool rendered = false;
if ( !context.testFlag( Qgis::RenderContextFlag::SkipSymbolRendering ) )
{
rendered = renderer->renderFeature( fet, context, -1, sel, drawMarker );
}
else
{
rendered = renderer->willRenderFeature( fet, context );
}

// labeling - register feature
if ( rendered )
@@ -573,11 +582,14 @@ void QgsVectorLayerRenderer::drawRendererLevels( QgsFeatureRenderer *renderer, Q
continue;
}

if ( !features.contains( sym ) )
if ( !context.testFlag( Qgis::RenderContextFlag::SkipSymbolRendering ) )
{
features.insert( sym, QList<QgsFeature>() );
if ( !features.contains( sym ) )
{
features.insert( sym, QList<QgsFeature>() );
}
features[sym].append( fet );
}
features[sym].append( fet );

// new labeling engine
if ( isMainRenderer && context.labelingEngine() && ( mLabelProvider || mDiagramProvider ) )
@@ -713,7 +725,22 @@ void QgsVectorLayerRenderer::prepareLabeling( QgsVectorLayer *layer, QSet<QStrin
{
if ( layer->labelsEnabled() )
{
mLabelProvider = layer->labeling()->provider( layer );
if ( context.labelSink() )
{
if ( const QgsRuleBasedLabeling *rbl = dynamic_cast<const QgsRuleBasedLabeling *>( layer->labeling() ) )
{
mLabelProvider = new QgsRuleBasedLabelSinkProvider( *rbl, layer, context.labelSink() );
}
else
{
QgsPalLayerSettings settings = layer->labeling()->settings();
mLabelProvider = new QgsLabelSinkProvider( layer, QString(), context.labelSink(), &settings );
}
}
else
{
mLabelProvider = layer->labeling()->provider( layer );
}
if ( mLabelProvider )
{
engine2->addProvider( mLabelProvider );

0 comments on commit 6c6e011

Please sign in to comment.