Skip to content

Commit edd56e9

Browse files
committed
Fix @geometry_point_num and @geometry_point_count for marker lines
Fixes #15673 (cherry-picked from ddfe91f)
1 parent 89e6904 commit edd56e9

File tree

6 files changed

+89
-0
lines changed

6 files changed

+89
-0
lines changed

src/core/symbology-ng/qgslinesymbollayerv2.cpp

+24
Original file line numberDiff line numberDiff line change
@@ -952,6 +952,9 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineInterval( const QPolygonF& points
952952
QgsRenderContext& rc = context.renderContext();
953953
double interval = mInterval;
954954

955+
QgsExpressionContextScope* scope = new QgsExpressionContextScope();
956+
context.renderContext().expressionContext().appendScope( scope );
957+
955958
if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_INTERVAL ) )
956959
{
957960
context.setOriginalValueVariable( mInterval );
@@ -971,6 +974,7 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineInterval( const QPolygonF& points
971974
double painterUnitInterval = QgsSymbolLayerV2Utils::convertToPainterUnits( rc, interval, mIntervalUnit, mIntervalMapUnitScale );
972975
lengthLeft = painterUnitInterval - QgsSymbolLayerV2Utils::convertToPainterUnits( rc, offsetAlongLine, mIntervalUnit, mIntervalMapUnitScale );
973976

977+
int pointNum = 0;
974978
for ( int i = 1; i < points.count(); ++i )
975979
{
976980
const QPointF& pt = points[i];
@@ -1001,12 +1005,15 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineInterval( const QPolygonF& points
10011005
// "c" is 1 for regular point or in interval (0,1] for begin of line segment
10021006
lastPt += c * diff;
10031007
lengthLeft -= painterUnitInterval;
1008+
scope->setVariable( QgsExpressionContext::EXPR_GEOMETRY_POINT_NUM, ++pointNum );
10041009
mMarker->renderPoint( lastPt, context.feature(), rc, -1, context.selected() );
10051010
c = 1; // reset c (if wasn't 1 already)
10061011
}
10071012

10081013
lastPt = pt;
10091014
}
1015+
1016+
delete context.renderContext().expressionContext().popScope();
10101017
}
10111018

10121019
static double _averageAngle( QPointF prevPt, QPointF pt, QPointF nextPt )
@@ -1030,6 +1037,10 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
10301037
int i, maxCount;
10311038
bool isRing = false;
10321039

1040+
QgsExpressionContextScope* scope = new QgsExpressionContextScope();
1041+
context.renderContext().expressionContext().appendScope( scope );
1042+
scope->setVariable( QgsExpressionContext::EXPR_GEOMETRY_POINT_COUNT, points.size() );
1043+
10331044
double offsetAlongLine = mOffsetAlongLine;
10341045
if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OFFSET_ALONG_LINE ) )
10351046
{
@@ -1052,8 +1063,11 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
10521063
QgsPointV2 vPoint;
10531064
double x, y, z;
10541065
QPointF mapPoint;
1066+
int pointNum = 0;
10551067
while ( context.renderContext().geometry()->nextVertex( vId, vPoint ) )
10561068
{
1069+
scope->setVariable( QgsExpressionContext::EXPR_GEOMETRY_POINT_NUM, ++pointNum );
1070+
10571071
if (( placement == Vertex && vId.type == QgsVertexId::SegmentVertex )
10581072
|| ( placement == CurvePoint && vId.type == QgsVertexId::CurveVertex ) )
10591073
{
@@ -1075,6 +1089,8 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
10751089
mMarker->renderPoint( mapPoint, context.feature(), rc, -1, context.selected() );
10761090
}
10771091
}
1092+
1093+
delete context.renderContext().expressionContext().popScope();
10781094
return;
10791095
}
10801096

@@ -1097,6 +1113,7 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
10971113
}
10981114
else
10991115
{
1116+
delete context.renderContext().expressionContext().popScope();
11001117
return;
11011118
}
11021119

@@ -1107,11 +1124,16 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
11071124
renderOffsetVertexAlongLine( points, i, distance, context );
11081125
// restore original rotation
11091126
mMarker->setAngle( origAngle );
1127+
1128+
delete context.renderContext().expressionContext().popScope();
11101129
return;
11111130
}
11121131

1132+
int pointNum = 0;
11131133
for ( ; i < maxCount; ++i )
11141134
{
1135+
scope->setVariable( QgsExpressionContext::EXPR_GEOMETRY_POINT_NUM, ++pointNum );
1136+
11151137
if ( isRing && placement == Vertex && i == points.count() - 1 )
11161138
{
11171139
continue; // don't draw the last marker - it has been drawn already
@@ -1128,6 +1150,8 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
11281150

11291151
// restore original rotation
11301152
mMarker->setAngle( origAngle );
1153+
1154+
delete context.renderContext().expressionContext().popScope();
11311155
}
11321156

11331157
double QgsMarkerLineSymbolLayerV2::markerAngle( const QPolygonF& points, bool isRing, int vertex )

tests/src/core/testqgsmarkerlinesymbol.cpp

+65
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@
2929
#include "qgsmaprenderer.h"
3030
#include "qgspallabeling.h"
3131
#include "qgsfontutils.h"
32+
#include "qgslinesymbollayerv2.h"
33+
#include "qgssinglesymbolrendererv2.h"
34+
#include "qgsmarkersymbollayerv2.h"
35+
#include "qgsdatadefined.h"
3236

3337
//qgis unit test includes
3438
#include <qgsrenderchecker.h>
@@ -56,6 +60,8 @@ class TestQgsMarkerLineSymbol : public QObject
5660
void cleanup() {} // will be called after every testfunction.
5761

5862
void lineOffset();
63+
void pointNumInterval();
64+
void pointNumVertex();
5965

6066
private:
6167
bool render( const QString& theFileName );
@@ -137,6 +143,65 @@ void TestQgsMarkerLineSymbol::lineOffset()
137143
// http://hub.qgis.org/issues/13811#note-1
138144
}
139145

146+
void TestQgsMarkerLineSymbol::pointNumInterval()
147+
{
148+
mMapSettings->setLayers( QStringList() << mLinesLayer->id() );
149+
150+
QgsMarkerLineSymbolLayerV2* ml = new QgsMarkerLineSymbolLayerV2();
151+
ml->setPlacement( QgsMarkerLineSymbolLayerV2::Interval );
152+
ml->setInterval( 4 );
153+
QgsLineSymbolV2* lineSymbol = new QgsLineSymbolV2();
154+
lineSymbol->changeSymbolLayer( 0, ml );
155+
QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( lineSymbol );
156+
157+
// make sub-symbol
158+
QgsStringMap props;
159+
props["color"] = "255,0,0";
160+
props["size"] = "2";
161+
props["outline_style"] = "no";
162+
QgsSimpleMarkerSymbolLayerV2* marker = static_cast< QgsSimpleMarkerSymbolLayerV2* >( QgsSimpleMarkerSymbolLayerV2::create( props ) );
163+
164+
marker->setDataDefinedProperty( "size", new QgsDataDefined( true, true, "@geometry_point_num * 2" ) );
165+
166+
QgsMarkerSymbolV2* subSymbol = new QgsMarkerSymbolV2();
167+
subSymbol->changeSymbolLayer( 0, marker );
168+
ml->setSubSymbol( subSymbol );
169+
170+
mLinesLayer->setRendererV2( r );
171+
172+
mMapSettings->setExtent( QgsRectangle( -140, -140, 140, 140 ) );
173+
QVERIFY( render( "point_num_interval" ) );
174+
}
175+
176+
void TestQgsMarkerLineSymbol::pointNumVertex()
177+
{
178+
mMapSettings->setLayers( QStringList() << mLinesLayer->id() );
179+
180+
QgsMarkerLineSymbolLayerV2* ml = new QgsMarkerLineSymbolLayerV2();
181+
ml->setPlacement( QgsMarkerLineSymbolLayerV2::Vertex );
182+
QgsLineSymbolV2* lineSymbol = new QgsLineSymbolV2();
183+
lineSymbol->changeSymbolLayer( 0, ml );
184+
QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( lineSymbol );
185+
186+
// make sub-symbol
187+
QgsStringMap props;
188+
props["color"] = "255,0,0";
189+
props["size"] = "2";
190+
props["outline_style"] = "no";
191+
QgsSimpleMarkerSymbolLayerV2* marker = static_cast< QgsSimpleMarkerSymbolLayerV2* >( QgsSimpleMarkerSymbolLayerV2::create( props ) );
192+
193+
marker->setDataDefinedProperty( "size", new QgsDataDefined( true, true, "@geometry_point_num * 2" ) );
194+
195+
QgsMarkerSymbolV2* subSymbol = new QgsMarkerSymbolV2();
196+
subSymbol->changeSymbolLayer( 0, marker );
197+
ml->setSubSymbol( subSymbol );
198+
199+
mLinesLayer->setRendererV2( r );
200+
201+
mMapSettings->setExtent( QgsRectangle( -140, -140, 140, 140 ) );
202+
QVERIFY( render( "point_num_vertex" ) );
203+
}
204+
140205
bool TestQgsMarkerLineSymbol::render( const QString& theTestType )
141206
{
142207
mReport += "<h2>" + theTestType + "</h2>\n";

0 commit comments

Comments
 (0)