Skip to content

Commit f13fc31

Browse files
committedMar 29, 2013
Data defined properties for simple fill
1 parent fdd8199 commit f13fc31

File tree

5 files changed

+297
-63
lines changed

5 files changed

+297
-63
lines changed
 

‎src/core/symbology-ng/qgsfillsymbollayerv2.cpp

Lines changed: 161 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#include "qgsmarkersymbollayerv2.h"
1717
#include "qgssymbollayerv2utils.h"
1818

19+
#include "qgsexpression.h"
1920
#include "qgsrendercontext.h"
2021
#include "qgsproject.h"
2122
#include "qgssvgcache.h"
@@ -29,7 +30,7 @@
2930

3031
QgsSimpleFillSymbolLayerV2::QgsSimpleFillSymbolLayerV2( QColor color, Qt::BrushStyle style, QColor borderColor, Qt::PenStyle borderStyle, double borderWidth )
3132
: mBrushStyle( style ), mBorderColor( borderColor ), mBorderStyle( borderStyle ), mBorderWidth( borderWidth ), mBorderWidthUnit( QgsSymbolV2::MM ),
32-
mOffsetUnit( QgsSymbolV2::MM )
33+
mOffsetUnit( QgsSymbolV2::MM ), mColorExpression( 0 ), mColorBorderExpression( 0 ), mWidthBorderExpression( 0 )
3334
{
3435
mColor = color;
3536
}
@@ -50,6 +51,124 @@ QgsSymbolV2::OutputUnit QgsSimpleFillSymbolLayerV2::outputUnit() const
5051
return unit;
5152
}
5253

54+
const QgsExpression* QgsSimpleFillSymbolLayerV2::dataDefinedProperty( const QString& property ) const
55+
{
56+
if ( property == "color" )
57+
{
58+
return mColorExpression;
59+
}
60+
else if ( property == "color_border" )
61+
{
62+
return mColorBorderExpression;
63+
}
64+
else if ( property == "width_border" )
65+
{
66+
return mWidthBorderExpression;
67+
}
68+
return 0;
69+
}
70+
71+
QString QgsSimpleFillSymbolLayerV2::dataDefinedPropertyString( const QString& property ) const
72+
{
73+
const QgsExpression* ex = dataDefinedProperty( property );
74+
return ex ? ex->dump() : QString();
75+
}
76+
77+
void QgsSimpleFillSymbolLayerV2::setDataDefinedProperty( const QString& property, const QString& expressionString )
78+
{
79+
if ( property == "color" )
80+
{
81+
delete mColorExpression; mColorExpression = new QgsExpression( expressionString );
82+
}
83+
else if ( property == "color_border" )
84+
{
85+
delete mColorBorderExpression; mColorBorderExpression = new QgsExpression( expressionString );
86+
}
87+
else if ( property == "width_border" )
88+
{
89+
delete mWidthBorderExpression; mWidthBorderExpression = new QgsExpression( expressionString );
90+
}
91+
}
92+
93+
void QgsSimpleFillSymbolLayerV2::removeDataDefinedProperty( const QString& property )
94+
{
95+
if ( property == "color" )
96+
{
97+
delete mColorExpression; mColorExpression = 0;
98+
}
99+
else if ( property == "color_border" )
100+
{
101+
delete mColorBorderExpression; mColorBorderExpression = 0;
102+
}
103+
else if ( property == "width_border" )
104+
{
105+
delete mWidthBorderExpression; mWidthBorderExpression = 0;
106+
}
107+
}
108+
109+
void QgsSimpleFillSymbolLayerV2::removeDataDefinedProperties()
110+
{
111+
delete mColorExpression; mColorExpression = 0;
112+
delete mColorBorderExpression; mColorBorderExpression = 0;
113+
delete mWidthBorderExpression; mWidthBorderExpression = 0;
114+
}
115+
116+
QSet<QString> QgsSimpleFillSymbolLayerV2::usedAttributes() const
117+
{
118+
QSet<QString> attributes;
119+
120+
//add data defined attributes
121+
QStringList columns;
122+
if ( mColorExpression )
123+
columns.append( mColorExpression->referencedColumns() );
124+
if ( mColorBorderExpression )
125+
columns.append( mColorBorderExpression->referencedColumns() );
126+
if ( mWidthBorderExpression )
127+
columns.append( mWidthBorderExpression->referencedColumns() );
128+
129+
QStringList::const_iterator it = columns.constBegin();
130+
for ( ; it != columns.constEnd(); ++it )
131+
{
132+
attributes.insert( *it );
133+
}
134+
return attributes;
135+
}
136+
137+
void QgsSimpleFillSymbolLayerV2::prepareExpressions( const QgsVectorLayer* vl )
138+
{
139+
if ( !vl )
140+
{
141+
return;
142+
}
143+
144+
const QgsFields& fields = vl->pendingFields();
145+
if ( mColorExpression )
146+
mColorExpression->prepare( fields );
147+
if ( mColorBorderExpression )
148+
mColorBorderExpression->prepare( fields );
149+
if ( mWidthBorderExpression )
150+
mWidthBorderExpression->prepare( fields );
151+
}
152+
153+
void QgsSimpleFillSymbolLayerV2::applyDataDefinedSymbology( QgsSymbolV2RenderContext& context, QBrush& brush, QPen& pen, QPen& selPen )
154+
{
155+
if ( mColorExpression )
156+
{
157+
brush.setColor( QColor( mColorExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() ) );
158+
}
159+
if ( mColorBorderExpression )
160+
{
161+
pen.setColor( QColor( mColorBorderExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toString() ) );
162+
}
163+
if ( mWidthBorderExpression )
164+
{
165+
double width = mWidthBorderExpression->evaluate( const_cast<QgsFeature*>( context.feature() ) ).toDouble();
166+
width *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mBorderWidthUnit );
167+
pen.setWidthF( width );
168+
selPen.setWidthF( width );
169+
}
170+
}
171+
53172

54173
QgsSymbolLayerV2* QgsSimpleFillSymbolLayerV2::create( const QgsStringMap& props )
55174
{
@@ -79,6 +198,19 @@ QgsSymbolLayerV2* QgsSimpleFillSymbolLayerV2::create( const QgsStringMap& props
79198
sl->setBorderWidthUnit( QgsSymbolLayerV2Utils::decodeOutputUnit( props["border_width_unit"] ) );
80199
if ( props.contains( "offset_unit" ) )
81200
sl->setOffsetUnit( QgsSymbolLayerV2Utils::decodeOutputUnit( props["offset_unit"] ) );
201+
202+
if ( props.contains( "color_expression" ) )
203+
{
204+
sl->setDataDefinedProperty( "color", props["color_expression"] );
205+
}
206+
if ( props.contains( "color_border_expression" ) )
207+
{
208+
sl->setDataDefinedProperty( "color_border", props["color_border_expression"] );
209+
}
210+
if ( props.contains( "width_border_expression" ) )
211+
{
212+
sl->setDataDefinedProperty( "width_border", props["width_border_expression"] );
213+
}
82214
return sl;
83215
}
84216

@@ -116,6 +248,7 @@ void QgsSimpleFillSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context
116248
mSelPen = QPen( selPenColor );
117249
mPen.setStyle( mBorderStyle );
118250
mPen.setWidthF( mBorderWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mBorderWidthUnit ) );
251+
prepareExpressions( context.layer() );
119252
}
120253

121254
void QgsSimpleFillSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
@@ -131,6 +264,8 @@ void QgsSimpleFillSymbolLayerV2::renderPolygon( const QPolygonF& points, QList<Q
131264
return;
132265
}
133266

267+
applyDataDefinedSymbology( context, mBrush, mPen, mSelPen );
268+
134269
p->setBrush( context.selected() ? mSelBrush : mBrush );
135270
p->setPen( mPen );
136271
p->setPen( context.selected() ? mSelPen : mPen );
@@ -162,6 +297,18 @@ QgsStringMap QgsSimpleFillSymbolLayerV2::properties() const
162297
map["border_width_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mBorderWidthUnit );
163298
map["offset"] = QgsSymbolLayerV2Utils::encodePoint( mOffset );
164299
map["offset_unit"] = QgsSymbolLayerV2Utils::encodeOutputUnit( mOffsetUnit );
300+
if ( mColorExpression )
301+
{
302+
map["color_expression"] = mColorExpression->dump();
303+
}
304+
if ( mColorBorderExpression )
305+
{
306+
map["color_border_expression"] = mColorBorderExpression->dump();
307+
}
308+
if ( mWidthBorderExpression )
309+
{
310+
map["width_border_expression"] = mWidthBorderExpression->dump();
311+
}
165312
return map;
166313
}
167314

@@ -171,6 +318,19 @@ QgsSymbolLayerV2* QgsSimpleFillSymbolLayerV2::clone() const
171318
sl->setOffset( mOffset );
172319
sl->setOffsetUnit( mOffsetUnit );
173320
sl->setBorderWidthUnit( mBorderWidthUnit );
321+
322+
if ( mColorExpression )
323+
{
324+
sl->setDataDefinedProperty( "color", mColorExpression->dump() );
325+
}
326+
if ( mColorBorderExpression )
327+
{
328+
sl->setDataDefinedProperty( "color_border", mColorBorderExpression->dump() );
329+
}
330+
if ( mWidthBorderExpression )
331+
{
332+
sl->setDataDefinedProperty( "width_border", mWidthBorderExpression->dump() );
333+
}
174334
return sl;
175335
}
176336

‎src/core/symbology-ng/qgsfillsymbollayerv2.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ class CORE_EXPORT QgsSimpleFillSymbolLayerV2 : public QgsFillSymbolLayerV2
8383
void setOutputUnit( QgsSymbolV2::OutputUnit unit );
8484
QgsSymbolV2::OutputUnit outputUnit() const;
8585

86+
const QgsExpression* dataDefinedProperty( const QString& property ) const;
87+
QString dataDefinedPropertyString( const QString& property ) const;
88+
void setDataDefinedProperty( const QString& property, const QString& expressionString );
89+
void removeDataDefinedProperty( const QString& property );
90+
void removeDataDefinedProperties();
91+
92+
QSet<QString> usedAttributes() const;
93+
8694
protected:
8795
QBrush mBrush;
8896
QBrush mSelBrush;
@@ -96,6 +104,16 @@ class CORE_EXPORT QgsSimpleFillSymbolLayerV2 : public QgsFillSymbolLayerV2
96104

97105
QPointF mOffset;
98106
QgsSymbolV2::OutputUnit mOffsetUnit;
107+
108+
//data defined properties
109+
QgsExpression* mColorExpression;
110+
QgsExpression* mColorBorderExpression;
111+
QgsExpression* mWidthBorderExpression;
112+
113+
private:
114+
//helper functions for data defined symbology
115+
void prepareExpressions( const QgsVectorLayer* vl );
116+
void applyDataDefinedSymbology( QgsSymbolV2RenderContext& context, QBrush& brush, QPen& pen, QPen& selPen );
99117
};
100118

101119
/**Base class for polygon renderers generating texture images*/

‎src/gui/symbology-ng/qgssymbollayerv2widget.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,37 @@ void QgsSimpleFillSymbolLayerV2Widget::on_mOffsetUnitComboBox_currentIndexChange
567567
}
568568
}
569569

570+
void QgsSimpleFillSymbolLayerV2Widget::on_mDataDefinedPropertiesButton_clicked()
571+
{
572+
if ( !mLayer )
573+
{
574+
return;
575+
}
576+
577+
QMap<QString, QPair< QString, QString> > dataDefinedProperties;
578+
dataDefinedProperties.insert( "color", qMakePair( tr( "Color" ), mLayer->dataDefinedPropertyString( "color" ) ) );
579+
dataDefinedProperties.insert( "color_border", qMakePair( tr( "Bordere color" ), mLayer->dataDefinedPropertyString( "color_border" ) ) );
580+
dataDefinedProperties.insert( "width_border", qMakePair( tr( "Border width" ), mLayer->dataDefinedPropertyString( "width_border" ) ) );
581+
582+
QgsDataDefinedSymbolDialog d( dataDefinedProperties, mVectorLayer );
583+
if ( d.exec() == QDialog::Accepted )
584+
{
585+
//empty all existing properties first
586+
mLayer->removeDataDefinedProperties();
587+
588+
QMap<QString, QString> properties = d.dataDefinedProperties();
589+
QMap<QString, QString>::const_iterator it = properties.constBegin();
590+
for ( ; it != properties.constEnd(); ++it )
591+
{
592+
if ( !it.value().isEmpty() )
593+
{
594+
mLayer->setDataDefinedProperty( it.key(), it.value() );
595+
}
596+
}
597+
emit changed();
598+
}
599+
}
600+
570601
///////////
571602

572603
QgsMarkerLineSymbolLayerV2Widget::QgsMarkerLineSymbolLayerV2Widget( const QgsVectorLayer* vl, QWidget* parent )

‎src/gui/symbology-ng/qgssymbollayerv2widget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ class GUI_EXPORT QgsSimpleFillSymbolLayerV2Widget : public QgsSymbolLayerV2Widge
141141
void offsetChanged();
142142
void on_mBorderWidthUnitComboBox_currentIndexChanged( int index );
143143
void on_mOffsetUnitComboBox_currentIndexChanged( int index );
144+
void on_mDataDefinedPropertiesButton_clicked();
144145

145146
protected:
146147
QgsSimpleFillSymbolLayerV2* mLayer;

0 commit comments

Comments
 (0)
Please sign in to comment.