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
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 0 deletions.
@@ -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";
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit edd56e9

Please sign in to comment.