Skip to content

Commit

Permalink
Data defined symbology for simple line symbol layer
Browse files Browse the repository at this point in the history
  • Loading branch information
mhugent committed Mar 22, 2013
1 parent 12f0947 commit aa70d07
Show file tree
Hide file tree
Showing 2 changed files with 218 additions and 4 deletions.
204 changes: 200 additions & 4 deletions src/core/symbology-ng/qgslinesymbollayerv2.cpp
Expand Up @@ -15,9 +15,10 @@

#include "qgslinesymbollayerv2.h"
#include "qgssymbollayerv2utils.h"

#include "qgsexpression.h"
#include "qgsrendercontext.h"
#include "qgslogger.h"
#include "qgsvectorlayer.h"

#include <QPainter>
#include <QDomDocument>
Expand All @@ -27,13 +28,135 @@

QgsSimpleLineSymbolLayerV2::QgsSimpleLineSymbolLayerV2( QColor color, double width, Qt::PenStyle penStyle )
: mPenStyle( penStyle ), mPenJoinStyle( DEFAULT_SIMPLELINE_JOINSTYLE ), mPenCapStyle( DEFAULT_SIMPLELINE_CAPSTYLE ), mOffset( 0 ), mOffsetUnit( QgsSymbolV2::MM ),
mUseCustomDashPattern( false ), mCustomDashPatternUnit( QgsSymbolV2::MM )
mUseCustomDashPattern( false ), mCustomDashPatternUnit( QgsSymbolV2::MM ), mStrokeColorExpression( 0 ), mStrokeWidthExpression( 0 ), mLineOffsetExpression( 0 ),
mDashPatternExpression( 0 ), mJoinStyleExpression( 0 ), mCapStyleExpression( 0 )
{
mColor = color;
mWidth = width;
mCustomDashVector << 5 << 2;
}

QgsSimpleLineSymbolLayerV2::~QgsSimpleLineSymbolLayerV2()
{
delete mStrokeColorExpression; delete mStrokeWidthExpression; delete mLineOffsetExpression;
delete mDashPatternExpression; delete mJoinStyleExpression; delete mCapStyleExpression;
}

QSet<QString> QgsSimpleLineSymbolLayerV2::usedAttributes() const
{
QSet<QString> attributes;

//add data defined attributes
QStringList columns;
if ( mStrokeColorExpression )
columns.append( mStrokeColorExpression->referencedColumns() );
if ( mStrokeWidthExpression )
columns.append( mStrokeWidthExpression->referencedColumns() );
if ( mLineOffsetExpression )
columns.append( mLineOffsetExpression->referencedColumns() );
if ( mDashPatternExpression )
columns.append( mDashPatternExpression->referencedColumns() );
if ( mJoinStyleExpression )
columns.append( mJoinStyleExpression->referencedColumns() );
if ( mCapStyleExpression )
columns.append( mCapStyleExpression->referencedColumns() );

QStringList::const_iterator it = columns.constBegin();
for ( ; it != columns.constEnd(); ++it )
{
attributes.insert( *it );
}
return attributes;
}

const QgsExpression* QgsSimpleLineSymbolLayerV2::dataDefinedProperty( const QString& property ) const
{
if ( property == "color" )
{
return mStrokeColorExpression;
}
else if ( property == "width" )
{
return mStrokeWidthExpression;
}
else if ( property == "offset" )
{
return mLineOffsetExpression;
}
else if ( property == "customdash" )
{
return mDashPatternExpression;
}
else if ( property == "joinstyle" )
{
return mJoinStyleExpression;
}
else if ( property == "capstyle" )
{
return mCapStyleExpression;
}
else
{
return 0;
}
}

void QgsSimpleLineSymbolLayerV2::setDataDefinedProperty( const QString& property, const QString& expressionString )
{
if ( property == "color" )
{
delete mStrokeColorExpression; mStrokeColorExpression = new QgsExpression( expressionString );
}
else if ( property == "width" )
{
delete mStrokeWidthExpression; mStrokeWidthExpression = new QgsExpression( expressionString );
}
else if ( property == "offset" )
{
delete mLineOffsetExpression; mLineOffsetExpression = new QgsExpression( expressionString );
}
else if ( property == "customdash" )
{
delete mDashPatternExpression; mDashPatternExpression = new QgsExpression( expressionString );
}
else if ( property == "joinstyle" )
{
delete mJoinStyleExpression; mJoinStyleExpression = new QgsExpression( expressionString );
}
else if ( property == "capstyle" )
{
delete mCapStyleExpression; mCapStyleExpression = new QgsExpression( expressionString );
}
}

void QgsSimpleLineSymbolLayerV2::removeDataDefinedProperty( const QString& property )
{
if ( property == "color" )
{
delete mStrokeColorExpression; mStrokeColorExpression = 0;
}
else if ( property == "width" )
{
delete mStrokeWidthExpression; mStrokeWidthExpression = 0;
}
else if ( property == "offset" )
{
delete mLineOffsetExpression; mLineOffsetExpression = 0;
}
else if ( property == "customdash" )
{
delete mDashPatternExpression; mDashPatternExpression = 0;
}
else if ( property == "joinstyle" )
{
delete mJoinStyleExpression; mJoinStyleExpression = 0;
}
else if ( property == "capstyle" )
{
delete mCapStyleExpression; mCapStyleExpression = 0;
}
}

void QgsSimpleLineSymbolLayerV2::setOutputUnit( QgsSymbolV2::OutputUnit unit )
{
mWidthUnit = unit;
Expand Down Expand Up @@ -90,6 +213,21 @@ QgsSymbolLayerV2* QgsSimpleLineSymbolLayerV2::create( const QgsStringMap& props
{
l->setCustomDashPatternUnit( QgsSymbolLayerV2Utils::decodeOutputUnit( props["customdash_unit"] ) );
}

//data defined properties
if ( props.contains( "color_expression" ) )
l->setDataDefinedProperty( "color_expression", props["color_expression"] );
if ( props.contains( "width_expression" ) )
l->setDataDefinedProperty( "width_expression", props["width_expression"] );
if ( props.contains( "offset_expression" ) )
l->setDataDefinedProperty( "offset_expression", props["offset_expression"] );
if ( props.contains( "customdash_expression" ) )
l->setDataDefinedProperty( "customdash_expression", props["customdash_expression"] );
if ( props.contains( "joinstyle_expression" ) )
l->setDataDefinedProperty( "joinstyle_expression", props["joinstyle_expression"] );
if ( props.contains( "capstyle_expression" ) )
l->setDataDefinedProperty( "capstyle_expression", props["capstyle_expression"] );

return l;
}

Expand Down Expand Up @@ -132,6 +270,25 @@ void QgsSimpleLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context
if ( ! selectionIsOpaque )
selColor.setAlphaF( context.alpha() );
mSelPen.setColor( selColor );

//prepare expressions for data defined properties
const QgsVectorLayer* vLayer = context.layer();
if ( vLayer )
{
const QgsFields& fields = vLayer->pendingFields();
if ( mStrokeColorExpression )
mStrokeColorExpression->prepare( fields );
if ( mStrokeWidthExpression )
mStrokeWidthExpression->prepare( fields );
if ( mLineOffsetExpression )
mLineOffsetExpression->prepare( fields );
if ( mDashPatternExpression )
mDashPatternExpression->prepare( fields );
if ( mJoinStyleExpression )
mJoinStyleExpression->prepare( fields );
if ( mCapStyleExpression )
mCapStyleExpression->prepare( fields );
}
}

void QgsSimpleLineSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
Expand All @@ -147,9 +304,18 @@ void QgsSimpleLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSym
return;
}

if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale )
//data defined properties
double scaledWidth = 0;
if ( mStrokeWidthExpression )
{
double scaledWidth = mWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit );
scaledWidth = mStrokeWidthExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble()
* QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit );
mPen.setWidthF( scaledWidth );
mSelPen.setWidthF( scaledWidth );
}
else if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale )
{
scaledWidth = mWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit );
mPen.setWidthF( scaledWidth );
mSelPen.setWidthF( scaledWidth );
}
Expand Down Expand Up @@ -180,6 +346,21 @@ QgsStringMap QgsSimpleLineSymbolLayerV2::properties() const
map["use_custom_dash"] = ( mUseCustomDashPattern ? "1" : "0" );
map["customdash"] = QgsSymbolLayerV2Utils::encodeRealVector( mCustomDashVector );
map["customdash_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mCustomDashPatternUnit );

//data defined properties
if ( mStrokeColorExpression )
map["color_expression"] = mStrokeColorExpression->dump();
if ( mStrokeWidthExpression )
map["width_expression"] = mStrokeWidthExpression->dump();
if ( mLineOffsetExpression )
map["offset_expression"] = mLineOffsetExpression->dump();
if ( mDashPatternExpression )
map["customdash_expression"] = mDashPatternExpression->dump();
if ( mJoinStyleExpression )
map["joinstyle_expression"] = mJoinStyleExpression->dump();
if ( mCapStyleExpression )
map["capstyle_expression"] = mCapStyleExpression->dump();

return map;
}

Expand All @@ -194,6 +375,21 @@ QgsSymbolLayerV2* QgsSimpleLineSymbolLayerV2::clone() const
l->setPenCapStyle( mPenCapStyle );
l->setUseCustomDashPattern( mUseCustomDashPattern );
l->setCustomDashVector( mCustomDashVector );

//data defined properties
if ( mStrokeColorExpression )
l->setDataDefinedProperty( "color", mStrokeColorExpression->dump() );
if ( mStrokeWidthExpression )
l->setDataDefinedProperty( "width", mStrokeWidthExpression->dump() );
if ( mLineOffsetExpression )
l->setDataDefinedProperty( "offset", mLineOffsetExpression->dump() );
if ( mDashPatternExpression )
l->setDataDefinedProperty( "customdash", mDashPatternExpression->dump() );
if ( mJoinStyleExpression )
l->setDataDefinedProperty( "joinstyle", mJoinStyleExpression->dump() );
if ( mCapStyleExpression )
l->setDataDefinedProperty( "capstyle", mCapStyleExpression->dump() );

return l;
}

Expand Down
18 changes: 18 additions & 0 deletions src/core/symbology-ng/qgslinesymbollayerv2.h
Expand Up @@ -21,6 +21,8 @@
#include <QPen>
#include <QVector>

class QgsExpression;

#define DEFAULT_SIMPLELINE_COLOR QColor(0,0,0)
#define DEFAULT_SIMPLELINE_WIDTH DEFAULT_LINE_WIDTH
#define DEFAULT_SIMPLELINE_PENSTYLE Qt::SolidLine
Expand All @@ -35,6 +37,8 @@ class CORE_EXPORT QgsSimpleLineSymbolLayerV2 : public QgsLineSymbolLayerV2
double width = DEFAULT_SIMPLELINE_WIDTH,
Qt::PenStyle penStyle = DEFAULT_SIMPLELINE_PENSTYLE );

~QgsSimpleLineSymbolLayerV2();

// static stuff

static QgsSymbolLayerV2* create( const QgsStringMap& properties = QgsStringMap() );
Expand Down Expand Up @@ -87,6 +91,12 @@ class CORE_EXPORT QgsSimpleLineSymbolLayerV2 : public QgsLineSymbolLayerV2
QVector<qreal> customDashVector() const { return mCustomDashVector; }
void setCustomDashVector( const QVector<qreal>& vector ) { mCustomDashVector = vector; }

const QgsExpression* dataDefinedProperty( const QString& property ) const;
void setDataDefinedProperty( const QString& property, const QString& expressionString );
void removeDataDefinedProperty( const QString& property );

QSet<QString> usedAttributes() const;

protected:
Qt::PenStyle mPenStyle;
Qt::PenJoinStyle mPenJoinStyle;
Expand All @@ -102,6 +112,14 @@ class CORE_EXPORT QgsSimpleLineSymbolLayerV2 : public QgsLineSymbolLayerV2

/**Vector with an even number of entries for the */
QVector<qreal> mCustomDashVector;

//data defined properties
QgsExpression* mStrokeColorExpression;
QgsExpression* mStrokeWidthExpression;
QgsExpression* mLineOffsetExpression;
QgsExpression* mDashPatternExpression;
QgsExpression* mJoinStyleExpression;
QgsExpression* mCapStyleExpression;
};

/////////
Expand Down

0 comments on commit aa70d07

Please sign in to comment.