Skip to content
Permalink
Browse files

Fix @geometry_point_num and @geometry_point_count for marker lines

Fixes #15673

(cherry-picked from ddfe91f)
  • Loading branch information
nyalldawson committed Oct 12, 2016
1 parent 89e6904 commit edd56e9534c957d52ca81701439fbbaf12834263
@@ -952,6 +952,9 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineInterval( const QPolygonF& points
QgsRenderContext& rc = context.renderContext();
double interval = mInterval;

QgsExpressionContextScope* scope = new QgsExpressionContextScope();
context.renderContext().expressionContext().appendScope( scope );

if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_INTERVAL ) )
{
context.setOriginalValueVariable( mInterval );
@@ -971,6 +974,7 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineInterval( const QPolygonF& points
double painterUnitInterval = QgsSymbolLayerV2Utils::convertToPainterUnits( rc, interval, mIntervalUnit, mIntervalMapUnitScale );
lengthLeft = painterUnitInterval - QgsSymbolLayerV2Utils::convertToPainterUnits( rc, offsetAlongLine, mIntervalUnit, mIntervalMapUnitScale );

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

lastPt = pt;
}

delete context.renderContext().expressionContext().popScope();
}

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

QgsExpressionContextScope* scope = new QgsExpressionContextScope();
context.renderContext().expressionContext().appendScope( scope );
scope->setVariable( QgsExpressionContext::EXPR_GEOMETRY_POINT_COUNT, points.size() );

double offsetAlongLine = mOffsetAlongLine;
if ( hasDataDefinedProperty( QgsSymbolLayerV2::EXPR_OFFSET_ALONG_LINE ) )
{
@@ -1052,8 +1063,11 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
QgsPointV2 vPoint;
double x, y, z;
QPointF mapPoint;
int pointNum = 0;
while ( context.renderContext().geometry()->nextVertex( vId, vPoint ) )
{
scope->setVariable( QgsExpressionContext::EXPR_GEOMETRY_POINT_NUM, ++pointNum );

if (( placement == Vertex && vId.type == QgsVertexId::SegmentVertex )
|| ( placement == CurvePoint && vId.type == QgsVertexId::CurveVertex ) )
{
@@ -1075,6 +1089,8 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
mMarker->renderPoint( mapPoint, context.feature(), rc, -1, context.selected() );
}
}

delete context.renderContext().expressionContext().popScope();
return;
}

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

@@ -1107,11 +1124,16 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,
renderOffsetVertexAlongLine( points, i, distance, context );
// restore original rotation
mMarker->setAngle( origAngle );

delete context.renderContext().expressionContext().popScope();
return;
}

int pointNum = 0;
for ( ; i < maxCount; ++i )
{
scope->setVariable( QgsExpressionContext::EXPR_GEOMETRY_POINT_NUM, ++pointNum );

if ( isRing && placement == Vertex && i == points.count() - 1 )
{
continue; // don't draw the last marker - it has been drawn already
@@ -1128,6 +1150,8 @@ void QgsMarkerLineSymbolLayerV2::renderPolylineVertex( const QPolygonF& points,

// restore original rotation
mMarker->setAngle( origAngle );

delete context.renderContext().expressionContext().popScope();
}

double QgsMarkerLineSymbolLayerV2::markerAngle( const QPolygonF& points, bool isRing, int vertex )
@@ -29,6 +29,10 @@
#include "qgsmaprenderer.h"
#include "qgspallabeling.h"
#include "qgsfontutils.h"
#include "qgslinesymbollayerv2.h"
#include "qgssinglesymbolrendererv2.h"
#include "qgsmarkersymbollayerv2.h"
#include "qgsdatadefined.h"

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

void lineOffset();
void pointNumInterval();
void pointNumVertex();

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

void TestQgsMarkerLineSymbol::pointNumInterval()
{
mMapSettings->setLayers( QStringList() << mLinesLayer->id() );

QgsMarkerLineSymbolLayerV2* ml = new QgsMarkerLineSymbolLayerV2();
ml->setPlacement( QgsMarkerLineSymbolLayerV2::Interval );
ml->setInterval( 4 );
QgsLineSymbolV2* lineSymbol = new QgsLineSymbolV2();
lineSymbol->changeSymbolLayer( 0, ml );
QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( lineSymbol );

// make sub-symbol
QgsStringMap props;
props["color"] = "255,0,0";
props["size"] = "2";
props["outline_style"] = "no";
QgsSimpleMarkerSymbolLayerV2* marker = static_cast< QgsSimpleMarkerSymbolLayerV2* >( QgsSimpleMarkerSymbolLayerV2::create( props ) );

marker->setDataDefinedProperty( "size", new QgsDataDefined( true, true, "@geometry_point_num * 2" ) );

QgsMarkerSymbolV2* subSymbol = new QgsMarkerSymbolV2();
subSymbol->changeSymbolLayer( 0, marker );
ml->setSubSymbol( subSymbol );

mLinesLayer->setRendererV2( r );

mMapSettings->setExtent( QgsRectangle( -140, -140, 140, 140 ) );
QVERIFY( render( "point_num_interval" ) );
}

void TestQgsMarkerLineSymbol::pointNumVertex()
{
mMapSettings->setLayers( QStringList() << mLinesLayer->id() );

QgsMarkerLineSymbolLayerV2* ml = new QgsMarkerLineSymbolLayerV2();
ml->setPlacement( QgsMarkerLineSymbolLayerV2::Vertex );
QgsLineSymbolV2* lineSymbol = new QgsLineSymbolV2();
lineSymbol->changeSymbolLayer( 0, ml );
QgsSingleSymbolRendererV2* r = new QgsSingleSymbolRendererV2( lineSymbol );

// make sub-symbol
QgsStringMap props;
props["color"] = "255,0,0";
props["size"] = "2";
props["outline_style"] = "no";
QgsSimpleMarkerSymbolLayerV2* marker = static_cast< QgsSimpleMarkerSymbolLayerV2* >( QgsSimpleMarkerSymbolLayerV2::create( props ) );

marker->setDataDefinedProperty( "size", new QgsDataDefined( true, true, "@geometry_point_num * 2" ) );

QgsMarkerSymbolV2* subSymbol = new QgsMarkerSymbolV2();
subSymbol->changeSymbolLayer( 0, marker );
ml->setSubSymbol( subSymbol );

mLinesLayer->setRendererV2( r );

mMapSettings->setExtent( QgsRectangle( -140, -140, 140, 140 ) );
QVERIFY( render( "point_num_vertex" ) );
}

bool TestQgsMarkerLineSymbol::render( const QString& theTestType )
{
mReport += "<h2>" + theTestType + "</h2>\n";
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit edd56e9

Please sign in to comment.
You can’t perform that action at this time.