@@ -612,7 +612,7 @@ class MyLine
612
612
};
613
613
614
614
615
- QgsMarkerLineSymbolLayerV2::QgsMarkerLineSymbolLayerV2 ( bool rotateMarker, double interval )
615
+ QgsMarkerLineSymbolLayerV2::QgsMarkerLineSymbolLayerV2 ( bool rotateMarker, double interval ): mIntervalExpression( 0 ), mOffsetExpression( 0 ), mPlacementExpression( 0 )
616
616
{
617
617
mRotateMarker = rotateMarker;
618
618
mInterval = interval;
@@ -630,6 +630,89 @@ QgsMarkerLineSymbolLayerV2::~QgsMarkerLineSymbolLayerV2()
630
630
delete mMarker ;
631
631
}
632
632
633
+ const QgsExpression* QgsMarkerLineSymbolLayerV2::dataDefinedProperty ( const QString& property ) const
634
+ {
635
+ if ( property == " interval" )
636
+ {
637
+ return mIntervalExpression ;
638
+ }
639
+ else if ( property == " offset" )
640
+ {
641
+ return mOffsetExpression ;
642
+ }
643
+ else if ( property == " placement" )
644
+ {
645
+ return mPlacementExpression ;
646
+ }
647
+ return 0 ;
648
+ }
649
+
650
+ QString QgsMarkerLineSymbolLayerV2::dataDefinedPropertyString ( const QString& property ) const
651
+ {
652
+ const QgsExpression* ex = dataDefinedProperty ( property );
653
+ return ex ? ex->dump () : QString ();
654
+ }
655
+
656
+ void QgsMarkerLineSymbolLayerV2::setDataDefinedProperty ( const QString& property, const QString& expressionString )
657
+ {
658
+ if ( property == " interval" )
659
+ {
660
+ delete mIntervalExpression ; mIntervalExpression = new QgsExpression ( expressionString );
661
+ }
662
+ else if ( property == " offset" )
663
+ {
664
+ delete mOffsetExpression ; mOffsetExpression = new QgsExpression ( expressionString );
665
+ }
666
+ else if ( property == " placement" )
667
+ {
668
+ delete mPlacementExpression ; mPlacementExpression = new QgsExpression ( expressionString );
669
+ }
670
+ }
671
+
672
+ void QgsMarkerLineSymbolLayerV2::removeDataDefinedProperty ( const QString& property )
673
+ {
674
+ if ( property == " interval" )
675
+ {
676
+ delete mIntervalExpression ; mIntervalExpression = 0 ;
677
+ }
678
+ else if ( property == " offset" )
679
+ {
680
+ delete mOffsetExpression ; mOffsetExpression = 0 ;
681
+ }
682
+ else if ( property == " placement" )
683
+ {
684
+ delete mPlacementExpression ; mPlacementExpression = 0 ;
685
+ }
686
+ }
687
+
688
+ void QgsMarkerLineSymbolLayerV2::removeDataDefinedProperties ()
689
+ {
690
+ delete mIntervalExpression ; mIntervalExpression = 0 ;
691
+ delete mOffsetExpression ; mOffsetExpression = 0 ;
692
+ delete mPlacementExpression ; mPlacementExpression = 0 ;
693
+ }
694
+
695
+ QSet<QString> QgsMarkerLineSymbolLayerV2::usedAttributes () const
696
+ {
697
+ QSet<QString> attributes;
698
+
699
+ // add data defined attributes
700
+ QStringList columns;
701
+ if ( mIntervalExpression )
702
+ columns.append ( mIntervalExpression ->referencedColumns () );
703
+ if ( mOffsetExpression )
704
+ columns.append ( mOffsetExpression ->referencedColumns () );
705
+ if ( mPlacementExpression )
706
+ columns.append ( mPlacementExpression ->referencedColumns () );
707
+
708
+ QStringList::const_iterator it = columns.constBegin ();
709
+ for ( ; it != columns.constEnd (); ++it )
710
+ {
711
+ attributes.insert ( *it );
712
+ }
713
+ return attributes;
714
+ }
715
+
633
716
QgsSymbolLayerV2* QgsMarkerLineSymbolLayerV2::create ( const QgsStringMap& props )
634
717
{
635
718
bool rotate = DEFAULT_MARKERLINE_ROTATE;
@@ -667,6 +750,21 @@ QgsSymbolLayerV2* QgsMarkerLineSymbolLayerV2::create( const QgsStringMap& props
667
750
else
668
751
x->setPlacement ( Interval );
669
752
}
753
+
754
+ // data defined properties
755
+ if ( props.contains ( " interval_expression" ) )
756
+ {
757
+ x->setDataDefinedProperty ( " interval" , props[" interval_expression" ] );
758
+ }
759
+ if ( props.contains ( " offset_expression" ) )
760
+ {
761
+ x->setDataDefinedProperty ( " offset" , props[" offset_expression" ] );
762
+ }
763
+ if ( props.contains ( " placement_expression" ) )
764
+ {
765
+ x->setDataDefinedProperty ( " placement" , props[" placement_expression" ] );
766
+ }
767
+
670
768
return x;
671
769
}
672
770
@@ -694,6 +792,9 @@ void QgsMarkerLineSymbolLayerV2::startRender( QgsSymbolV2RenderContext& context
694
792
mMarker ->setRenderHints ( hints );
695
793
696
794
mMarker ->startRender ( context.renderContext () );
795
+
796
+ // prepare expressions for data defined properties
797
+ prepareExpressions ( context.layer () );
697
798
}
698
799
699
800
void QgsMarkerLineSymbolLayerV2::stopRender ( QgsSymbolV2RenderContext& context )
@@ -703,24 +804,56 @@ void QgsMarkerLineSymbolLayerV2::stopRender( QgsSymbolV2RenderContext& context )
703
804
704
805
void QgsMarkerLineSymbolLayerV2::renderPolyline ( const QPolygonF& points, QgsSymbolV2RenderContext& context )
705
806
{
706
- if ( mOffset == 0 )
807
+ double offset = mOffset ;
808
+ if ( mOffsetExpression )
809
+ {
810
+ offset = mOffsetExpression ->evaluate ( const_cast <QgsFeature*>( context.feature () ) ).toDouble ();
811
+ }
812
+
813
+ Placement placement = mPlacement ;
814
+ if ( mPlacementExpression )
815
+ {
816
+ QString placementString = mPlacementExpression ->evaluate ( const_cast <QgsFeature*>( context.feature () ) ).toString ();
817
+ if ( placementString.compare ( " vertex" , Qt::CaseInsensitive ) == 0 )
818
+ {
819
+ placement = Vertex;
820
+ }
821
+ else if ( placementString.compare ( " lastvertex" , Qt::CaseInsensitive ) == 0 )
822
+ {
823
+ placement = LastVertex;
824
+ }
825
+ else if ( placementString.compare ( " firstvertex" , Qt::CaseInsensitive ) == 0 )
826
+ {
827
+ placement = FirstVertex;
828
+ }
829
+ else if ( placementString.compare ( " centerpoint" , Qt::CaseInsensitive ) == 0 )
830
+ {
831
+ placement = CentralPoint;
832
+ }
833
+ else
834
+ {
835
+ placement = Interval;
836
+ }
837
+ }
838
+
839
+ if ( offset == 0 )
707
840
{
708
- if ( mPlacement == Interval )
841
+ if ( placement == Interval )
709
842
renderPolylineInterval ( points, context );
710
- else if ( mPlacement == CentralPoint )
843
+ else if ( placement == CentralPoint )
711
844
renderPolylineCentral ( points, context );
712
845
else
713
- renderPolylineVertex ( points, context );
846
+ renderPolylineVertex ( points, context, placement );
714
847
}
715
848
else
716
849
{
717
- QPolygonF points2 = ::offsetLine ( points, mOffset * QgsSymbolLayerV2Utils::lineWidthScaleFactor ( context.renderContext (), mOffsetUnit ) );
718
- if ( mPlacement == Interval )
850
+ QPolygonF points2 = ::offsetLine ( points, offset * QgsSymbolLayerV2Utils::lineWidthScaleFactor ( context.renderContext (), mOffsetUnit ) );
851
+ if ( placement == Interval )
719
852
renderPolylineInterval ( points2, context );
720
- else if ( mPlacement == CentralPoint )
853
+ else if ( placement == CentralPoint )
721
854
renderPolylineCentral ( points2, context );
722
855
else
723
- renderPolylineVertex ( points2, context );
856
+ renderPolylineVertex ( points2, context, placement );
724
857
}
725
858
}
726
859
@@ -735,7 +868,16 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineInterval( const QPolygonF& points
735
868
double origAngle = mMarker ->angle ();
736
869
737
870
QgsRenderContext& rc = context.renderContext ();
738
- double interval = mInterval > 0 ? mInterval : 0.1 ;
871
+ double interval = mInterval ;
872
+ if ( mIntervalExpression )
873
+ {
874
+ interval = mIntervalExpression ->evaluate ( const_cast <QgsFeature*>( context.feature () ) ).toDouble ();
875
+ }
876
+ if ( !interval > 0 )
877
+ {
878
+ interval = 0.1 ;
879
+ }
880
+
739
881
double painterUnitInterval = interval * QgsSymbolLayerV2Utils::lineWidthScaleFactor ( rc, mIntervalUnit );
740
882
741
883
for ( int i = 1 ; i < points.count (); ++i )
@@ -796,7 +938,7 @@ static double _averageAngle( const QPointF& prevPt, const QPointF& pt, const QPo
796
938
return atan2 ( unitY, unitX );
797
939
}
798
940
799
- void QgsMarkerLineSymbolLayerV2::renderPolylineVertex ( const QPolygonF& points, QgsSymbolV2RenderContext& context )
941
+ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex ( const QPolygonF& points, QgsSymbolV2RenderContext& context, Placement placement )
800
942
{
801
943
if ( points.isEmpty () )
802
944
return ;
@@ -808,12 +950,12 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
808
950
int i, maxCount;
809
951
bool isRing = false ;
810
952
811
- if ( mPlacement == FirstVertex )
953
+ if ( placement == FirstVertex )
812
954
{
813
955
i = 0 ;
814
956
maxCount = 1 ;
815
957
}
816
- else if ( mPlacement == LastVertex )
958
+ else if ( placement == LastVertex )
817
959
{
818
960
i = points.count () - 1 ;
819
961
maxCount = points.count ();
@@ -955,6 +1097,19 @@ QgsStringMap QgsMarkerLineSymbolLayerV2::properties() const
955
1097
else
956
1098
map[" placement" ] = " interval" ;
957
1099
1100
+ if ( mIntervalExpression )
1101
+ {
1102
+ map[" interval_expression" ] = mIntervalExpression ->dump ();
1103
+ }
1104
+ if ( mOffsetExpression )
1105
+ {
1106
+ map[" offset_expression" ] = mOffsetExpression ->dump ();
1107
+ }
1108
+ if ( mPlacementExpression )
1109
+ {
1110
+ map[" placement_expression" ] = mPlacementExpression ->dump ();
1111
+ }
1112
+
958
1113
return map;
959
1114
}
960
1115
@@ -985,6 +1140,21 @@ QgsSymbolLayerV2* QgsMarkerLineSymbolLayerV2::clone() const
985
1140
x->setPlacement ( mPlacement );
986
1141
x->setOffsetUnit ( mOffsetUnit );
987
1142
x->setIntervalUnit ( mIntervalUnit );
1143
+
1144
+ // data defined properties
1145
+ if ( mIntervalExpression )
1146
+ {
1147
+ x->setDataDefinedProperty ( " interval" , mIntervalExpression ->dump () );
1148
+ }
1149
+ if ( mOffsetExpression )
1150
+ {
1151
+ x->setDataDefinedProperty ( " offset" , mOffsetExpression ->dump () );
1152
+ }
1153
+ if ( mPlacementExpression )
1154
+ {
1155
+ x->setDataDefinedProperty ( " placement" , mPlacementExpression ->dump () );
1156
+ }
1157
+
988
1158
return x;
989
1159
}
990
1160
@@ -1162,6 +1332,22 @@ QgsSymbolV2::OutputUnit QgsMarkerLineSymbolLayerV2::outputUnit() const
1162
1332
return unit;
1163
1333
}
1164
1334
1335
+ void QgsMarkerLineSymbolLayerV2::prepareExpressions ( const QgsVectorLayer* vl )
1336
+ {
1337
+ if ( !vl )
1338
+ {
1339
+ return ;
1340
+ }
1341
+
1342
+ const QgsFields& fields = vl->pendingFields ();
1343
+ if ( mIntervalExpression )
1344
+ mIntervalExpression ->prepare ( fields );
1345
+ if ( mOffsetExpression )
1346
+ mOffsetExpression ->prepare ( fields );
1347
+ if ( mPlacementExpression )
1348
+ mPlacementExpression ->prepare ( fields );
1349
+ }
1350
+
1165
1351
// ///////////
1166
1352
1167
1353
QgsLineDecorationSymbolLayerV2::QgsLineDecorationSymbolLayerV2 ( QColor color, double width )
@@ -1191,7 +1377,6 @@ QgsSymbolLayerV2* QgsLineDecorationSymbolLayerV2::create( const QgsStringMap& pr
1191
1377
layer->setWidthUnit ( QgsSymbolLayerV2Utils::decodeOutputUnit ( props[" width_unit" ] ) );
1192
1378
}
1193
1379
return layer;
1194
-
1195
1380
}
1196
1381
1197
1382
QString QgsLineDecorationSymbolLayerV2::layerType () const
0 commit comments