Skip to content

Commit eb716fc

Browse files
committedMay 9, 2015
[symbology] Fall back to symbol style if data defined evaluation
fails or is null.
1 parent 4a4877d commit eb716fc

File tree

7 files changed

+328
-200
lines changed

7 files changed

+328
-200
lines changed
 

‎python/core/symbology-ng/qgssymbollayerv2.sip‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,9 @@ class QgsSymbolLayerV2
204204
* @param property property key
205205
* @param feature pointer to the feature to use during expression or field
206206
* evaluation
207-
* @returns calculated value for data defined property, or an invalid QVariant
207+
* @param defaultVal default value to return if evaluation was not successful
208+
* @param ok if specified, will be set to true if evaluation was successful
209+
* @returns calculated value for data defined property, or default value
208210
* if property does not exist or is deactived.
209211
* @see hasDataDefinedProperty
210212
* @see getDataDefinedProperty

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

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -195,26 +195,33 @@ QgsSymbolLayerV2* QgsEllipseSymbolLayerV2::create( const QgsStringMap& propertie
195195

196196
void QgsEllipseSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2RenderContext& context )
197197
{
198+
bool ok;
198199
if ( hasDataDefinedProperty( "outline_width" ) )
199200
{
200-
double width = evaluateDataDefinedProperty( "outline_width", context.feature() ).toDouble();
201+
double width = evaluateDataDefinedProperty( "outline_width", context.feature(), mOutlineWidth ).toDouble();
201202
width *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOutlineWidthUnit, mOutlineWidthMapUnitScale );
202203
mPen.setWidthF( width );
203204
}
204205
if ( hasDataDefinedProperty( "outline_style" ) )
205206
{
206-
Qt::PenStyle style = QgsSymbolLayerV2Utils::decodePenStyle( evaluateDataDefinedProperty( "outline_style", context.feature() ).toString() );
207-
mPen.setStyle( style );
207+
QString styleString = evaluateDataDefinedProperty( "outline_style", context.feature(), QVariant(), &ok ).toString();
208+
if ( ok )
209+
{
210+
Qt::PenStyle style = QgsSymbolLayerV2Utils::decodePenStyle( styleString );
211+
mPen.setStyle( style );
212+
}
208213
}
209214
if ( hasDataDefinedProperty( "fill_color" ) )
210215
{
211-
QString colorString = evaluateDataDefinedProperty( "fill_color", context.feature() ).toString();
212-
mBrush.setColor( QColor( QgsSymbolLayerV2Utils::decodeColor( colorString ) ) );
216+
QString colorString = evaluateDataDefinedProperty( "fill_color", context.feature(), QVariant(), &ok ).toString();
217+
if ( ok )
218+
mBrush.setColor( QColor( QgsSymbolLayerV2Utils::decodeColor( colorString ) ) );
213219
}
214220
if ( hasDataDefinedProperty( "outline_color" ) )
215221
{
216-
QString colorString = evaluateDataDefinedProperty( "outline_color", context.feature() ).toString();
217-
mPen.setColor( QColor( QgsSymbolLayerV2Utils::decodeColor( colorString ) ) );
222+
QString colorString = evaluateDataDefinedProperty( "outline_color", context.feature(), QVariant(), &ok ).toString();
223+
if ( ok )
224+
mPen.setColor( QColor( QgsSymbolLayerV2Utils::decodeColor( colorString ) ) );
218225
}
219226
double scaledWidth = mSymbolWidth;
220227
double scaledHeight = mSymbolHeight;
@@ -223,7 +230,7 @@ void QgsEllipseSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2Rend
223230
QString symbolName = mSymbolName;
224231
if ( hasDataDefinedProperty( "symbol_name" ) )
225232
{
226-
symbolName = evaluateDataDefinedProperty( "symbol_name", context.feature() ).toString();
233+
symbolName = evaluateDataDefinedProperty( "symbol_name", context.feature(), mSymbolName ).toString();
227234
}
228235
preparePath( symbolName, context, &scaledWidth, &scaledHeight, context.feature() );
229236
}
@@ -244,7 +251,7 @@ void QgsEllipseSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2Rend
244251
double rotation = 0.0;
245252
if ( hasDataDefinedProperty( "rotation" ) )
246253
{
247-
rotation = evaluateDataDefinedProperty( "rotation", context.feature() ).toDouble();
254+
rotation = evaluateDataDefinedProperty( "rotation", context.feature(), mAngle ).toDouble();
248255
}
249256
else if ( !qgsDoubleNear( mAngle, 0.0 ) )
250257
{
@@ -446,7 +453,7 @@ void QgsEllipseSymbolLayerV2::preparePath( const QString& symbolName, QgsSymbolV
446453

447454
if ( hasDataDefinedProperty( "width" ) ) //1. priority: data defined setting on symbol layer le
448455
{
449-
width = evaluateDataDefinedProperty( "width", f ).toDouble();
456+
width = evaluateDataDefinedProperty( "width", f, mSymbolWidth ).toDouble();
450457
}
451458
else if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level
452459
{
@@ -465,7 +472,7 @@ void QgsEllipseSymbolLayerV2::preparePath( const QString& symbolName, QgsSymbolV
465472
double height = 0;
466473
if ( hasDataDefinedProperty( "height" ) ) //1. priority: data defined setting on symbol layer level
467474
{
468-
height = evaluateDataDefinedProperty( "height", f ).toDouble();
475+
height = evaluateDataDefinedProperty( "height", f, mSymbolHeight ).toDouble();
469476
}
470477
else if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level
471478
{
@@ -549,7 +556,7 @@ bool QgsEllipseSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFa
549556

550557
if ( hasDataDefinedProperty( "width" ) ) //1. priority: data defined setting on symbol layer le
551558
{
552-
symbolWidth = evaluateDataDefinedProperty( "width", f ).toDouble();
559+
symbolWidth = evaluateDataDefinedProperty( "width", f, mSymbolWidth ).toDouble();
553560
}
554561
else if ( context->renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level
555562
{
@@ -564,7 +571,7 @@ bool QgsEllipseSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFa
564571
double symbolHeight = mSymbolHeight;
565572
if ( hasDataDefinedProperty( "height" ) ) //1. priority: data defined setting on symbol layer level
566573
{
567-
symbolHeight = evaluateDataDefinedProperty( "height", f ).toDouble();
574+
symbolHeight = evaluateDataDefinedProperty( "height", f, mSymbolHeight ).toDouble();
568575
}
569576
else if ( context->renderHints() & QgsSymbolV2::DataDefinedSizeScale ) //2. priority: is data defined size on symbol level
570577
{
@@ -580,32 +587,37 @@ bool QgsEllipseSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFa
580587

581588
if ( hasDataDefinedProperty( "outline_width" ) )
582589
{
583-
outlineWidth = evaluateDataDefinedProperty( "outline_width", f ).toDouble();
590+
outlineWidth = evaluateDataDefinedProperty( "outline_width", f, mOutlineWidth ).toDouble();
584591
}
585592
if ( mOutlineWidthUnit == QgsSymbolV2::MM )
586593
{
587594
outlineWidth *= outlineWidth;
588595
}
589596

590597
//fill color
598+
bool ok;
591599
QColor fc = mFillColor;
592600
if ( hasDataDefinedProperty( "fill_color" ) )
593601
{
594-
fc = QColor( evaluateDataDefinedProperty( "fill_color", f ).toString() );
602+
QString colorString = evaluateDataDefinedProperty( "fill_color", f, QVariant(), &ok ).toString();
603+
if ( ok )
604+
fc = QColor( colorString );
595605
}
596606

597607
//outline color
598608
QColor oc = mOutlineColor;
599609
if ( hasDataDefinedProperty( "outline_color" ) )
600610
{
601-
oc = QColor( evaluateDataDefinedProperty( "outline_color", f ).toString() );
611+
QString colorString = evaluateDataDefinedProperty( "outline_color", f, QVariant(), &ok ).toString();
612+
if ( ok )
613+
oc = QColor( colorString );
602614
}
603615

604616
//symbol name
605-
QString symbolName = mSymbolName;
617+
QString symbolName = mSymbolName;
606618
if ( hasDataDefinedProperty( "symbol_name" ) )
607619
{
608-
symbolName = evaluateDataDefinedProperty( "symbol_name", f ).toString();
620+
symbolName = evaluateDataDefinedProperty( "symbol_name", f, mSymbolName ).toString();
609621
}
610622

611623
//offset
@@ -618,7 +630,7 @@ bool QgsEllipseSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScaleFa
618630
double rotation = 0.0;
619631
if ( hasDataDefinedProperty( "rotation" ) )
620632
{
621-
rotation = evaluateDataDefinedProperty( "rotation", f ).toDouble();
633+
rotation = evaluateDataDefinedProperty( "rotation", f, mAngle ).toDouble();
622634
}
623635
else if ( !qgsDoubleNear( mAngle, 0.0 ) )
624636
{

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

Lines changed: 132 additions & 90 deletions
Large diffs are not rendered by default.

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

Lines changed: 56 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -469,23 +469,26 @@ void QgsSimpleLineSymbolLayerV2::applyDataDefinedSymbology( QgsSymbolV2RenderCon
469469
bool hasStrokeWidthExpression = false;
470470
if ( hasDataDefinedProperty( "width" ) )
471471
{
472-
double scaledWidth = evaluateDataDefinedProperty( "width", context.feature() ).toDouble()
472+
double scaledWidth = evaluateDataDefinedProperty( "width", context.feature(), mWidth ).toDouble()
473473
* QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mWidthUnit, mWidthMapUnitScale );
474474
pen.setWidthF( scaledWidth );
475475
selPen.setWidthF( scaledWidth );
476476
hasStrokeWidthExpression = true;
477477
}
478478

479479
//color
480+
bool ok;
480481
if ( hasDataDefinedProperty( "color" ) )
481482
{
482-
pen.setColor( QgsSymbolLayerV2Utils::decodeColor( evaluateDataDefinedProperty( "color", context.feature() ).toString() ) );
483+
QString colorString = evaluateDataDefinedProperty( "color", context.feature(), QVariant(), &ok ).toString();
484+
if ( ok )
485+
pen.setColor( QgsSymbolLayerV2Utils::decodeColor( colorString ) );
483486
}
484487

485488
//offset
486489
if ( hasDataDefinedProperty( "offset" ) )
487490
{
488-
offset = evaluateDataDefinedProperty( "offset", context.feature() ).toDouble();
491+
offset = evaluateDataDefinedProperty( "offset", context.feature(), offset ).toDouble();
489492
}
490493

491494
//dash dot vector
@@ -510,34 +513,40 @@ void QgsSimpleLineSymbolLayerV2::applyDataDefinedSymbology( QgsSymbolV2RenderCon
510513
}
511514

512515
QVector<qreal> dashVector;
513-
QStringList dashList = evaluateDataDefinedProperty( "customdash", context.feature() ).toString().split( ";" );
514-
QStringList::const_iterator dashIt = dashList.constBegin();
515-
for ( ; dashIt != dashList.constEnd(); ++dashIt )
516+
QStringList dashList = evaluateDataDefinedProperty( "customdash", context.feature(), QVariant(), &ok ).toString().split( ";" );
517+
if ( ok )
516518
{
517-
dashVector.push_back( dashIt->toDouble() * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mCustomDashPatternUnit, mCustomDashPatternMapUnitScale ) / dashWidthDiv );
519+
QStringList::const_iterator dashIt = dashList.constBegin();
520+
for ( ; dashIt != dashList.constEnd(); ++dashIt )
521+
{
522+
dashVector.push_back( dashIt->toDouble() * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mCustomDashPatternUnit, mCustomDashPatternMapUnitScale ) / dashWidthDiv );
523+
}
524+
pen.setDashPattern( dashVector );
518525
}
519-
pen.setDashPattern( dashVector );
520526
}
521527

522528
//line style
523529
if ( hasDataDefinedProperty( "line_style" ) )
524530
{
525-
QString lineStyleString = evaluateDataDefinedProperty( "line_style", context.feature() ).toString();
526-
pen.setStyle( QgsSymbolLayerV2Utils::decodePenStyle( lineStyleString ) );
531+
QString lineStyleString = evaluateDataDefinedProperty( "line_style", context.feature(), QVariant(), &ok ).toString();
532+
if ( ok )
533+
pen.setStyle( QgsSymbolLayerV2Utils::decodePenStyle( lineStyleString ) );
527534
}
528535

529536
//join style
530537
if ( hasDataDefinedProperty( "joinstyle" ) )
531538
{
532-
QString joinStyleString = evaluateDataDefinedProperty( "joinstyle", context.feature() ).toString();
533-
pen.setJoinStyle( QgsSymbolLayerV2Utils::decodePenJoinStyle( joinStyleString ) );
539+
QString joinStyleString = evaluateDataDefinedProperty( "joinstyle", context.feature(), QVariant(), &ok ).toString();
540+
if ( ok )
541+
pen.setJoinStyle( QgsSymbolLayerV2Utils::decodePenJoinStyle( joinStyleString ) );
534542
}
535543

536544
//cap style
537545
if ( hasDataDefinedProperty( "capstyle" ) )
538546
{
539-
QString capStyleString = evaluateDataDefinedProperty( "capstyle", context.feature() ).toString();
540-
pen.setCapStyle( QgsSymbolLayerV2Utils::decodePenCapStyle( capStyleString ) );
547+
QString capStyleString = evaluateDataDefinedProperty( "capstyle", context.feature(), QVariant(), &ok ).toString();
548+
if ( ok )
549+
pen.setCapStyle( QgsSymbolLayerV2Utils::decodePenCapStyle( capStyleString ) );
541550
}
542551
}
543552

@@ -571,7 +580,7 @@ double QgsSimpleLineSymbolLayerV2::dxfWidth( const QgsDxfExport& e, const QgsSym
571580

572581
if ( hasDataDefinedProperty( "width" ) )
573582
{
574-
width = evaluateDataDefinedProperty( "width", context.feature() ).toDouble() * e.mapUnitScaleFactor( e.symbologyScaleDenominator(), widthUnit(), e.mapUnits() );
583+
width = evaluateDataDefinedProperty( "width", context.feature(), mWidth ).toDouble() * e.mapUnitScaleFactor( e.symbologyScaleDenominator(), widthUnit(), e.mapUnits() );
575584
}
576585
else if ( context.renderHints() & QgsSymbolV2::DataDefinedSizeScale )
577586
{
@@ -585,7 +594,10 @@ QColor QgsSimpleLineSymbolLayerV2::dxfColor( const QgsSymbolV2RenderContext& con
585594
{
586595
if ( hasDataDefinedProperty( "color" ) )
587596
{
588-
return ( QgsSymbolLayerV2Utils::decodeColor( evaluateDataDefinedProperty( "color", context.feature() ).toString() ) );
597+
bool ok;
598+
QString colorString = evaluateDataDefinedProperty( "color", context.feature(), QVariant(), &ok ).toString();
599+
if ( ok )
600+
return ( QgsSymbolLayerV2Utils::decodeColor( colorString ) );
589601
}
590602
return mColor;
591603
}
@@ -597,7 +609,7 @@ double QgsSimpleLineSymbolLayerV2::dxfOffset( const QgsDxfExport& e, const QgsSy
597609

598610
if ( hasDataDefinedProperty( "offset" ) )
599611
{
600-
offset = evaluateDataDefinedProperty( "offset", context.feature() ).toDouble();
612+
offset = evaluateDataDefinedProperty( "offset", context.feature(), mOffset ).toDouble();
601613
}
602614
return offset;
603615
}
@@ -788,33 +800,37 @@ void QgsMarkerLineSymbolLayerV2::renderPolyline( const QPolygonF& points, QgsSym
788800

789801
if ( hasDataDefinedProperty( "offset" ) )
790802
{
791-
offset = evaluateDataDefinedProperty( "offset", context.feature() ).toDouble();
803+
offset = evaluateDataDefinedProperty( "offset", context.feature(), mOffset ).toDouble();
792804
}
793805

794806
Placement placement = mPlacement;
795807

808+
bool ok;
796809
if ( hasDataDefinedProperty( "placement" ) )
797810
{
798-
QString placementString = evaluateDataDefinedProperty( "placement", context.feature() ).toString();
799-
if ( placementString.compare( "vertex", Qt::CaseInsensitive ) == 0 )
800-
{
801-
placement = Vertex;
802-
}
803-
else if ( placementString.compare( "lastvertex", Qt::CaseInsensitive ) == 0 )
804-
{
805-
placement = LastVertex;
806-
}
807-
else if ( placementString.compare( "firstvertex", Qt::CaseInsensitive ) == 0 )
808-
{
809-
placement = FirstVertex;
810-
}
811-
else if ( placementString.compare( "centerpoint", Qt::CaseInsensitive ) == 0 )
812-
{
813-
placement = CentralPoint;
814-
}
815-
else
811+
QString placementString = evaluateDataDefinedProperty( "placement", context.feature(), QVariant(), &ok ).toString();
812+
if ( ok )
816813
{
817-
placement = Interval;
814+
if ( placementString.compare( "vertex", Qt::CaseInsensitive ) == 0 )
815+
{
816+
placement = Vertex;
817+
}
818+
else if ( placementString.compare( "lastvertex", Qt::CaseInsensitive ) == 0 )
819+
{
820+
placement = LastVertex;
821+
}
822+
else if ( placementString.compare( "firstvertex", Qt::CaseInsensitive ) == 0 )
823+
{
824+
placement = FirstVertex;
825+
}
826+
else if ( placementString.compare( "centerpoint", Qt::CaseInsensitive ) == 0 )
827+
{
828+
placement = CentralPoint;
829+
}
830+
else
831+
{
832+
placement = Interval;
833+
}
818834
}
819835
}
820836

@@ -872,7 +888,7 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineInterval( const QPolygonF& points
872888

873889
if ( hasDataDefinedProperty( "interval" ) )
874890
{
875-
interval = evaluateDataDefinedProperty( "interval", context.feature() ).toDouble();
891+
interval = evaluateDataDefinedProperty( "interval", context.feature(), mInterval ).toDouble();
876892
}
877893
if ( interval <= 0 )
878894
{
@@ -881,7 +897,7 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineInterval( const QPolygonF& points
881897
double offsetAlongLine = mOffsetAlongLine;
882898
if ( hasDataDefinedProperty( "offset_along_line" ) )
883899
{
884-
offsetAlongLine = evaluateDataDefinedProperty( "offset_along_line", context.feature() ).toDouble();
900+
offsetAlongLine = evaluateDataDefinedProperty( "offset_along_line", context.feature(), mOffsetAlongLine ).toDouble();
885901
}
886902

887903
double painterUnitInterval = interval * QgsSymbolLayerV2Utils::lineWidthScaleFactor( rc, mIntervalUnit, mIntervalMapUnitScale );
@@ -959,7 +975,7 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
959975
double offsetAlongLine = mOffsetAlongLine;
960976
if ( hasDataDefinedProperty( "offset_along_line" ) )
961977
{
962-
offsetAlongLine = evaluateDataDefinedProperty( "offset_along_line", context.feature() ).toDouble();
978+
offsetAlongLine = evaluateDataDefinedProperty( "offset_along_line", context.feature(), mOffsetAlongLine ).toDouble();
963979
}
964980
if ( offsetAlongLine != 0 )
965981
{

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

Lines changed: 76 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -472,16 +472,16 @@ void QgsSimpleMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV
472472
bool hasDataDefinedSize = context.renderHints() & QgsSymbolV2::DataDefinedSizeScale || hasDataDefinedProperty( EXPR_SIZE );
473473

474474
double scaledSize = mSize;
475+
bool ok;
475476
if ( hasDataDefinedSize )
476477
{
477478
if ( hasDataDefinedProperty( EXPR_SIZE ) )
478479
{
479-
scaledSize = evaluateDataDefinedProperty( EXPR_SIZE, context.feature() ).toDouble();
480-
}
481-
482-
if ( mScaleMethod == QgsSymbolV2::ScaleArea )
483-
{
484-
scaledSize = sqrt( scaledSize );
480+
scaledSize = evaluateDataDefinedProperty( EXPR_SIZE, context.feature(), mSize, &ok ).toDouble();
481+
if ( ok && mScaleMethod == QgsSymbolV2::ScaleArea )
482+
{
483+
scaledSize = sqrt( scaledSize );
484+
}
485485
}
486486
}
487487

@@ -493,12 +493,14 @@ void QgsSimpleMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV
493493

494494
//angle
495495
double angle = mAngle;
496+
bool usingDataDefinedRotation = false;
496497
if ( hasDataDefinedProperty( "angle" ) )
497498
{
498-
angle = evaluateDataDefinedProperty( "angle", context.feature() ).toDouble();
499+
angle = evaluateDataDefinedProperty( "angle", context.feature(), mAngle, &ok ).toDouble();
500+
usingDataDefinedRotation = ok;
499501
}
500502

501-
bool hasDataDefinedRotation = context.renderHints() & QgsSymbolV2::DataDefinedRotation || hasDataDefinedProperty( "angle" );
503+
bool hasDataDefinedRotation = context.renderHints() & QgsSymbolV2::DataDefinedRotation || usingDataDefinedRotation;
502504
if ( hasDataDefinedRotation )
503505
{
504506
// For non-point markers, "dataDefinedRotation" means following the
@@ -525,12 +527,15 @@ void QgsSimpleMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV
525527
bool createdNewPath = false;
526528
if ( hasDataDefinedProperty( "name" ) )
527529
{
528-
QString name = evaluateDataDefinedProperty( "name", context.feature() ).toString();
529-
if ( !prepareShape( name ) ) // drawing as a polygon
530+
QString name = evaluateDataDefinedProperty( "name", context.feature(), QVariant(), &ok ).toString();
531+
if ( ok )
530532
{
531-
preparePath( name ); // drawing as a painter path
533+
if ( !prepareShape( name ) ) // drawing as a polygon
534+
{
535+
preparePath( name ); // drawing as a painter path
536+
}
537+
createdNewPath = true;
532538
}
533-
createdNewPath = true;
534539
}
535540

536541
if ( mUsingCache )
@@ -563,24 +568,36 @@ void QgsSimpleMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV
563568

564569
if ( hasDataDefinedProperty( "color" ) )
565570
{
566-
mBrush.setColor( QgsSymbolLayerV2Utils::decodeColor( evaluateDataDefinedProperty( "color", context.feature() ).toString() ) );
571+
QString colorString = evaluateDataDefinedProperty( "color", context.feature(), QVariant(), &ok ).toString();
572+
if ( ok )
573+
mBrush.setColor( QgsSymbolLayerV2Utils::decodeColor( colorString ) );
567574
}
568575
if ( hasDataDefinedProperty( "color_border" ) )
569576
{
570-
mPen.setColor( QgsSymbolLayerV2Utils::decodeColor( evaluateDataDefinedProperty( "color_border", context.feature() ).toString() ) );
571-
mSelPen.setColor( QgsSymbolLayerV2Utils::decodeColor( evaluateDataDefinedProperty( "color_border", context.feature() ).toString() ) );
577+
QString colorString = evaluateDataDefinedProperty( "color_border", context.feature(), QVariant(), &ok ).toString();
578+
if ( ok )
579+
{
580+
mPen.setColor( QgsSymbolLayerV2Utils::decodeColor( colorString ) );
581+
mSelPen.setColor( QgsSymbolLayerV2Utils::decodeColor( colorString ) );
582+
}
572583
}
573584
if ( hasDataDefinedProperty( "outline_width" ) )
574585
{
575-
double outlineWidth = evaluateDataDefinedProperty( "outline_width", context.feature() ).toDouble();
576-
mPen.setWidthF( outlineWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOutlineWidthUnit, mOutlineWidthMapUnitScale ) );
577-
mSelPen.setWidthF( outlineWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOutlineWidthUnit, mOutlineWidthMapUnitScale ) );
586+
double outlineWidth = evaluateDataDefinedProperty( "outline_width", context.feature(), QVariant(), &ok ).toDouble();
587+
if ( ok )
588+
{
589+
mPen.setWidthF( outlineWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOutlineWidthUnit, mOutlineWidthMapUnitScale ) );
590+
mSelPen.setWidthF( outlineWidth * QgsSymbolLayerV2Utils::lineWidthScaleFactor( context.renderContext(), mOutlineWidthUnit, mOutlineWidthMapUnitScale ) );
591+
}
578592
}
579593
if ( hasDataDefinedProperty( "outline_style" ) )
580594
{
581-
QString outlineStyle = evaluateDataDefinedProperty( "outline_style", context.feature() ).toString();
582-
mPen.setStyle( QgsSymbolLayerV2Utils::decodePenStyle( outlineStyle ) );
583-
mSelPen.setStyle( QgsSymbolLayerV2Utils::decodePenStyle( outlineStyle ) );
595+
QString outlineStyle = evaluateDataDefinedProperty( "outline_style", context.feature(), QVariant(), &ok ).toString();
596+
if ( ok )
597+
{
598+
mPen.setStyle( QgsSymbolLayerV2Utils::decodePenStyle( outlineStyle ) );
599+
mSelPen.setStyle( QgsSymbolLayerV2Utils::decodePenStyle( outlineStyle ) );
600+
}
584601
}
585602

586603
p->setBrush( context.selected() ? mSelBrush : mBrush );
@@ -790,20 +807,24 @@ bool QgsSimpleMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitSc
790807
}
791808

792809
//data defined size
810+
bool ok = true;
793811
if ( hasDataDefinedSize )
794812
{
795813
if ( hasDataDefinedProperty( "size" ) )
796814
{
797-
size = evaluateDataDefinedProperty( "size", f ).toDouble();
815+
size = evaluateDataDefinedProperty( "size", f, mSize, &ok ).toDouble();
798816
}
799817

800-
switch ( mScaleMethod )
818+
if ( ok )
801819
{
802-
case QgsSymbolV2::ScaleArea:
803-
size = sqrt( size );
804-
break;
805-
case QgsSymbolV2::ScaleDiameter:
806-
break;
820+
switch ( mScaleMethod )
821+
{
822+
case QgsSymbolV2::ScaleArea:
823+
size = sqrt( size );
824+
break;
825+
case QgsSymbolV2::ScaleDiameter:
826+
break;
827+
}
807828
}
808829

809830
size *= QgsSymbolLayerV2Utils::lineWidthScaleFactor( context->renderContext(), mSizeUnit, mSizeMapUnitScale );
@@ -819,7 +840,7 @@ bool QgsSimpleMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitSc
819840

820841
if ( context && hasDataDefinedProperty( "outline_width" ) )
821842
{
822-
outlineWidth = evaluateDataDefinedProperty( "outline_width", f ).toDouble();
843+
outlineWidth = evaluateDataDefinedProperty( "outline_width", f, mOutlineWidth ).toDouble();
823844
}
824845
if ( mSizeUnit == QgsSymbolV2::MM )
825846
{
@@ -831,11 +852,15 @@ bool QgsSimpleMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitSc
831852
QColor bc = mBrush.color();
832853
if ( hasDataDefinedProperty( "color" ) )
833854
{
834-
bc = QgsSymbolLayerV2Utils::decodeColor( evaluateDataDefinedProperty( "color", f ).toString() );
855+
QString colorString = evaluateDataDefinedProperty( "color", f, QVariant(), &ok ).toString();
856+
if ( ok )
857+
bc = QgsSymbolLayerV2Utils::decodeColor( colorString );
835858
}
836859
if ( hasDataDefinedProperty( "color_border" ) )
837860
{
838-
pc = QgsSymbolLayerV2Utils::decodeColor( evaluateDataDefinedProperty( "color_border", f ).toString() );
861+
QString colorString = evaluateDataDefinedProperty( "color_border", f, QVariant(), &ok ).toString();
862+
if ( ok )
863+
pc = QgsSymbolLayerV2Utils::decodeColor( colorString );
839864
}
840865

841866
//offset
@@ -851,7 +876,7 @@ bool QgsSimpleMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitSc
851876
double angle = mAngle;
852877
if ( context && hasDataDefinedProperty( "angle" ) )
853878
{
854-
angle = evaluateDataDefinedProperty( "angle", f ).toDouble();
879+
angle = evaluateDataDefinedProperty( "angle", f, mAngle ).toDouble();
855880
}
856881

857882
angle = -angle; //rotation in Qt is counterclockwise
@@ -1212,12 +1237,13 @@ void QgsSvgMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2Re
12121237

12131238
bool hasDataDefinedSize = context.renderHints() & QgsSymbolV2::DataDefinedSizeScale || hasDataDefinedProperty( "size" );
12141239

1240+
bool ok = true;
12151241
if ( hasDataDefinedProperty( "size" ) )
12161242
{
1217-
scaledSize = evaluateDataDefinedProperty( "size", context.feature() ).toDouble();
1243+
scaledSize = evaluateDataDefinedProperty( "size", context.feature(), mSize, &ok ).toDouble();
12181244
}
12191245

1220-
if ( hasDataDefinedSize )
1246+
if ( hasDataDefinedSize && ok )
12211247
{
12221248
switch ( mScaleMethod )
12231249
{
@@ -1248,7 +1274,7 @@ void QgsSvgMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2Re
12481274
double angle = mAngle;
12491275
if ( hasDataDefinedProperty( "angle" ) )
12501276
{
1251-
angle = evaluateDataDefinedProperty( "angle", context.feature() ).toDouble();
1277+
angle = evaluateDataDefinedProperty( "angle", context.feature(), mAngle ).toDouble();
12521278
}
12531279

12541280
bool hasDataDefinedRotation = context.renderHints() & QgsSymbolV2::DataDefinedRotation || hasDataDefinedProperty( "angle" );
@@ -1282,25 +1308,29 @@ void QgsSvgMarkerSymbolLayerV2::renderPoint( const QPointF& point, QgsSymbolV2Re
12821308
QString path = mPath;
12831309
if ( hasDataDefinedProperty( "name" ) )
12841310
{
1285-
path = evaluateDataDefinedProperty( "name", context.feature() ).toString();
1311+
path = evaluateDataDefinedProperty( "name", context.feature(), mPath ).toString();
12861312
}
12871313

12881314
double outlineWidth = mOutlineWidth;
12891315
if ( hasDataDefinedProperty( "outline_width" ) )
12901316
{
1291-
outlineWidth = evaluateDataDefinedProperty( "outline_width", context.feature() ).toDouble();
1317+
outlineWidth = evaluateDataDefinedProperty( "outline_width", context.feature(), mOutlineWidth ).toDouble();
12921318
}
12931319

12941320
QColor fillColor = mFillColor;
12951321
if ( hasDataDefinedProperty( "fill" ) )
12961322
{
1297-
fillColor = QgsSymbolLayerV2Utils::decodeColor( evaluateDataDefinedProperty( "fill", context.feature() ).toString() );
1323+
QString colorString = evaluateDataDefinedProperty( "fill", context.feature(), QVariant(), &ok ).toString();
1324+
if ( ok )
1325+
fillColor = QgsSymbolLayerV2Utils::decodeColor( colorString );
12981326
}
12991327

13001328
QColor outlineColor = mOutlineColor;
13011329
if ( hasDataDefinedProperty( "outline" ) )
13021330
{
1303-
outlineColor = QgsSymbolLayerV2Utils::decodeColor( evaluateDataDefinedProperty( "outline", context.feature() ).toString() );
1331+
QString colorString = evaluateDataDefinedProperty( "outline", context.feature(), QVariant(), &ok ).toString();
1332+
if ( ok )
1333+
outlineColor = QgsSymbolLayerV2Utils::decodeColor( colorString );
13041334
}
13051335

13061336
bool fitsInCache = true;
@@ -1529,12 +1559,13 @@ bool QgsSvgMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScale
15291559

15301560
bool hasDataDefinedSize = context->renderHints() & QgsSymbolV2::DataDefinedSizeScale || hasDataDefinedProperty( "size" );
15311561

1562+
bool ok = true;
15321563
if ( hasDataDefinedProperty( "size" ) )
15331564
{
1534-
size = evaluateDataDefinedProperty( "size", f ).toDouble();
1565+
size = evaluateDataDefinedProperty( "size", f, mSize, &ok ).toDouble();
15351566
}
15361567

1537-
if ( hasDataDefinedSize )
1568+
if ( hasDataDefinedSize && ok )
15381569
{
15391570
switch ( mScaleMethod )
15401571
{
@@ -1558,8 +1589,9 @@ bool QgsSvgMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScale
15581589

15591590
if ( hasDataDefinedProperty( "offset" ) )
15601591
{
1561-
QString offsetString = evaluateDataDefinedProperty( "offset", f ).toString();
1562-
offset = QgsSymbolLayerV2Utils::decodePoint( offsetString );
1592+
QString offsetString = evaluateDataDefinedProperty( "offset", f, QVariant(), &ok ).toString();
1593+
if ( ok )
1594+
offset = QgsSymbolLayerV2Utils::decodePoint( offsetString );
15631595
}
15641596
double offsetX = offset.x();
15651597
double offsetY = offset.y();
@@ -1574,7 +1606,7 @@ bool QgsSvgMarkerSymbolLayerV2::writeDxf( QgsDxfExport& e, double mmMapUnitScale
15741606
double angle = mAngle;
15751607
if ( hasDataDefinedProperty( "angle" ) )
15761608
{
1577-
angle = evaluateDataDefinedProperty( "angle", f ).toDouble();
1609+
angle = evaluateDataDefinedProperty( "angle", f, mAngle ).toDouble();
15781610
}
15791611
//angle = -angle; //rotation in Qt is counterclockwise
15801612
if ( angle )

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

Lines changed: 26 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,23 +110,45 @@ bool QgsSymbolLayerV2::hasDataDefinedProperty( const QString& property ) const
110110
return dd && dd->isActive();
111111
}
112112

113-
QVariant QgsSymbolLayerV2::evaluateDataDefinedProperty( const QString &property, const QgsFeature* feature ) const
113+
QVariant QgsSymbolLayerV2::evaluateDataDefinedProperty( const QString &property, const QgsFeature* feature, const QVariant& defaultVal, bool *ok ) const
114114
{
115+
if ( ok )
116+
*ok = false;
117+
115118
QgsDataDefined* dd = getDataDefinedProperty( property );
116119
if ( !dd || !dd->isActive() )
117-
return QVariant();
120+
return defaultVal;
118121

119122
if ( dd->useExpression() )
120123
{
121-
return dd->expression() ? dd->expression()->evaluate( feature ) : QVariant();
124+
if ( dd->expression() )
125+
{
126+
QVariant result = dd->expression()->evaluate( feature );
127+
if ( result.isValid() )
128+
{
129+
if ( ok )
130+
*ok = true;
131+
return result;
132+
}
133+
else
134+
return defaultVal;
135+
}
136+
else
137+
{
138+
return defaultVal;
139+
}
122140
}
123141
else if ( feature && !dd->field().isEmpty() && !mFields.isEmpty() )
124142
{
125143
int attributeIndex = mFields.fieldNameIndex( dd->field() );
126144
if ( attributeIndex >= 0 )
145+
{
146+
if ( ok )
147+
*ok = true;
127148
return feature->attribute( attributeIndex );
149+
}
128150
}
129-
return QVariant();
151+
return defaultVal;
130152
}
131153

132154
bool QgsSymbolLayerV2::writeDxf( QgsDxfExport& e,

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,13 +191,15 @@ class CORE_EXPORT QgsSymbolLayerV2
191191
* @param property property key
192192
* @param feature pointer to the feature to use during expression or field
193193
* evaluation
194-
* @returns calculated value for data defined property, or an invalid QVariant
194+
* @param defaultVal default value to return if evaluation was not successful
195+
* @param ok if specified, will be set to true if evaluation was successful
196+
* @returns calculated value for data defined property, or default value
195197
* if property does not exist or is deactived.
196198
* @see hasDataDefinedProperty
197199
* @see getDataDefinedProperty
198200
* @note added in QGIS 2.9
199201
*/
200-
virtual QVariant evaluateDataDefinedProperty( const QString& property, const QgsFeature* feature ) const;
202+
virtual QVariant evaluateDataDefinedProperty( const QString& property, const QgsFeature* feature, const QVariant& defaultVal = QVariant(), bool *ok = 0 ) const;
201203

202204
virtual bool writeDxf( QgsDxfExport& e,
203205
double mmMapUnitScaleFactor,

1 commit comments

Comments
 (1)

nirvn commented on May 9, 2015

@nirvn
Contributor

Ahhhhhh, bye bye black rectangle legend items!

Please sign in to comment.