Skip to content

Commit

Permalink
[FEATURE] Data defined symbol layer visibility
Browse files Browse the repository at this point in the history
Adds a data defined override to control a symbol layer's
visibility. Allows users to disable drawing certain symbol layers
for matching features.
  • Loading branch information
nyalldawson committed Oct 18, 2016
1 parent b8c2e68 commit a6148de
Show file tree
Hide file tree
Showing 17 changed files with 262 additions and 41 deletions.
9 changes: 6 additions & 3 deletions python/core/symbology-ng/qgssymbollayer.sip
Expand Up @@ -277,16 +277,19 @@ class QgsSymbolLayer
*/
void setPaintEffect( QgsPaintEffect* effect /Transfer/);

protected:
QgsSymbolLayer( QgsSymbol::SymbolType type, bool locked = false );

/** Prepares all data defined property expressions for evaluation. This should
* be called prior to evaluating data defined properties.
* @param context symbol render context
* @note added in QGIS 2.12
*/
virtual void prepareExpressions( const QgsSymbolRenderContext& context );

//! Data defined layer enabled string
static const QString EXPR_LAYER_ENABLED;

protected:
QgsSymbolLayer( QgsSymbol::SymbolType type, bool locked = false );

/** Saves all data defined properties to a string map.
* @param stringMap destination string map
* @see restoreDataDefinedProperties
Expand Down
2 changes: 1 addition & 1 deletion python/gui/symbology-ng/qgslayerpropertieswidget.sip
@@ -1,4 +1,4 @@
class QgsLayerPropertiesWidget : QgsPanelWidget
class QgsLayerPropertiesWidget : QgsPanelWidget, QgsExpressionContextGenerator
{
%TypeHeaderCode
#include <qgslayerpropertieswidget.h>
Expand Down
1 change: 0 additions & 1 deletion src/core/symbology-ng/qgsellipsesymbollayer.cpp
Expand Up @@ -353,7 +353,6 @@ void QgsEllipseSymbolLayer::startRender( QgsSymbolRenderContext& context )
mPen.setJoinStyle( mPenJoinStyle );
mPen.setWidthF( QgsSymbolLayerUtils::convertToPainterUnits( context.renderContext(), mOutlineWidth, mOutlineWidthUnit, mOutlineWidthMapUnitScale ) );
mBrush.setColor( mColor );
prepareExpressions( context );
}

void QgsEllipseSymbolLayer::stopRender( QgsSymbolRenderContext & )
Expand Down
16 changes: 4 additions & 12 deletions src/core/symbology-ng/qgsfillsymbollayer.cpp
Expand Up @@ -258,7 +258,6 @@ void QgsSimpleFillSymbolLayer::startRender( QgsSymbolRenderContext& context )
mPen.setStyle( mBorderStyle );
mPen.setWidthF( QgsSymbolLayerUtils::convertToPainterUnits( context.renderContext(), mBorderWidth, mBorderWidthUnit, mBorderWidthMapUnitScale ) );
mPen.setJoinStyle( mPenJoinStyle );
prepareExpressions( context );
}

void QgsSimpleFillSymbolLayer::stopRender( QgsSymbolRenderContext& context )
Expand Down Expand Up @@ -838,9 +837,6 @@ void QgsGradientFillSymbolLayer::startRender( QgsSymbolRenderContext& context )
QColor selColor = context.renderContext().selectionColor();
if ( ! selectionIsOpaque ) selColor.setAlphaF( context.alpha() );
mSelBrush = QBrush( selColor );

//update mBrush to use a gradient fill with specified properties
prepareExpressions( context );
}

void QgsGradientFillSymbolLayer::stopRender( QgsSymbolRenderContext& context )
Expand Down Expand Up @@ -1132,8 +1128,6 @@ void QgsShapeburstFillSymbolLayer::startRender( QgsSymbolRenderContext& context
QColor selColor = context.renderContext().selectionColor();
if ( ! selectionIsOpaque ) selColor.setAlphaF( context.alpha() );
mSelBrush = QBrush( selColor );

prepareExpressions( context );
}

void QgsShapeburstFillSymbolLayer::stopRender( QgsSymbolRenderContext& context )
Expand Down Expand Up @@ -1996,8 +1990,6 @@ void QgsSVGFillSymbolLayer::startRender( QgsSymbolRenderContext& context )
{
mOutline->startRender( context.renderContext(), context.fields() );
}

prepareExpressions( context );
}

void QgsSVGFillSymbolLayer::stopRender( QgsSymbolRenderContext& context )
Expand Down Expand Up @@ -2831,8 +2823,6 @@ void QgsLinePatternFillSymbolLayer::startRender( QgsSymbolRenderContext& context
{
mFillLineSymbol->startRender( context.renderContext(), context.fields() );
}

prepareExpressions( context );
}

void QgsLinePatternFillSymbolLayer::stopRender( QgsSymbolRenderContext & )
Expand Down Expand Up @@ -3257,7 +3247,6 @@ void QgsPointPatternFillSymbolLayer::startRender( QgsSymbolRenderContext& contex
{
mOutline->startRender( context.renderContext(), context.fields() );
}
prepareExpressions( context );
}

void QgsPointPatternFillSymbolLayer::stopRender( QgsSymbolRenderContext& context )
Expand Down Expand Up @@ -3451,6 +3440,8 @@ QgsSymbolLayer* QgsCentroidFillSymbolLayer::create( const QgsStringMap& properti
if ( properties.contains( "point_on_all_parts" ) )
sl->setPointOnAllParts( properties["point_on_all_parts"].toInt() != 0 );

sl->restoreDataDefinedProperties( properties );

return sl;
}

Expand Down Expand Up @@ -3533,6 +3524,7 @@ QgsStringMap QgsCentroidFillSymbolLayer::properties() const
QgsStringMap map;
map["point_on_surface"] = QString::number( mPointOnSurface );
map["point_on_all_parts"] = QString::number( mPointOnAllParts );
saveDataDefinedProperties( map );
return map;
}

Expand All @@ -3544,6 +3536,7 @@ QgsCentroidFillSymbolLayer* QgsCentroidFillSymbolLayer::clone() const
x->setSubSymbol( mMarker->clone() );
x->setPointOnSurface( mPointOnSurface );
x->setPointOnAllParts( mPointOnAllParts );
copyDataDefinedProperties( x );
copyPaintEffect( x );
return x;
}
Expand Down Expand Up @@ -3760,7 +3753,6 @@ void QgsRasterFillSymbolLayer::renderPolygon( const QPolygonF &points, QList<QPo

void QgsRasterFillSymbolLayer::startRender( QgsSymbolRenderContext &context )
{
prepareExpressions( context );
applyPattern( mBrush, mImageFilePath, mWidth, mAlpha, context );
}

Expand Down
7 changes: 6 additions & 1 deletion src/core/symbology-ng/qgsgeometrygeneratorsymbollayer.cpp
Expand Up @@ -44,6 +44,7 @@ QgsSymbolLayer* QgsGeometryGeneratorSymbolLayer::create( const QgsStringMap& pro
{
symbolLayer->setSubSymbol( QgsFillSymbol::createSimple( properties ) );
}
symbolLayer->restoreDataDefinedProperties( properties );

return symbolLayer;
}
Expand Down Expand Up @@ -117,6 +118,7 @@ QgsSymbolLayer* QgsGeometryGeneratorSymbolLayer::clone() const

clone->setSymbolType( mSymbolType );

copyDataDefinedProperties( clone );
copyPaintEffect( clone );

return clone;
Expand All @@ -138,6 +140,7 @@ QgsStringMap QgsGeometryGeneratorSymbolLayer::properties() const
props.insert( "SymbolType", "Fill" );
break;
}
saveDataDefinedProperties( props );

return props;
}
Expand Down Expand Up @@ -180,7 +183,9 @@ bool QgsGeometryGeneratorSymbolLayer::setSubSymbol( QgsSymbol* symbol )

QSet<QString> QgsGeometryGeneratorSymbolLayer::usedAttributes() const
{
return mSymbol->usedAttributes() + mExpression->referencedColumns();
return QgsSymbolLayer::usedAttributes()
+ mSymbol->usedAttributes()
+ mExpression->referencedColumns();
}

bool QgsGeometryGeneratorSymbolLayer::isCompatibleWithSymbol( QgsSymbol* symbol ) const
Expand Down
6 changes: 0 additions & 6 deletions src/core/symbology-ng/qgslinesymbollayer.cpp
Expand Up @@ -228,9 +228,6 @@ void QgsSimpleLineSymbolLayer::startRender( QgsSymbolRenderContext& context )
if ( ! selectionIsOpaque )
selColor.setAlphaF( context.alpha() );
mSelPen.setColor( selColor );

//prepare expressions for data defined properties
prepareExpressions( context );
}

void QgsSimpleLineSymbolLayer::stopRender( QgsSymbolRenderContext& context )
Expand Down Expand Up @@ -815,9 +812,6 @@ void QgsMarkerLineSymbolLayer::startRender( QgsSymbolRenderContext& context )
mMarker->setRenderHints( hints );

mMarker->startRender( context.renderContext(), context.fields() );

//prepare expressions for data defined properties
prepareExpressions( context );
}

void QgsMarkerLineSymbolLayer::stopRender( QgsSymbolRenderContext& context )
Expand Down
4 changes: 0 additions & 4 deletions src/core/symbology-ng/qgsmarkersymbollayer.cpp
Expand Up @@ -160,8 +160,6 @@ void QgsSimpleMarkerSymbolLayerBase::startRender( QgsSymbolRenderContext &contex
else
mPath = transform.map( mPath );

prepareExpressions( context );

QgsMarkerSymbolLayer::startRender( context );
}

Expand Down Expand Up @@ -1909,7 +1907,6 @@ void QgsSvgMarkerSymbolLayer::startRender( QgsSymbolRenderContext& context )
{
QgsMarkerSymbolLayer::startRender( context ); // get anchor point expressions
Q_UNUSED( context );
prepareExpressions( context );
}

void QgsSvgMarkerSymbolLayer::stopRender( QgsSymbolRenderContext& context )
Expand Down Expand Up @@ -2574,7 +2571,6 @@ void QgsFontMarkerSymbolLayer::startRender( QgsSymbolRenderContext& context )
mChrWidth = mFontMetrics->width( mChr );
mChrOffset = QPointF( mChrWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
mOrigSize = mSize; // save in case the size would be data defined
prepareExpressions( context );
}

void QgsFontMarkerSymbolLayer::stopRender( QgsSymbolRenderContext& context )
Expand Down
33 changes: 33 additions & 0 deletions src/core/symbology-ng/qgssymbol.cpp
Expand Up @@ -400,6 +400,7 @@ void QgsSymbol::startRender( QgsRenderContext& context, const QgsFields& fields
if ( !layer->enabled() )
continue;

layer->prepareExpressions( symbolContext );
layer->startRender( symbolContext );
}
}
Expand Down Expand Up @@ -610,6 +611,14 @@ void QgsSymbol::renderUsingLayer( QgsSymbolLayer* layer, QgsSymbolRenderContext&
{
Q_ASSERT( layer->type() == Hybrid );

if ( layer->hasDataDefinedProperty( QgsSymbolLayer::EXPR_LAYER_ENABLED ) )
{
bool ok = false;
bool enabled = layer->evaluateDataDefinedProperty( QgsSymbolLayer::EXPR_LAYER_ENABLED, context, QVariant(), &ok ).toBool();
if ( ok && !enabled )
return;
}

QgsGeometryGeneratorSymbolLayer* generatorLayer = static_cast<QgsGeometryGeneratorSymbolLayer*>( layer );

QgsPaintEffect* effect = generatorLayer->paintEffect();
Expand Down Expand Up @@ -1403,6 +1412,14 @@ void QgsMarkerSymbol::renderPointUsingLayer( QgsMarkerSymbolLayer* layer, QPoint
{
static QPointF nullPoint( 0, 0 );

if ( layer->hasDataDefinedProperty( QgsSymbolLayer::EXPR_LAYER_ENABLED ) )
{
bool ok = false;
bool enabled = layer->evaluateDataDefinedProperty( QgsSymbolLayer::EXPR_LAYER_ENABLED, context, QVariant(), &ok ).toBool();
if ( ok && !enabled )
return;
}

QgsPaintEffect* effect = layer->paintEffect();
if ( effect && effect->enabled() )
{
Expand Down Expand Up @@ -1676,6 +1693,14 @@ void QgsLineSymbol::renderPolyline( const QPolygonF& points, const QgsFeature* f

void QgsLineSymbol::renderPolylineUsingLayer( QgsLineSymbolLayer *layer, const QPolygonF &points, QgsSymbolRenderContext &context )
{
if ( layer->hasDataDefinedProperty( QgsSymbolLayer::EXPR_LAYER_ENABLED ) )
{
bool ok = false;
bool enabled = layer->evaluateDataDefinedProperty( QgsSymbolLayer::EXPR_LAYER_ENABLED, context, QVariant(), &ok ).toBool();
if ( ok && !enabled )
return;
}

QgsPaintEffect* effect = layer->paintEffect();
if ( effect && effect->enabled() )
{
Expand Down Expand Up @@ -1748,6 +1773,14 @@ void QgsFillSymbol::renderPolygon( const QPolygonF& points, QList<QPolygonF>* ri

void QgsFillSymbol::renderPolygonUsingLayer( QgsSymbolLayer* layer, const QPolygonF& points, QList<QPolygonF>* rings, QgsSymbolRenderContext& context )
{
if ( layer->hasDataDefinedProperty( QgsSymbolLayer::EXPR_LAYER_ENABLED ) )
{
bool ok = false;
bool enabled = layer->evaluateDataDefinedProperty( QgsSymbolLayer::EXPR_LAYER_ENABLED, context, QVariant(), &ok ).toBool();
if ( ok && !enabled )
return;
}

QgsSymbol::SymbolType layertype = layer->type();

QgsPaintEffect* effect = layer->paintEffect();
Expand Down
1 change: 1 addition & 0 deletions src/core/symbology-ng/qgssymbollayer.cpp
Expand Up @@ -89,6 +89,7 @@ const QString QgsSymbolLayer::EXPR_INTERVAL( "interval" );
const QString QgsSymbolLayer::EXPR_OFFSET_ALONG_LINE( "offset_along_line" );
const QString QgsSymbolLayer::EXPR_HORIZONTAL_ANCHOR_POINT( "horizontal_anchor_point" );
const QString QgsSymbolLayer::EXPR_VERTICAL_ANCHOR_POINT( "vertical_anchor_point" );
const QString QgsSymbolLayer::EXPR_LAYER_ENABLED( "enabled" );

QgsDataDefined *QgsSymbolLayer::getDataDefinedProperty( const QString &property ) const
{
Expand Down
17 changes: 10 additions & 7 deletions src/core/symbology-ng/qgssymbollayer.h
Expand Up @@ -278,6 +278,16 @@ class CORE_EXPORT QgsSymbolLayer
*/
void setPaintEffect( QgsPaintEffect* effect );

/** Prepares all data defined property expressions for evaluation. This should
* be called prior to evaluating data defined properties.
* @param context symbol render context
* @note added in QGIS 2.12
*/
virtual void prepareExpressions( const QgsSymbolRenderContext& context );

//! Data defined layer enabled string
static const QString EXPR_LAYER_ENABLED;

protected:
QgsSymbolLayer( QgsSymbol::SymbolType type, bool locked = false );

Expand All @@ -299,13 +309,6 @@ class CORE_EXPORT QgsSymbolLayer
static const bool selectFillBorder = false; // Fill symbol layer also selects border symbology
static const bool selectFillStyle = false; // Fill symbol uses symbol layer style..

/** Prepares all data defined property expressions for evaluation. This should
* be called prior to evaluating data defined properties.
* @param context symbol render context
* @note added in QGIS 2.12
*/
virtual void prepareExpressions( const QgsSymbolRenderContext& context );

/** Saves all data defined properties to a string map.
* @param stringMap destination string map
* @see restoreDataDefinedProperties
Expand Down

0 comments on commit a6148de

Please sign in to comment.