mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-06 00:07:29 -04:00
[Selective masking]Fixes #34352 : use QUUid to identify symbol layer
Don't use pointers anymore because there are not stable when it comes to clone
This commit is contained in:
parent
07090ba36c
commit
b3af80e3e4
@ -109,7 +109,39 @@ This is currently used to implement selective masking.
|
||||
.. versionadded:: 3.12
|
||||
%End
|
||||
|
||||
QSet<const QgsSymbolLayer *> disabledSymbolLayers() const;
|
||||
|
||||
void setDisabledSymbolLayers( const QSet<const QgsSymbolLayer *> &symbolLayers );
|
||||
%Docstring
|
||||
When rendering a map layer in a second pass (for selective masking),
|
||||
some symbol layers may be disabled.
|
||||
|
||||
Sets the list of disabled symbol layers.
|
||||
|
||||
.. seealso:: :py:func:`disabledSymbolLayers`
|
||||
|
||||
.. seealso:: :py:func:`isSymbolLayerEnabled`
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. deprecated:: QGIS 3.28
|
||||
and replaced with setDisabledSymbolLayersV2
|
||||
%End
|
||||
|
||||
void setDisabledSymbolLayersV2( const QSet<QString> &symbolLayers );
|
||||
%Docstring
|
||||
When rendering a map layer in a second pass (for selective masking),
|
||||
some symbol layers may be disabled.
|
||||
|
||||
Sets the list of disabled symbol layer ids.
|
||||
|
||||
.. seealso:: :py:func:`disabledSymbolLayersV2`
|
||||
|
||||
.. seealso:: :py:func:`isSymbolLayerEnabledV2`
|
||||
|
||||
.. versionadded:: 3.28
|
||||
%End
|
||||
|
||||
QSet<const QgsSymbolLayer *> disabledSymbolLayers() const;
|
||||
%Docstring
|
||||
When rendering a map layer in a second pass (for selective masking),
|
||||
some symbol layers may be disabled.
|
||||
@ -121,6 +153,26 @@ Returns the list of disabled symbol layers.
|
||||
.. seealso:: :py:func:`isSymbolLayerEnabled`
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. deprecated:: QGIS 3.28
|
||||
and replaced with disabledSymbolLayersV2
|
||||
%End
|
||||
|
||||
const QSet<QString> &disabledSymbolLayersV2() const;
|
||||
%Docstring
|
||||
When rendering a map layer in a second pass (for selective masking),
|
||||
some symbol layers may be disabled.
|
||||
|
||||
Returns the list of disabled symbol layer ids.
|
||||
|
||||
.. seealso:: :py:func:`setDisabledSymbolLayers`
|
||||
|
||||
.. seealso:: :py:func:`isSymbolLayerEnabled`
|
||||
|
||||
.. versionadded:: 3.12
|
||||
|
||||
.. deprecated:: QGIS 3.28
|
||||
and replaced with disabledSymbolLayersV2
|
||||
%End
|
||||
|
||||
bool isSymbolLayerEnabled( const QgsSymbolLayer *layer ) const;
|
||||
@ -515,20 +567,6 @@ of any rendering operations.
|
||||
Multiple mask painters can be defined and the second parameter gives a unique identifier to each one.
|
||||
|
||||
.. seealso:: :py:func:`maskPainter`
|
||||
%End
|
||||
|
||||
void setDisabledSymbolLayers( const QSet<const QgsSymbolLayer *> &symbolLayers );
|
||||
%Docstring
|
||||
When rendering a map layer in a second pass (for selective masking),
|
||||
some symbol layers may be disabled.
|
||||
|
||||
Sets the list of disabled symbol layers.
|
||||
|
||||
.. seealso:: :py:func:`disabledSymbolLayers`
|
||||
|
||||
.. seealso:: :py:func:`isSymbolLayerEnabled`
|
||||
|
||||
.. versionadded:: 3.12
|
||||
%End
|
||||
|
||||
void setForceVectorOutput( bool force );
|
||||
@ -935,6 +973,19 @@ rendering using QBrush objects.
|
||||
.. versionadded:: 3.16
|
||||
%End
|
||||
|
||||
void addSymbolLayerClipPath( const QString &symbolLayerId, QPainterPath path );
|
||||
%Docstring
|
||||
Add a clip ``path`` to be applied to the ``symbolLayer`` before rendering
|
||||
|
||||
.. versionadded:: 3.26
|
||||
%End
|
||||
|
||||
QList<QPainterPath> symbolLayerClipPaths( const QString &symbolLayerId ) const;
|
||||
%Docstring
|
||||
Returns clip paths to be applied to the ``symbolLayer`` before rendering
|
||||
|
||||
.. versionadded:: 3.26
|
||||
%End
|
||||
|
||||
QgsDoubleRange zRange() const;
|
||||
%Docstring
|
||||
|
@ -646,6 +646,22 @@ Prepares all mask internal objects according to what is defined in ``context``
|
||||
This should be called prior to calling :py:func:`~QgsSymbolLayer.startRender` method.
|
||||
|
||||
.. versionadded:: 3.26
|
||||
%End
|
||||
|
||||
void setId( const QString &id );
|
||||
%Docstring
|
||||
Set symbol layer identifier
|
||||
This id has to be unique in the whole project
|
||||
|
||||
.. versionadded:: 3.28
|
||||
%End
|
||||
|
||||
const QString &id() const;
|
||||
%Docstring
|
||||
Returns symbol layer identifier
|
||||
This id is unique in the whole project
|
||||
|
||||
.. versionadded:: 3.28
|
||||
%End
|
||||
|
||||
protected:
|
||||
@ -664,7 +680,6 @@ Constructor for QgsSymbolLayer.
|
||||
|
||||
|
||||
|
||||
|
||||
void restoreOldDataDefinedProperties( const QVariantMap &stringMap );
|
||||
%Docstring
|
||||
Restores older data defined properties from string map.
|
||||
|
@ -106,19 +106,31 @@ Type used to refer to a specific symbol layer in a symbol of a layer.
|
||||
Default constructor
|
||||
%End
|
||||
|
||||
QgsSymbolLayerReference( const QString &layerId, const QgsSymbolLayerId &symbolLayer );
|
||||
QgsSymbolLayerReference( const QString &layerId, const QgsSymbolLayerId &symbolLayer );
|
||||
%Docstring
|
||||
Constructor
|
||||
%End
|
||||
|
||||
QgsSymbolLayerReference( const QString &layerId, const QString &symbolLayerId );
|
||||
|
||||
QString layerId() const;
|
||||
%Docstring
|
||||
The referenced vector layer / feature renderer
|
||||
%End
|
||||
|
||||
QgsSymbolLayerId symbolLayerId() const;
|
||||
QgsSymbolLayerId symbolLayerId() const;
|
||||
%Docstring
|
||||
The symbol layer's id
|
||||
|
||||
.. deprecated:: QGIS 3.28
|
||||
use symbolLayerIdV2 instead
|
||||
%End
|
||||
|
||||
QString symbolLayerIdV2() const;
|
||||
%Docstring
|
||||
The symbol layer's id
|
||||
|
||||
.. versionadded:: 3.28
|
||||
%End
|
||||
|
||||
bool operator==( const QgsSymbolLayerReference &other ) const;
|
||||
@ -131,13 +143,13 @@ The symbol layer's id
|
||||
{
|
||||
pathString.append( QString::number( path ) );
|
||||
}
|
||||
QString str = QStringLiteral( "<QgsSymbolLayerReference: %1 - %2 (%3)>" ).arg( sipCpp->layerId(), sipCpp->symbolLayerId().symbolKey(), pathString.join( ',' ) );
|
||||
QString str = QStringLiteral( "<QgsSymbolLayerReference: %1 - %2>" ).arg( sipCpp->layerId(), sipCpp->symbolLayerIdV2() );
|
||||
sipRes = PyUnicode_FromString( str.toUtf8().constData() );
|
||||
%End
|
||||
|
||||
};
|
||||
|
||||
uint qHash( const QgsSymbolLayerId &id );
|
||||
uint qHash( const QgsSymbolLayerId &id );
|
||||
|
||||
uint qHash( const QgsSymbolLayerReference &r );
|
||||
|
||||
|
@ -203,7 +203,7 @@ Write settings into a DOM element.
|
||||
.. seealso:: :py:func:`readXml`
|
||||
%End
|
||||
|
||||
QList<QgsSymbolLayerReference> maskedSymbolLayers() const;
|
||||
const QList<QgsSymbolLayerReference> &maskedSymbolLayers() const;
|
||||
%Docstring
|
||||
Returns a list of references to symbol layers that are masked by this buffer.
|
||||
|
||||
|
@ -653,7 +653,7 @@ std::vector< LayerRenderJob > QgsMapRendererJob::prepareSecondPassJobs( std::vec
|
||||
|
||||
// We collect for each layer, the set of symbol layers that will be "masked"
|
||||
// and the list of source layers that have a mask
|
||||
QHash<QString, QPair<QSet<QgsSymbolLayerId>, QList<MaskSource>>> maskedSymbolLayers;
|
||||
QHash<QString, QPair<QSet<QString>, QList<MaskSource>>> maskedSymbolLayers;
|
||||
|
||||
const bool forceVector = mapSettings().testFlag( Qgis::MapSettingsFlag::ForceVectorOutput )
|
||||
&& !mapSettings().testFlag( Qgis::MapSettingsFlag::ForceRasterMasks );
|
||||
@ -732,10 +732,8 @@ std::vector< LayerRenderJob > QgsMapRendererJob::prepareSecondPassJobs( std::vec
|
||||
if ( !layerJobMapping.contains( sourceLayerId ) )
|
||||
continue;
|
||||
|
||||
for ( auto slIt = mit.value().symbolLayerIds.begin(); slIt != mit.value().symbolLayerIds.end(); slIt++ )
|
||||
{
|
||||
slRefs.insert( QgsSymbolLayerReference( mit.key(), *slIt ) );
|
||||
}
|
||||
for ( QString symbolLayerId : mit.value().symbolLayerIds )
|
||||
slRefs.insert( QgsSymbolLayerReference( sourceLayerId, symbolLayerId ) );
|
||||
|
||||
hasEffects |= mit.value().hasEffects;
|
||||
}
|
||||
@ -865,7 +863,7 @@ std::vector< LayerRenderJob > QgsMapRendererJob::prepareSecondPassJobs( std::vec
|
||||
continue;
|
||||
|
||||
QList<MaskSource> &sourceList = it->second;
|
||||
const QSet<QgsSymbolLayerId> &symbolList = it->first;
|
||||
const QSet<QString> &symbolList = it->first;
|
||||
|
||||
secondPassJobs.emplace_back( LayerRenderJob() );
|
||||
LayerRenderJob &job2 = secondPassJobs.back();
|
||||
@ -919,7 +917,7 @@ std::vector< LayerRenderJob > QgsMapRendererJob::prepareSecondPassJobs( std::vec
|
||||
|
||||
// Render only the non masked symbol layer and we will compose 2nd pass with mask and first pass rendering in composeSecondPass
|
||||
// If vector output is enabled, disabled symbol layers would be actually rendered and masked with clipping path set in QgsMapRendererJob::initSecondPassJobs
|
||||
job2.context()->setDisabledSymbolLayers( QgsSymbolLayerUtils::toSymbolLayerPointers( mapRenderer->featureRenderer(), symbolList ) );
|
||||
job2.context()->setDisabledSymbolLayersV2( symbolList );
|
||||
}
|
||||
|
||||
return secondPassJobs;
|
||||
@ -942,13 +940,13 @@ void QgsMapRendererJob::initSecondPassJobs( std::vector< LayerRenderJob > &secon
|
||||
{
|
||||
QPainter *maskPainter = p.first ? p.first->maskPainter.get() : labelJob.maskPainters[p.second].get();
|
||||
QPainterPath path = static_cast<QgsMaskPaintDevice *>( maskPainter->device() )->maskPainterPath();
|
||||
for ( const QgsSymbolLayer *symbolLayer : job.context()->disabledSymbolLayers() )
|
||||
for ( const QString &symbolLayerId : job.context()->disabledSymbolLayersV2() )
|
||||
{
|
||||
job.context()->addSymbolLayerClipPath( symbolLayer, path );
|
||||
job.context()->addSymbolLayerClipPath( symbolLayerId, path );
|
||||
}
|
||||
}
|
||||
|
||||
job.context()->setDisabledSymbolLayers( QSet<const QgsSymbolLayer *>() );
|
||||
job.context()->setDisabledSymbolLayersV2( QSet<QString>() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "qgslogger.h"
|
||||
#include "qgselevationmap.h"
|
||||
#include "qgsunittypes.h"
|
||||
#include "qgssymbollayer.h"
|
||||
|
||||
#define POINTS_TO_MM 2.83464567
|
||||
#define INCH_TO_MM 25.4
|
||||
@ -708,12 +709,39 @@ void QgsRenderContext::setElevationMap( QgsElevationMap *map )
|
||||
mElevationMap = map;
|
||||
}
|
||||
|
||||
void QgsRenderContext::addSymbolLayerClipPath( const QgsSymbolLayer *symbolLayer, QPainterPath path )
|
||||
void QgsRenderContext::addSymbolLayerClipPath( const QString &symbolLayerId, QPainterPath path )
|
||||
{
|
||||
mSymbolLayerClipPaths[ symbolLayer ].append( path );
|
||||
mSymbolLayerClipPaths[ symbolLayerId ].append( path );
|
||||
}
|
||||
|
||||
QList<QPainterPath> QgsRenderContext::symbolLayerClipPaths( const QgsSymbolLayer *symbolLayer ) const
|
||||
QList<QPainterPath> QgsRenderContext::symbolLayerClipPaths( const QString &symbolLayerId ) const
|
||||
{
|
||||
return mSymbolLayerClipPaths[ symbolLayer ];
|
||||
return mSymbolLayerClipPaths[ symbolLayerId ];
|
||||
}
|
||||
|
||||
void QgsRenderContext::setDisabledSymbolLayers( const QSet<const QgsSymbolLayer *> &symbolLayers )
|
||||
{
|
||||
mDisabledSymbolLayers.clear();
|
||||
for ( const QgsSymbolLayer *symbolLayer : symbolLayers )
|
||||
mDisabledSymbolLayers << symbolLayer->id();
|
||||
}
|
||||
|
||||
void QgsRenderContext::setDisabledSymbolLayersV2( const QSet<QString> &symbolLayers )
|
||||
{
|
||||
mDisabledSymbolLayers = symbolLayers;
|
||||
}
|
||||
|
||||
QSet<const QgsSymbolLayer *> QgsRenderContext::disabledSymbolLayers() const
|
||||
{
|
||||
return QSet<const QgsSymbolLayer *>();
|
||||
}
|
||||
|
||||
const QSet<QString> &QgsRenderContext::disabledSymbolLayersV2() const
|
||||
{
|
||||
return mDisabledSymbolLayers;
|
||||
}
|
||||
|
||||
bool QgsRenderContext::isSymbolLayerEnabled( const QgsSymbolLayer *layer ) const
|
||||
{
|
||||
return !mDisabledSymbolLayers.contains( layer->id() );
|
||||
}
|
||||
|
@ -144,6 +144,31 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
|
||||
*/
|
||||
QPainter *maskPainter( int id = 0 ) { return mMaskPainter.value( id, nullptr ); }
|
||||
|
||||
// TODO QGIS 4 : remove the V2 from method name
|
||||
|
||||
/**
|
||||
* When rendering a map layer in a second pass (for selective masking),
|
||||
* some symbol layers may be disabled.
|
||||
*
|
||||
* Sets the list of disabled symbol layers.
|
||||
* \see disabledSymbolLayers()
|
||||
* \see isSymbolLayerEnabled()
|
||||
* \since QGIS 3.12
|
||||
* \deprecated since QGIS 3.28 and replaced with setDisabledSymbolLayersV2
|
||||
*/
|
||||
Q_DECL_DEPRECATED void setDisabledSymbolLayers( const QSet<const QgsSymbolLayer *> &symbolLayers );
|
||||
|
||||
/**
|
||||
* When rendering a map layer in a second pass (for selective masking),
|
||||
* some symbol layers may be disabled.
|
||||
*
|
||||
* Sets the list of disabled symbol layer ids.
|
||||
* \see disabledSymbolLayersV2()
|
||||
* \see isSymbolLayerEnabledV2()
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
void setDisabledSymbolLayersV2( const QSet<QString> &symbolLayers );
|
||||
|
||||
/**
|
||||
* When rendering a map layer in a second pass (for selective masking),
|
||||
* some symbol layers may be disabled.
|
||||
@ -152,8 +177,21 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
|
||||
* \see setDisabledSymbolLayers()
|
||||
* \see isSymbolLayerEnabled()
|
||||
* \since QGIS 3.12
|
||||
* \deprecated since QGIS 3.28 and replaced with disabledSymbolLayersV2
|
||||
*/
|
||||
QSet<const QgsSymbolLayer *> disabledSymbolLayers() const { return mDisabledSymbolLayers; }
|
||||
Q_DECL_DEPRECATED QSet<const QgsSymbolLayer *> disabledSymbolLayers() const;
|
||||
|
||||
/**
|
||||
* When rendering a map layer in a second pass (for selective masking),
|
||||
* some symbol layers may be disabled.
|
||||
*
|
||||
* Returns the list of disabled symbol layer ids.
|
||||
* \see setDisabledSymbolLayers()
|
||||
* \see isSymbolLayerEnabled()
|
||||
* \since QGIS 3.12
|
||||
* \deprecated since QGIS 3.28 and replaced with disabledSymbolLayersV2
|
||||
*/
|
||||
const QSet<QString> &disabledSymbolLayersV2() const;
|
||||
|
||||
/**
|
||||
* When rendering a map layer in a second pass (for selective masking),
|
||||
@ -164,7 +202,7 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
|
||||
* \see disabledSymbolLayers()
|
||||
* \since QGIS 3.12
|
||||
*/
|
||||
bool isSymbolLayerEnabled( const QgsSymbolLayer *layer ) const { return ! mDisabledSymbolLayers.contains( layer ); }
|
||||
bool isSymbolLayerEnabled( const QgsSymbolLayer *layer ) const;
|
||||
|
||||
/**
|
||||
* Returns the current coordinate transform for the context.
|
||||
@ -521,17 +559,6 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
|
||||
*/
|
||||
void setMaskPainter( QPainter *p, int id = 0 ) { mMaskPainter[id] = p; }
|
||||
|
||||
/**
|
||||
* When rendering a map layer in a second pass (for selective masking),
|
||||
* some symbol layers may be disabled.
|
||||
*
|
||||
* Sets the list of disabled symbol layers.
|
||||
* \see disabledSymbolLayers()
|
||||
* \see isSymbolLayerEnabled()
|
||||
* \since QGIS 3.12
|
||||
*/
|
||||
void setDisabledSymbolLayers( const QSet<const QgsSymbolLayer *> &symbolLayers ) { mDisabledSymbolLayers = symbolLayers; }
|
||||
|
||||
/**
|
||||
* Sets whether rendering operations should use vector operations instead
|
||||
* of any faster raster shortcuts.
|
||||
@ -891,21 +918,17 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
|
||||
*/
|
||||
void setTextureOrigin( const QPointF &origin );
|
||||
|
||||
#ifndef SIP_RUN
|
||||
|
||||
/**
|
||||
* Add a clip \a path to be applied to the \a symbolLayer before rendering
|
||||
* \since QGIS 3.26
|
||||
* \since QGIS 3.26, arguments changed and public API since 3.28
|
||||
*/
|
||||
void addSymbolLayerClipPath( const QgsSymbolLayer *symbolLayer, QPainterPath path );
|
||||
void addSymbolLayerClipPath( const QString &symbolLayerId, QPainterPath path );
|
||||
|
||||
/**
|
||||
* Returns clip paths to be applied to the \a symbolLayer before rendering
|
||||
* \since QGIS 3.26
|
||||
* \since QGIS 3.26, arguments changed and public API since 3.28
|
||||
*/
|
||||
QList<QPainterPath> symbolLayerClipPaths( const QgsSymbolLayer *symbolLayer ) const;
|
||||
|
||||
#endif
|
||||
QList<QPainterPath> symbolLayerClipPaths( const QString &symbolLayerId ) const;
|
||||
|
||||
/**
|
||||
* Returns the range of z-values which should be rendered.
|
||||
@ -1170,7 +1193,7 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
|
||||
bool mHasRenderedFeatureHandlers = false;
|
||||
QVariantMap mCustomRenderingFlags;
|
||||
|
||||
QSet<const QgsSymbolLayer *> mDisabledSymbolLayers;
|
||||
QSet<QString> mDisabledSymbolLayers;
|
||||
|
||||
QList< QgsMapClippingRegion > mClippingRegions;
|
||||
QgsGeometry mFeatureClipGeometry;
|
||||
@ -1189,7 +1212,7 @@ class CORE_EXPORT QgsRenderContext : public QgsTemporalRangeObject
|
||||
long long mCurrentFrame = -1;
|
||||
|
||||
//! clip paths to be applied to the symbol layer before rendering
|
||||
QMap< const QgsSymbolLayer *, QList<QPainterPath> > mSymbolLayerClipPaths;
|
||||
QMap< QString, QList<QPainterPath> > mSymbolLayerClipPaths;
|
||||
|
||||
#ifdef QGISDEBUG
|
||||
bool mHasTransformContext = false;
|
||||
|
@ -1153,6 +1153,7 @@ QgsSymbolLayerList QgsSymbol::cloneLayers() const
|
||||
layer->setLocked( ( *it )->isLocked() );
|
||||
layer->setRenderingPass( ( *it )->renderingPass() );
|
||||
layer->setEnabled( ( *it )->enabled() );
|
||||
layer->setId( ( *it )->id() );
|
||||
lst.append( layer );
|
||||
}
|
||||
return lst;
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <QPainter>
|
||||
#include <QPointF>
|
||||
#include <QPolygonF>
|
||||
#include <QUuid>
|
||||
|
||||
QgsPropertiesDefinition QgsSymbolLayer::sPropertyDefinitions;
|
||||
|
||||
@ -230,6 +231,7 @@ void QgsSymbolLayer::setPaintEffect( QgsPaintEffect *effect )
|
||||
QgsSymbolLayer::QgsSymbolLayer( Qgis::SymbolType type, bool locked )
|
||||
: mType( type )
|
||||
, mLocked( locked )
|
||||
, mId( QUuid::createUuid().toString() )
|
||||
{
|
||||
}
|
||||
|
||||
@ -911,7 +913,7 @@ void QgsSymbolLayer::prepareMasks( const QgsSymbolRenderContext &context )
|
||||
mClipPath.clear();
|
||||
|
||||
const QgsRenderContext &renderContext = context.renderContext();
|
||||
const QList<QPainterPath> clipPaths = renderContext.symbolLayerClipPaths( this );
|
||||
const QList<QPainterPath> clipPaths = renderContext.symbolLayerClipPaths( id() );
|
||||
if ( !clipPaths.isEmpty() )
|
||||
{
|
||||
QPainterPath mergedPaths;
|
||||
@ -929,3 +931,13 @@ void QgsSymbolLayer::prepareMasks( const QgsSymbolRenderContext &context )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void QgsSymbolLayer::setId( const QString &id )
|
||||
{
|
||||
mId = id;
|
||||
}
|
||||
|
||||
const QString &QgsSymbolLayer::id() const
|
||||
{
|
||||
return mId;
|
||||
}
|
||||
|
@ -630,6 +630,20 @@ class CORE_EXPORT QgsSymbolLayer
|
||||
*/
|
||||
virtual void prepareMasks( const QgsSymbolRenderContext &context );
|
||||
|
||||
/**
|
||||
* Set symbol layer identifier
|
||||
* This id has to be unique in the whole project
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
void setId( const QString &id );
|
||||
|
||||
/**
|
||||
* Returns symbol layer identifier
|
||||
* This id is unique in the whole project
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
const QString &id() const;
|
||||
|
||||
protected:
|
||||
|
||||
/**
|
||||
@ -647,7 +661,7 @@ class CORE_EXPORT QgsSymbolLayer
|
||||
bool mLocked = false;
|
||||
QColor mColor;
|
||||
int mRenderingPass = 0;
|
||||
|
||||
QString mId;
|
||||
QgsPropertyCollection mDataDefinedProperties;
|
||||
|
||||
std::unique_ptr< QgsPaintEffect > mPaintEffect;
|
||||
|
@ -20,19 +20,11 @@
|
||||
QString symbolLayerReferenceListToString( const QgsSymbolLayerReferenceList &lst )
|
||||
{
|
||||
QStringList slst;
|
||||
slst.reserve( lst.size() );
|
||||
slst.reserve( lst.size() * 2 );
|
||||
for ( const QgsSymbolLayerReference &ref : lst )
|
||||
{
|
||||
QStringList indexPathStr;
|
||||
const QVector<int> indexPath = ref.symbolLayerId().symbolLayerIndexPath();
|
||||
indexPathStr.reserve( indexPath.size() );
|
||||
for ( const int index : indexPath )
|
||||
{
|
||||
indexPathStr.append( QString::number( index ) );
|
||||
}
|
||||
// this is BAD BAD BAD -- it assumes that the component parts eg the symbolKey has no commas!
|
||||
// a more unique string should have been used as a concatenator here, but it's too late to fix that without breaking projects...
|
||||
slst.append( QStringLiteral( "%1,%2,%3" ).arg( ref.layerId(), ref.symbolLayerId().symbolKey(), indexPathStr.join( ',' ) ) );
|
||||
slst << ref.layerId();
|
||||
slst << ref.symbolLayerIdV2();
|
||||
}
|
||||
return slst.join( ';' );
|
||||
}
|
||||
@ -43,36 +35,57 @@ QgsSymbolLayerReferenceList stringToSymbolLayerReferenceList( const QString &str
|
||||
if ( str.isEmpty() )
|
||||
return lst;
|
||||
|
||||
// when saving we used ; as a concatenator... but that was silly, cos maybe the symbol keys contain this string!
|
||||
// try to handle this gracefully via regex...
|
||||
const thread_local QRegularExpression partsRx( QStringLiteral( "((?:.*?),(?:.*?),(?:(?:\\d+,)+)?(?:\\d+);)" ) );
|
||||
QRegularExpressionMatchIterator partsIt = partsRx.globalMatch( str + ';' );
|
||||
|
||||
while ( partsIt.hasNext() )
|
||||
if ( str.contains( "," ) )
|
||||
{
|
||||
const QRegularExpressionMatch partMatch = partsIt.next();
|
||||
const QString tuple = partMatch.captured( 1 );
|
||||
// TODO QGIS 4 : remove this if branch, keep only else part
|
||||
Q_NOWARN_DEPRECATED_PUSH
|
||||
|
||||
// We should have "layer_id,symbol_key,symbol_layer_index0,symbol_layer_index1,..."
|
||||
// EXCEPT that the symbol_key CAN have commas, so this whole logic is extremely broken.
|
||||
// Let's see if a messy regex can save the day!
|
||||
const thread_local QRegularExpression rx( QStringLiteral( "(.*?),(.*?),((?:\\d+,)+)?(\\d+)" ) );
|
||||
// old masked symbol layer format (before 3.28), we use unique id now!
|
||||
// we load it the old fashion way and we will update the new one later when
|
||||
// the whole project is loaded
|
||||
|
||||
const QRegularExpressionMatch match = rx.match( tuple );
|
||||
if ( !match.hasMatch() )
|
||||
continue;
|
||||
// when saving we used ; as a concatenator... but that was silly, cos maybe the symbol keys contain this string!
|
||||
// try to handle this gracefully via regex...
|
||||
const thread_local QRegularExpression partsRx( QStringLiteral( "((?:.*?),(?:.*?),(?:(?:\\d+,)+)?(?:\\d+);)" ) );
|
||||
QRegularExpressionMatchIterator partsIt = partsRx.globalMatch( str + ';' );
|
||||
|
||||
const QString layerId = match.captured( 1 );
|
||||
const QString symbolKey = match.captured( 2 );
|
||||
const QStringList indices = QString( match.captured( 3 ) + match.captured( 4 ) ).split( ',' );
|
||||
|
||||
QVector<int> indexPath;
|
||||
indexPath.reserve( indices.size() );
|
||||
for ( const QString &index : indices )
|
||||
while ( partsIt.hasNext() )
|
||||
{
|
||||
indexPath.append( index.toInt() );
|
||||
const QRegularExpressionMatch partMatch = partsIt.next();
|
||||
const QString tuple = partMatch.captured( 1 );
|
||||
|
||||
// We should have "layer_id,symbol_key,symbol_layer_index0,symbol_layer_index1,..."
|
||||
// EXCEPT that the symbol_key CAN have commas, so this whole logic is extremely broken.
|
||||
// Let's see if a messy regex can save the day!
|
||||
const thread_local QRegularExpression rx( QStringLiteral( "(.*?),(.*?),((?:\\d+,)+)?(\\d+)" ) );
|
||||
|
||||
const QRegularExpressionMatch match = rx.match( tuple );
|
||||
if ( !match.hasMatch() )
|
||||
continue;
|
||||
|
||||
const QString layerId = match.captured( 1 );
|
||||
const QString symbolKey = match.captured( 2 );
|
||||
const QStringList indices = QString( match.captured( 3 ) + match.captured( 4 ) ).split( ',' );
|
||||
|
||||
QVector<int> indexPath;
|
||||
indexPath.reserve( indices.size() );
|
||||
for ( const QString &index : indices )
|
||||
{
|
||||
indexPath.append( index.toInt() );
|
||||
}
|
||||
lst.append( QgsSymbolLayerReference( layerId, QgsSymbolLayerId( symbolKey, indexPath ) ) );
|
||||
Q_NOWARN_DEPRECATED_POP
|
||||
}
|
||||
lst.append( QgsSymbolLayerReference( layerId, QgsSymbolLayerId( symbolKey, indexPath ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
const QStringList elems = str.split( ";" );
|
||||
for ( int i = 0; i < elems.size(); )
|
||||
{
|
||||
lst << QgsSymbolLayerReference( elems[i], elems[i + 1] );
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
return lst;
|
||||
}
|
||||
|
@ -137,8 +137,12 @@ class CORE_EXPORT QgsSymbolLayerReference
|
||||
QgsSymbolLayerReference() = default;
|
||||
|
||||
//! Constructor
|
||||
QgsSymbolLayerReference( const QString &layerId, const QgsSymbolLayerId &symbolLayer )
|
||||
: mLayerId( layerId ), mSymbolLayerId( symbolLayer )
|
||||
Q_DECL_DEPRECATED QgsSymbolLayerReference( const QString &layerId, const QgsSymbolLayerId &symbolLayer )
|
||||
: mLayerId( layerId ), mDeprecatedSymbolLayerId( symbolLayer )
|
||||
{}
|
||||
|
||||
QgsSymbolLayerReference( const QString &layerId, const QString &symbolLayerId )
|
||||
: mLayerId( layerId ), mSymbolLayerId( symbolLayerId )
|
||||
{}
|
||||
|
||||
/**
|
||||
@ -148,14 +152,22 @@ class CORE_EXPORT QgsSymbolLayerReference
|
||||
|
||||
/**
|
||||
* The symbol layer's id
|
||||
* \deprecated since QGIS 3.28, use symbolLayerIdV2 instead
|
||||
*/
|
||||
QgsSymbolLayerId symbolLayerId() const { return mSymbolLayerId; }
|
||||
Q_DECL_DEPRECATED QgsSymbolLayerId symbolLayerId() const { return mDeprecatedSymbolLayerId; }
|
||||
|
||||
/**
|
||||
* The symbol layer's id
|
||||
* \since QGIS 3.28
|
||||
*/
|
||||
QString symbolLayerIdV2() const { return mSymbolLayerId; }
|
||||
|
||||
//! Comparison operator
|
||||
bool operator==( const QgsSymbolLayerReference &other ) const
|
||||
{
|
||||
return mLayerId == other.mLayerId &&
|
||||
mSymbolLayerId == other.mSymbolLayerId;
|
||||
return mLayerId == other.mLayerId
|
||||
&& mSymbolLayerId == other.mSymbolLayerId
|
||||
&& mDeprecatedSymbolLayerId == other.mDeprecatedSymbolLayerId;
|
||||
}
|
||||
|
||||
#ifdef SIP_RUN
|
||||
@ -167,24 +179,26 @@ class CORE_EXPORT QgsSymbolLayerReference
|
||||
{
|
||||
pathString.append( QString::number( path ) );
|
||||
}
|
||||
QString str = QStringLiteral( "<QgsSymbolLayerReference: %1 - %2 (%3)>" ).arg( sipCpp->layerId(), sipCpp->symbolLayerId().symbolKey(), pathString.join( ',' ) );
|
||||
QString str = QStringLiteral( "<QgsSymbolLayerReference: %1 - %2>" ).arg( sipCpp->layerId(), sipCpp->symbolLayerIdV2() );
|
||||
sipRes = PyUnicode_FromString( str.toUtf8().constData() );
|
||||
% End
|
||||
#endif
|
||||
|
||||
private:
|
||||
QString mLayerId;
|
||||
QgsSymbolLayerId mSymbolLayerId;
|
||||
// TODO QGIS 4 : remove mDeprecatedSymbolLayerId
|
||||
QgsSymbolLayerId mDeprecatedSymbolLayerId;
|
||||
QString mSymbolLayerId;
|
||||
};
|
||||
|
||||
inline uint qHash( const QgsSymbolLayerId &id )
|
||||
Q_DECL_DEPRECATED inline uint qHash( const QgsSymbolLayerId &id )
|
||||
{
|
||||
return qHash( id.symbolKey() ) ^ qHash( id.symbolLayerIndexPath() );
|
||||
}
|
||||
|
||||
inline uint qHash( const QgsSymbolLayerReference &r )
|
||||
{
|
||||
return qHash( r.layerId() ) ^ qHash( r.symbolLayerId() );
|
||||
return qHash( r.layerId() ) ^ qHash( r.symbolLayerIdV2() );
|
||||
}
|
||||
|
||||
typedef QList<QgsSymbolLayerReference> QgsSymbolLayerReferenceList;
|
||||
|
@ -1327,6 +1327,7 @@ QgsSymbolLayer *QgsSymbolLayerUtils::loadSymbolLayer( QDomElement &element, cons
|
||||
const bool locked = element.attribute( QStringLiteral( "locked" ) ).toInt();
|
||||
const bool enabled = element.attribute( QStringLiteral( "enabled" ), QStringLiteral( "1" ) ).toInt();
|
||||
const int pass = element.attribute( QStringLiteral( "pass" ) ).toInt();
|
||||
const QString id = element.attribute( QStringLiteral( "id" ) );
|
||||
|
||||
// parse properties
|
||||
QVariantMap props = parseProperties( element );
|
||||
@ -1344,6 +1345,10 @@ QgsSymbolLayer *QgsSymbolLayerUtils::loadSymbolLayer( QDomElement &element, cons
|
||||
layer->setRenderingPass( pass );
|
||||
layer->setEnabled( enabled );
|
||||
|
||||
// old project format, empty is missing, keep the actual layer one
|
||||
if ( !id.isEmpty() )
|
||||
layer->setId( id );
|
||||
|
||||
//restore layer effect
|
||||
const QDomElement effectElem = element.firstChildElement( QStringLiteral( "effect" ) );
|
||||
if ( !effectElem.isNull() )
|
||||
@ -1424,6 +1429,7 @@ QDomElement QgsSymbolLayerUtils::saveSymbol( const QString &name, const QgsSymbo
|
||||
layerEl.setAttribute( QStringLiteral( "enabled" ), layer->enabled() );
|
||||
layerEl.setAttribute( QStringLiteral( "locked" ), layer->isLocked() );
|
||||
layerEl.setAttribute( QStringLiteral( "pass" ), layer->renderingPass() );
|
||||
layerEl.setAttribute( QStringLiteral( "id" ), layer->id() );
|
||||
|
||||
QVariantMap props = layer->properties();
|
||||
|
||||
|
@ -234,7 +234,7 @@ QDomElement QgsTextMaskSettings::writeXml( QDomDocument &doc ) const
|
||||
return textMaskElem;
|
||||
}
|
||||
|
||||
QList<QgsSymbolLayerReference> QgsTextMaskSettings::maskedSymbolLayers() const
|
||||
const QList<QgsSymbolLayerReference> &QgsTextMaskSettings::maskedSymbolLayers() const
|
||||
{
|
||||
return d->maskedSymbolLayers;
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ class CORE_EXPORT QgsTextMaskSettings
|
||||
* \returns a list of references to masked symbol layers
|
||||
* \see setMaskedSymbolLayers
|
||||
*/
|
||||
QList<QgsSymbolLayerReference> maskedSymbolLayers() const;
|
||||
const QList<QgsSymbolLayerReference> &maskedSymbolLayers() const;
|
||||
|
||||
/**
|
||||
* Sets the symbol layers that will be masked by this buffer.
|
||||
|
@ -977,7 +977,7 @@ QHash<QString, QgsMaskedLayers> QgsVectorLayerUtils::labelMasks( const QgsVector
|
||||
for ( const auto &r : maskSettings.maskedSymbolLayers() )
|
||||
{
|
||||
QgsMaskedLayer &maskedLayer = maskedLayers[currentRule][r.layerId()];
|
||||
maskedLayer.symbolLayerIds.insert( r.symbolLayerId() );
|
||||
maskedLayer.symbolLayerIds.insert( r.symbolLayerIdV2() );
|
||||
maskedLayer.hasEffects = hasEffects;
|
||||
}
|
||||
}
|
||||
@ -1032,7 +1032,7 @@ QgsMaskedLayers QgsVectorLayerUtils::symbolLayerMasks( const QgsVectorLayer *lay
|
||||
{
|
||||
QgsMaskedLayer &maskedLayer = maskedLayers[mask.layerId()];
|
||||
maskedLayer.hasEffects |= slHasEffects;
|
||||
maskedLayer.symbolLayerIds.insert( mask.symbolLayerId() );
|
||||
maskedLayer.symbolLayerIds.insert( mask.symbolLayerIdV2() );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,9 +33,10 @@ struct QgsMaskedLayer
|
||||
bool hasEffects = false;
|
||||
|
||||
// masked symbol layers
|
||||
QSet<QgsSymbolLayerId> symbolLayerIds;
|
||||
QSet<QString> symbolLayerIds;
|
||||
};
|
||||
|
||||
//! masked layers where key is the layer id
|
||||
typedef QHash<QString, QgsMaskedLayer> QgsMaskedLayers;
|
||||
|
||||
#endif
|
||||
|
@ -90,13 +90,13 @@ void QgsMaskingWidget::showEvent( QShowEvent *event )
|
||||
* - mask source symbol layer id
|
||||
* - list of target mask symbol layer references
|
||||
*/
|
||||
QList<QPair<QgsSymbolLayerId, QList<QgsSymbolLayerReference>>> symbolLayerMasks( const QgsVectorLayer *layer )
|
||||
QList<QPair<QString, QList<QgsSymbolLayerReference>>> symbolLayerMasks( const QgsVectorLayer *layer )
|
||||
{
|
||||
if ( ! layer->renderer() )
|
||||
return {};
|
||||
|
||||
QList<QPair<QgsSymbolLayerId, QList<QgsSymbolLayerReference>>> mMasks;
|
||||
SymbolLayerVisitor collector( [&]( const QgsSymbolLayer * sl, const QgsSymbolLayerId & lid )
|
||||
QList<QPair<QString, QList<QgsSymbolLayerReference>>> mMasks;
|
||||
SymbolLayerVisitor collector( [&]( const QgsSymbolLayer * sl, const QString & lid )
|
||||
{
|
||||
if ( ! sl->masks().isEmpty() )
|
||||
mMasks.push_back( qMakePair( lid, sl->masks() ) );
|
||||
@ -120,7 +120,7 @@ void QgsMaskingWidget::populate()
|
||||
mMaskTargetsWidget->setLayer( mLayer );
|
||||
|
||||
// collect masks and filter on those which have the current layer as destination
|
||||
QSet<QgsSymbolLayerId> maskedSymbolLayers;
|
||||
QSet<QString> maskedSymbolLayers;
|
||||
QList<QgsMaskSourceSelectionWidget::MaskSource> maskSources;
|
||||
QMap<QString, QgsMapLayer *> layers = QgsProject::instance()->mapLayers();
|
||||
|
||||
@ -133,16 +133,16 @@ void QgsMaskingWidget::populate()
|
||||
continue;
|
||||
|
||||
// collect symbol layer masks
|
||||
const QList<QPair<QgsSymbolLayerId, QList<QgsSymbolLayerReference>>> slMasks = symbolLayerMasks( vl );
|
||||
for ( const QPair<QgsSymbolLayerId, QList<QgsSymbolLayerReference>> &p : slMasks )
|
||||
const QList<QPair<QString, QList<QgsSymbolLayerReference>>> slMasks = symbolLayerMasks( vl );
|
||||
for ( const QPair<QString, QList<QgsSymbolLayerReference>> &p : slMasks )
|
||||
{
|
||||
const QgsSymbolLayerId &sourceSymbolLayerId = p.first;
|
||||
const QString &sourceSymbolLayerId = p.first;
|
||||
for ( const QgsSymbolLayerReference &ref : p.second )
|
||||
{
|
||||
if ( ref.layerId() == mLayer->id() )
|
||||
{
|
||||
// add to the set of destinations
|
||||
maskedSymbolLayers.insert( ref.symbolLayerId() );
|
||||
maskedSymbolLayers.insert( ref.symbolLayerIdV2() );
|
||||
// add to the list of mask sources
|
||||
source.layerId = layerId;
|
||||
source.isLabeling = false;
|
||||
@ -166,7 +166,7 @@ void QgsMaskingWidget::populate()
|
||||
// add the mask source
|
||||
source.layerId = layerId;
|
||||
source.isLabeling = true;
|
||||
source.symbolLayerId = QgsSymbolLayerId( ruleKey, {} );
|
||||
source.symbolLayerId = ruleKey;
|
||||
maskSources.append( source );
|
||||
}
|
||||
}
|
||||
@ -180,7 +180,7 @@ void QgsMaskingWidget::populate()
|
||||
void QgsMaskingWidget::apply()
|
||||
{
|
||||
QList<QgsMaskSourceSelectionWidget::MaskSource> maskSources = mMaskSourcesWidget->selection();
|
||||
QSet<QgsSymbolLayerId> maskedSymbolLayers = mMaskTargetsWidget->selection();
|
||||
QSet<QString> maskedSymbolLayers = mMaskTargetsWidget->selection();
|
||||
|
||||
QSet<QString> layersToRefresh;
|
||||
|
||||
@ -193,7 +193,7 @@ void QgsMaskingWidget::apply()
|
||||
|
||||
//
|
||||
// First reset symbol layer masks
|
||||
SymbolLayerVisitor maskSetter( [&]( const QgsSymbolLayer * sl, const QgsSymbolLayerId & slId )
|
||||
SymbolLayerVisitor maskSetter( [&]( const QgsSymbolLayer * sl, const QString & slId )
|
||||
{
|
||||
if ( sl->layerType() == "MaskMarker" )
|
||||
{
|
||||
@ -212,7 +212,7 @@ void QgsMaskingWidget::apply()
|
||||
if ( ! source.isLabeling && source.layerId == layerIt.key() && source.symbolLayerId == slId )
|
||||
{
|
||||
// ... then add the new masked symbol layers, if any
|
||||
for ( const QgsSymbolLayerId &maskedId : maskedSymbolLayers )
|
||||
for ( const QString &maskedId : maskedSymbolLayers )
|
||||
{
|
||||
newMasks.append( QgsSymbolLayerReference( mLayer->id(), maskedId ) );
|
||||
}
|
||||
@ -249,9 +249,9 @@ void QgsMaskingWidget::apply()
|
||||
{
|
||||
// ... then add the new masked symbol layers, if any
|
||||
|
||||
if ( source.isLabeling && source.layerId == layerIt.key() && source.symbolLayerId.symbolKey() == labelProvider )
|
||||
if ( source.isLabeling && source.layerId == layerIt.key() && source.symbolLayerId == labelProvider )
|
||||
{
|
||||
for ( const QgsSymbolLayerId &maskedId : maskedSymbolLayers )
|
||||
for ( const QString &maskedId : maskedSymbolLayers )
|
||||
{
|
||||
newMasks.append( QgsSymbolLayerReference( mLayer->id(), maskedId ) );
|
||||
}
|
||||
@ -303,7 +303,7 @@ void SymbolLayerVisitor::visitSymbol( const QgsSymbol *symbol, const QString &le
|
||||
|
||||
const QgsSymbolLayer *sl = symbol->symbolLayer( idx );
|
||||
|
||||
mCallback( sl, QgsSymbolLayerId( mSymbolKey + leafIdentifier, indexPath ) );
|
||||
mCallback( sl, sl->id() );
|
||||
|
||||
// recurse over sub symbols
|
||||
const QgsSymbol *subSymbol = const_cast<QgsSymbolLayer *>( sl )->subSymbol();
|
||||
|
@ -84,7 +84,7 @@ class GUI_EXPORT QgsMaskingWidget: public QgsPanelWidget, private Ui::QgsMasking
|
||||
class SymbolLayerVisitor : public QgsStyleEntityVisitorInterface
|
||||
{
|
||||
public:
|
||||
typedef std::function<void( const QgsSymbolLayer *, const QgsSymbolLayerId & )> SymbolLayerCallback;
|
||||
typedef std::function<void( const QgsSymbolLayer *, const QString & )> SymbolLayerCallback;
|
||||
|
||||
//! constructor
|
||||
SymbolLayerVisitor( SymbolLayerCallback callback );
|
||||
|
@ -34,20 +34,9 @@ static void expandAll( QTreeWidgetItem *item )
|
||||
item->setExpanded( true );
|
||||
}
|
||||
|
||||
void printSymbolLayerId( const QgsSymbolLayerId &lid )
|
||||
{
|
||||
std::cout << lid.symbolKey().toLocal8Bit().constData() << "/";
|
||||
QVector<int> path = lid.symbolLayerIndexPath();
|
||||
for ( int i = 0; i < path.size(); i++ )
|
||||
{
|
||||
std::cout << path[i] << "/";
|
||||
}
|
||||
}
|
||||
|
||||
void printSymbolLayerRef( const QgsSymbolLayerReference &ref )
|
||||
{
|
||||
std::cout << ref.layerId().toLocal8Bit().constData() << "/";
|
||||
printSymbolLayerId( ref.symbolLayerId() );
|
||||
std::cout << ref.layerId().toLocal8Bit().constData() << "/" << ref.symbolLayerIdV2().toLocal8Bit().constData();
|
||||
}
|
||||
|
||||
QgsMaskSourceSelectionWidget::QgsMaskSourceSelectionWidget( QWidget *parent )
|
||||
@ -113,7 +102,7 @@ void QgsMaskSourceSelectionWidget::update()
|
||||
if ( ( sl->layerType() == "MaskMarker" ) ||
|
||||
( subSymbol && visitSymbol( slItem.get(), identifier, subSymbol, indexPath ) ) )
|
||||
{
|
||||
const QgsSymbolLayerReference ref( mLayer->id(), QgsSymbolLayerId( mCurrentIdentifier + identifier, indexPath ) );
|
||||
const QgsSymbolLayerReference ref( mLayer->id(), sl->id() );
|
||||
mItems[ref] = slItem.get();
|
||||
rootItem->addChild( slItem.release() );
|
||||
ret = true;
|
||||
@ -180,7 +169,7 @@ void QgsMaskSourceSelectionWidget::update()
|
||||
slItem->setFlags( slItem->flags() | Qt::ItemIsUserCheckable );
|
||||
slItem->setCheckState( 0, Qt::Unchecked );
|
||||
mLayerItem->addChild( slItem );
|
||||
mItems[QgsSymbolLayerReference( "__labels__" + mLayer->id(), { currentRule, 0 } )] = slItem;
|
||||
mItems[QgsSymbolLayerReference( "__labels__" + mLayer->id(), currentRule )] = slItem;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
@ -237,7 +226,7 @@ QList<QgsMaskSourceSelectionWidget::MaskSource> QgsMaskSourceSelectionWidget::se
|
||||
QgsMaskSourceSelectionWidget::MaskSource source;
|
||||
source.isLabeling = ref.layerId().startsWith( "__labels__" );
|
||||
source.layerId = source.isLabeling ? ref.layerId().mid( 10 ) : ref.layerId();
|
||||
source.symbolLayerId = ref.symbolLayerId();
|
||||
source.symbolLayerId = ref.symbolLayerIdV2();
|
||||
sel.append( source );
|
||||
}
|
||||
}
|
||||
@ -263,4 +252,3 @@ void QgsMaskSourceSelectionWidget::setSelection( const QList<QgsMaskSourceSelect
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,7 @@ class GUI_EXPORT QgsMaskSourceSelectionWidget : public QWidget
|
||||
bool isLabeling = false;
|
||||
|
||||
//! The symbol layer id
|
||||
QgsSymbolLayerId symbolLayerId;
|
||||
QString symbolLayerId;
|
||||
};
|
||||
|
||||
//! constructor
|
||||
|
@ -49,7 +49,7 @@ void QgsSymbolLayerSelectionWidget::setLayer( const QgsVectorLayer *layer )
|
||||
class TreeFillVisitor : public QgsStyleEntityVisitorInterface
|
||||
{
|
||||
public:
|
||||
TreeFillVisitor( QTreeWidgetItem *layerItem, const QgsVectorLayer *layer, QHash<QgsSymbolLayerId, QTreeWidgetItem *> &items ):
|
||||
TreeFillVisitor( QTreeWidgetItem *layerItem, const QgsVectorLayer *layer, QHash<QString, QTreeWidgetItem *> &items ):
|
||||
mLayerItem( layerItem ), mLayer( layer ), mItems( items )
|
||||
{}
|
||||
|
||||
@ -96,7 +96,7 @@ void QgsSymbolLayerSelectionWidget::setLayer( const QgsVectorLayer *layer )
|
||||
rootItem->addChild( slItem );
|
||||
slItem->setExpanded( true );
|
||||
|
||||
mItems[QgsSymbolLayerId( mCurrentIdentifier + identifier, indexPath )] = slItem;
|
||||
mItems[sl->id()] = slItem;
|
||||
|
||||
if ( subSymbol )
|
||||
{
|
||||
@ -133,7 +133,7 @@ void QgsSymbolLayerSelectionWidget::setLayer( const QgsVectorLayer *layer )
|
||||
QString mCurrentIdentifier;
|
||||
QTreeWidgetItem *mLayerItem;
|
||||
const QgsVectorLayer *mLayer;
|
||||
QHash<QgsSymbolLayerId, QTreeWidgetItem *> &mItems;
|
||||
QHash<QString, QTreeWidgetItem *> &mItems;
|
||||
};
|
||||
|
||||
// populate the tree
|
||||
@ -146,9 +146,9 @@ void QgsSymbolLayerSelectionWidget::setLayer( const QgsVectorLayer *layer )
|
||||
mLayer->renderer()->accept( &visitor );
|
||||
}
|
||||
|
||||
QSet<QgsSymbolLayerId> QgsSymbolLayerSelectionWidget::selection() const
|
||||
QSet<QString> QgsSymbolLayerSelectionWidget::selection() const
|
||||
{
|
||||
QSet<QgsSymbolLayerId> sel;
|
||||
QSet<QString> sel;
|
||||
for ( auto it = mItems.begin(); it != mItems.end(); it++ )
|
||||
{
|
||||
if ( it.value()->checkState( 0 ) == Qt::Checked )
|
||||
@ -157,7 +157,7 @@ QSet<QgsSymbolLayerId> QgsSymbolLayerSelectionWidget::selection() const
|
||||
return sel;
|
||||
}
|
||||
|
||||
void QgsSymbolLayerSelectionWidget::setSelection( const QSet<QgsSymbolLayerId> &sel )
|
||||
void QgsSymbolLayerSelectionWidget::setSelection( const QSet<QString> &sel )
|
||||
{
|
||||
// clear selection
|
||||
for ( auto it = mItems.begin(); it != mItems.end(); it++ )
|
||||
@ -167,7 +167,7 @@ void QgsSymbolLayerSelectionWidget::setSelection( const QSet<QgsSymbolLayerId> &
|
||||
}
|
||||
|
||||
// apply selection passed in parameter
|
||||
for ( const QgsSymbolLayerId &lid : sel )
|
||||
for ( const QString &lid : sel )
|
||||
{
|
||||
const auto it = mItems.find( lid );
|
||||
if ( it != mItems.end() )
|
||||
|
@ -45,10 +45,10 @@ class GUI_EXPORT QgsSymbolLayerSelectionWidget : public QWidget
|
||||
void setLayer( const QgsVectorLayer *layer );
|
||||
|
||||
//! Returns current symbol layer selection
|
||||
QSet<QgsSymbolLayerId> selection() const;
|
||||
QSet<QString> selection() const;
|
||||
|
||||
//! Sets the symbol layer selection
|
||||
void setSelection( const QSet<QgsSymbolLayerId> &sel );
|
||||
void setSelection( const QSet<QString> &sel );
|
||||
|
||||
signals:
|
||||
//! Signal emitted when something the configuration is changed
|
||||
@ -61,7 +61,7 @@ class GUI_EXPORT QgsSymbolLayerSelectionWidget : public QWidget
|
||||
const QgsVectorLayer *mLayer = nullptr;
|
||||
|
||||
// Mapping between symbol layer id and tree elements
|
||||
QHash<QgsSymbolLayerId, QTreeWidgetItem *> mItems;
|
||||
QHash<QString, QTreeWidgetItem *> mItems;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -133,6 +133,28 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
with open(report_file_path, 'a') as report_file:
|
||||
report_file.write(self.report)
|
||||
|
||||
def get_symbollayer_ref(self, layer, ruleId, symbollayer_ids):
|
||||
"""
|
||||
Returns the symbol layer according to given path to
|
||||
|
||||
"""
|
||||
|
||||
renderer = layer.renderer()
|
||||
symbol = None
|
||||
if renderer.type() == "categorizedSymbol":
|
||||
i = renderer.categoryIndexForValue(ruleId)
|
||||
cat = renderer.categories()[i]
|
||||
symbol = cat.symbol()
|
||||
elif renderer.type() == "singleSymbol":
|
||||
symbol = renderer.symbol()
|
||||
|
||||
symbollayer = symbol.symbolLayer(symbollayer_ids[0])
|
||||
for i in range(1, len(symbollayer_ids)):
|
||||
symbol = symbollayer.subSymbol()
|
||||
symbollayer = symbol.symbolLayer(symbollayer_ids[i])
|
||||
|
||||
return QgsSymbolLayerReference(layer.id(), symbollayer.id())
|
||||
|
||||
def check_renderings(self, map_settings, control_name):
|
||||
"""Test a rendering with different configurations:
|
||||
- parallel rendering, no cache
|
||||
@ -159,6 +181,10 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
suffix = ("_parallel" if do_parallel else "_sequential") + ("_cache" if use_cache else "_nocache")
|
||||
res = self.checker.compareImages(control_name + suffix)
|
||||
self.report += self.checker.report()
|
||||
f = open("/tmp/merdier.html", "w")
|
||||
f.write(self.report)
|
||||
f.close()
|
||||
|
||||
self.assertTrue(res)
|
||||
|
||||
print(f"=== Rendering took {float(t) / 1000.0}s")
|
||||
@ -216,6 +242,11 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
self.checker.setRenderedImage(image_result_filename)
|
||||
res = self.checker.compareImages(control_name)
|
||||
self.report += self.checker.report()
|
||||
|
||||
f = open("/tmp/merdier.html", "w")
|
||||
f.write(self.report)
|
||||
f.close()
|
||||
|
||||
self.assertTrue(res)
|
||||
|
||||
def test_save_restore_references(self):
|
||||
@ -226,7 +257,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# simple ids
|
||||
mask_layer = QgsMaskMarkerSymbolLayer()
|
||||
mask_layer.setMasks([
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
QgsSymbolLayerReference(self.lines_layer2.id(), QgsSymbolLayerId("some_id", [1, 3, 5, 19])),
|
||||
QgsSymbolLayerReference(self.polys_layer.id(), QgsSymbolLayerId("some_other_id", [4, 5])),
|
||||
])
|
||||
@ -235,7 +266,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
|
||||
mask_layer2 = QgsMaskMarkerSymbolLayer.create(props)
|
||||
self.assertEqual(mask_layer2.masks(), [
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
QgsSymbolLayerReference(self.lines_layer2.id(), QgsSymbolLayerId("some_id", [1, 3, 5, 19])),
|
||||
QgsSymbolLayerReference(self.polys_layer.id(), QgsSymbolLayerId("some_other_id", [4, 5])),
|
||||
])
|
||||
@ -243,7 +274,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# complex ids
|
||||
mask_layer = QgsMaskMarkerSymbolLayer()
|
||||
mask_layer.setMasks([
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
QgsSymbolLayerReference(self.lines_layer2.id(), QgsSymbolLayerId("some id, #1", [1, 3, 5, 19])),
|
||||
QgsSymbolLayerReference(self.polys_layer.id(), QgsSymbolLayerId("some other id, like, this", [4, 5])),
|
||||
])
|
||||
@ -252,7 +283,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
|
||||
mask_layer2 = QgsMaskMarkerSymbolLayer.create(props)
|
||||
self.assertEqual(mask_layer2.masks(), [
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
QgsSymbolLayerReference(self.lines_layer2.id(), QgsSymbolLayerId("some id, #1", [1, 3, 5, 19])),
|
||||
QgsSymbolLayerReference(self.polys_layer.id(), QgsSymbolLayerId("some other id, like, this", [4, 5])),
|
||||
])
|
||||
@ -260,7 +291,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# complex ids, v2
|
||||
mask_layer = QgsMaskMarkerSymbolLayer()
|
||||
mask_layer.setMasks([
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("a string; with bits", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "a string; with bits", [0]),
|
||||
QgsSymbolLayerReference(self.lines_layer2.id(), QgsSymbolLayerId("some; id, #1", [1, 3, 5, 19])),
|
||||
QgsSymbolLayerReference(self.polys_layer.id(), QgsSymbolLayerId("some other; id, lik;e, this", [4, 5])),
|
||||
])
|
||||
@ -269,7 +300,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
|
||||
mask_layer2 = QgsMaskMarkerSymbolLayer.create(props)
|
||||
self.assertEqual(mask_layer2.masks(), [
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("a string; with bits", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "a string; with bits", [0]),
|
||||
QgsSymbolLayerReference(self.lines_layer2.id(), QgsSymbolLayerId("some; id, #1", [1, 3, 5, 19])),
|
||||
QgsSymbolLayerReference(self.polys_layer.id(), QgsSymbolLayerId("some other; id, lik;e, this", [4, 5])),
|
||||
])
|
||||
@ -284,10 +315,10 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
# the black jets
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("B52", 0)),
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("Jet", 0))])
|
||||
self.get_symbollayer_ref(self.points_layer, "B52", [0]),
|
||||
self.get_symbollayer_ref(self.points_layer, "Jet", [0])])
|
||||
|
||||
label_settings.setFormat(fmt)
|
||||
self.polys_layer.labeling().setSettings(label_settings)
|
||||
@ -307,10 +338,10 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_with_labels.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_with_labels, "", [0]),
|
||||
# the black jets
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("B52", 0)),
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("Jet", 0))])
|
||||
self.get_symbollayer_ref(self.points_layer, "B52", [0]),
|
||||
self.get_symbollayer_ref(self.points_layer, "Jet", [0])])
|
||||
|
||||
label_settings.setFormat(fmt)
|
||||
self.polys_layer.labeling().setSettings(label_settings)
|
||||
@ -327,7 +358,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# polygons
|
||||
QgsSymbolLayerReference(self.polys_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.polys_layer, "", [0]),
|
||||
])
|
||||
label_settings.setFormat(fmt)
|
||||
self.lines_with_labels.labeling().setSettings(label_settings)
|
||||
@ -348,7 +379,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_with_labels.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_with_labels, "", [0]),
|
||||
])
|
||||
|
||||
label_settings.setFormat(fmt)
|
||||
@ -366,7 +397,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_with_labels.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_with_labels, "", [0]),
|
||||
])
|
||||
label_settings.setFormat(fmt)
|
||||
self.lines_with_labels.labeling().setSettings(label_settings)
|
||||
@ -390,10 +421,10 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# mask only vertical segments of "roads"
|
||||
QgsSymbolLayerReference(self.lines_layer2.id(), QgsSymbolLayerId("", [1, 0])),
|
||||
self.get_symbollayer_ref(self.lines_layer2, "", [1, 0]),
|
||||
# the black jets
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("B52", 0)),
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("Jet", 0))])
|
||||
self.get_symbollayer_ref(self.points_layer, "B52", [0]),
|
||||
self.get_symbollayer_ref(self.points_layer, "Jet", [0])])
|
||||
|
||||
label_settings.setFormat(fmt)
|
||||
self.polys_layer.labeling().setSettings(label_settings)
|
||||
@ -416,10 +447,10 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
# the black jets
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("B52", 0)),
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("Jet", 0))])
|
||||
self.get_symbollayer_ref(self.points_layer, "B52", [0]),
|
||||
self.get_symbollayer_ref(self.points_layer, "Jet", [0])])
|
||||
|
||||
# overwrite with data-defined properties
|
||||
fmt.dataDefinedProperties().setProperty(QgsPalLayerSettings.MaskEnabled, QgsProperty.fromExpression('1'))
|
||||
@ -455,10 +486,10 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
# the black jets
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("B52", 0)),
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("Jet", 0))])
|
||||
self.get_symbollayer_ref(self.points_layer, "B52", [0]),
|
||||
self.get_symbollayer_ref(self.points_layer, "Jet", [0])])
|
||||
|
||||
label_settings.setFormat(fmt)
|
||||
child.setSettings(label_settings)
|
||||
@ -475,7 +506,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the polygons
|
||||
QgsSymbolLayerReference(self.polys_layer2.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.polys_layer2, "", [0]),
|
||||
])
|
||||
label_settings.setFormat(fmt)
|
||||
child.setSettings(label_settings)
|
||||
@ -495,10 +526,10 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
# the black jets
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("B52", 0)),
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("Jet", 0))])
|
||||
self.get_symbollayer_ref(self.points_layer, "B52", [0]),
|
||||
self.get_symbollayer_ref(self.points_layer, "Jet", [0])])
|
||||
|
||||
label_settings.setFormat(fmt)
|
||||
self.polys_layer.labeling().setSettings(label_settings)
|
||||
@ -520,7 +551,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
mask_layer.setSubSymbol(circle_symbol)
|
||||
mask_layer.setMasks([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
])
|
||||
# add this mask layer to the point layer
|
||||
self.points_layer.renderer().symbol().appendSymbolLayer(mask_layer)
|
||||
@ -540,7 +571,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
mask_layer.setSubSymbol(circle_symbol)
|
||||
mask_layer.setMasks([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
])
|
||||
# add this mask layer to the point layer
|
||||
self.points_layer.renderer().symbol().appendSymbolLayer(mask_layer)
|
||||
@ -558,7 +589,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0))
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0])
|
||||
])
|
||||
label_settings.setFormat(fmt)
|
||||
self.polys_layer.labeling().setSettings(label_settings)
|
||||
@ -579,7 +610,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
mask_layer.setSubSymbol(circle_symbol)
|
||||
mask_layer.setMasks([
|
||||
# the yellow part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 1)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [1]),
|
||||
])
|
||||
# add this mask layer to the point layer
|
||||
self.points_layer.renderer().symbol().appendSymbolLayer(mask_layer)
|
||||
@ -597,7 +628,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0))
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0])
|
||||
])
|
||||
label_settings.setFormat(fmt)
|
||||
self.polys_layer.labeling().setSettings(label_settings)
|
||||
@ -618,7 +649,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
mask_layer.setSubSymbol(circle_symbol)
|
||||
mask_layer.setMasks([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
])
|
||||
# add this mask layer to the point layer
|
||||
self.points_layer.renderer().symbol().appendSymbolLayer(mask_layer)
|
||||
@ -636,7 +667,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the yellow part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 1))
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [1])
|
||||
])
|
||||
label_settings.setFormat(fmt)
|
||||
self.polys_layer.labeling().setSettings(label_settings)
|
||||
@ -679,7 +710,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
mask_layer.setSubSymbol(circle_symbol)
|
||||
mask_layer.setMasks([
|
||||
# the yellow part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 1)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [1]),
|
||||
])
|
||||
# add an outer glow effect to the mask layer
|
||||
blur = QgsOuterGlowEffect.create({"enabled": "1",
|
||||
@ -707,10 +738,10 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
# the black jets
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("B52", 0)),
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("Jet", 0))])
|
||||
self.get_symbollayer_ref(self.points_layer, "B52", [0]),
|
||||
self.get_symbollayer_ref(self.points_layer, "Jet", [0])])
|
||||
|
||||
# add an outer glow effect to the mask
|
||||
blur = QgsOuterGlowEffect.create({"enabled": "1",
|
||||
@ -748,7 +779,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0))])
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0])])
|
||||
|
||||
label_settings.setFormat(fmt)
|
||||
self.polys_layer.labeling().setSettings(label_settings)
|
||||
@ -763,6 +794,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
|
||||
def test_layout_export(self):
|
||||
"""Test mask effects in a layout export at 300 dpi"""
|
||||
|
||||
# modify labeling settings
|
||||
label_settings = self.polys_layer.labeling().settings()
|
||||
fmt = label_settings.format()
|
||||
@ -775,10 +807,10 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
# the black jets
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("B52", 0)),
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("Jet", 0))])
|
||||
self.get_symbollayer_ref(self.points_layer, "B52", [0]),
|
||||
self.get_symbollayer_ref(self.points_layer, "Jet", [0])])
|
||||
|
||||
label_settings.setFormat(fmt)
|
||||
self.polys_layer.labeling().setSettings(label_settings)
|
||||
@ -799,10 +831,10 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
# the black jets
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("B52", 0)),
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("Jet", 0))])
|
||||
self.get_symbollayer_ref(self.points_layer, "B52", [0]),
|
||||
self.get_symbollayer_ref(self.points_layer, "Jet", [0])])
|
||||
|
||||
# add an outer glow effect to the mask
|
||||
blur = QgsOuterGlowEffect.create({"enabled": "1",
|
||||
@ -833,7 +865,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
mask_layer.setSubSymbol(circle_symbol)
|
||||
mask_layer.setMasks([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
])
|
||||
# add this mask layer to the point layer
|
||||
self.points_layer.renderer().symbol().appendSymbolLayer(mask_layer)
|
||||
@ -851,7 +883,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
mask_layer.setSubSymbol(circle_symbol)
|
||||
mask_layer.setMasks([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
])
|
||||
|
||||
# add an outer glow effect to the mask
|
||||
@ -892,10 +924,10 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
# the black jets
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("B52", 0)),
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("Jet", 0))])
|
||||
self.get_symbollayer_ref(self.points_layer, "B52", [0]),
|
||||
self.get_symbollayer_ref(self.points_layer, "Jet", [0])])
|
||||
|
||||
label_settings.setFormat(fmt)
|
||||
self.polys_layer.labeling().setSettings(label_settings)
|
||||
@ -918,7 +950,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
mask_layer.setSubSymbol(circle_symbol)
|
||||
mask_layer.setMasks([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
])
|
||||
# add this mask layer to the point layer
|
||||
self.points_layer.renderer().symbol().appendSymbolLayer(mask_layer)
|
||||
@ -939,7 +971,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
mask_layer.setSubSymbol(circle_symbol)
|
||||
mask_layer.setMasks([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
])
|
||||
# add this mask layer to the point layer
|
||||
self.points_layer.renderer().symbol().appendSymbolLayer(mask_layer)
|
||||
@ -963,10 +995,10 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
# the black jets
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("B52", 0)),
|
||||
QgsSymbolLayerReference(self.points_layer.id(), QgsSymbolLayerId("Jet", 0))])
|
||||
self.get_symbollayer_ref(self.points_layer, "B52", [0]),
|
||||
self.get_symbollayer_ref(self.points_layer, "Jet", [0])])
|
||||
|
||||
label_settings.setFormat(fmt)
|
||||
self.polys_layer.labeling().setSettings(label_settings)
|
||||
@ -989,7 +1021,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0))])
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0])])
|
||||
|
||||
label_settings.setFormat(fmt)
|
||||
self.polys_layer.labeling().setSettings(label_settings)
|
||||
@ -1055,7 +1087,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
mask_layer.setSubSymbol(circle_symbol)
|
||||
mask_layer.setMasks([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0)),
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0]),
|
||||
])
|
||||
self.points_layer.renderer().symbol().appendSymbolLayer(mask_layer)
|
||||
|
||||
@ -1069,7 +1101,7 @@ class TestSelectiveMasking(unittest.TestCase):
|
||||
# and mask other symbol layers underneath
|
||||
fmt.mask().setMaskedSymbolLayers([
|
||||
# the black part of roads
|
||||
QgsSymbolLayerReference(self.lines_layer.id(), QgsSymbolLayerId("", 0))])
|
||||
self.get_symbollayer_ref(self.lines_layer, "", [0])])
|
||||
|
||||
label_settings.setFormat(fmt)
|
||||
self.polys_layer.labeling().setSettings(label_settings)
|
||||
|
Loading…
x
Reference in New Issue
Block a user