Skip to content
Permalink
Browse files

Fix @geometry_point_num and @geometry_point_count for marker lines

Fixes #15673
  • Loading branch information
nyalldawson committed Oct 10, 2016
1 parent 748d8ac commit ddfe91f76342578934398f9cc56aa68e4e525020
@@ -933,6 +933,9 @@ void QgsMarkerLineSymbolLayer::renderPolylineInterval( const QPolygonF& points,
QgsRenderContext& rc = context.renderContext();
double interval = mInterval;

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

if ( hasDataDefinedProperty( QgsSymbolLayer::EXPR_INTERVAL ) )
{
context.setOriginalValueVariable( mInterval );
@@ -952,6 +955,7 @@ void QgsMarkerLineSymbolLayer::renderPolylineInterval( const QPolygonF& points,
double painterUnitInterval = QgsSymbolLayerUtils::convertToPainterUnits( rc, interval, mIntervalUnit, mIntervalMapUnitScale );
lengthLeft = painterUnitInterval - QgsSymbolLayerUtils::convertToPainterUnits( rc, offsetAlongLine, mIntervalUnit, mIntervalMapUnitScale );

int pointNum = 0;
for ( int i = 1; i < points.count(); ++i )
{
const QPointF& pt = points[i];
@@ -982,12 +986,15 @@ void QgsMarkerLineSymbolLayer::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 )
@@ -1011,6 +1018,10 @@ void QgsMarkerLineSymbolLayer::renderPolylineVertex( const QPolygonF& points, Qg
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( QgsSymbolLayer::EXPR_OFFSET_ALONG_LINE ) )
{
@@ -1033,8 +1044,11 @@ void QgsMarkerLineSymbolLayer::renderPolylineVertex( const QPolygonF& points, Qg
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 ) )
{
@@ -1056,6 +1070,8 @@ void QgsMarkerLineSymbolLayer::renderPolylineVertex( const QPolygonF& points, Qg
mMarker->renderPoint( mapPoint, context.feature(), rc, -1, context.selected() );
}
}

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

@@ -1078,6 +1094,7 @@ void QgsMarkerLineSymbolLayer::renderPolylineVertex( const QPolygonF& points, Qg
}
else
{
delete context.renderContext().expressionContext().popScope();
return;
}

@@ -1088,11 +1105,16 @@ void QgsMarkerLineSymbolLayer::renderPolylineVertex( const QPolygonF& points, Qg
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
@@ -1109,6 +1131,8 @@ void QgsMarkerLineSymbolLayer::renderPolylineVertex( const QPolygonF& points, Qg

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

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

double QgsMarkerLineSymbolLayer::markerAngle( const QPolygonF& points, bool isRing, int vertex )
@@ -28,6 +28,10 @@
#include "qgsapplication.h"
#include "qgspallabeling.h"
#include "qgsfontutils.h"
#include "qgslinesymbollayer.h"
#include "qgssinglesymbolrenderer.h"
#include "qgsmarkersymbollayer.h"
#include "qgsdatadefined.h"

//qgis unit test includes
#include <qgsrenderchecker.h>
@@ -55,6 +59,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 );
@@ -136,6 +142,65 @@ void TestQgsMarkerLineSymbol::lineOffset()
// http://hub.qgis.org/issues/13811#note-1
}

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

QgsMarkerLineSymbolLayer* ml = new QgsMarkerLineSymbolLayer();
ml->setPlacement( QgsMarkerLineSymbolLayer::Interval );
ml->setInterval( 4 );
QgsLineSymbol* lineSymbol = new QgsLineSymbol();
lineSymbol->changeSymbolLayer( 0, ml );
QgsSingleSymbolRenderer* r = new QgsSingleSymbolRenderer( lineSymbol );

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

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

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

mLinesLayer->setRenderer( r );

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

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

QgsMarkerLineSymbolLayer* ml = new QgsMarkerLineSymbolLayer();
ml->setPlacement( QgsMarkerLineSymbolLayer::Vertex );
QgsLineSymbol* lineSymbol = new QgsLineSymbol();
lineSymbol->changeSymbolLayer( 0, ml );
QgsSingleSymbolRenderer* r = new QgsSingleSymbolRenderer( lineSymbol );

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

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

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

mLinesLayer->setRenderer( 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.

0 comments on commit ddfe91f

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