Skip to content
Permalink
Browse files

Avoid repeating points when appending lines

  • Loading branch information
nyalldawson committed Jul 24, 2020
1 parent 91931fe commit e2a370fe3e33593885242d656ec1b8175d200235
@@ -741,6 +741,15 @@ May return an empty linestring if the substring is zero length.
%Docstring
Returns ``True`` if the angle formed by the line ``p1`` - ``p2`` - ``p3`` forms a "sharp" corner.

.. versionadded:: 3.16
%End

static void appendPolyline( QPolygonF &target, const QPolygonF &line );
%Docstring
Appends a polyline ``line`` to an existing ``target`` polyline.

Any duplicate points at the start ``line`` which match the end point from ``target`` will be skipped.

.. versionadded:: 3.16
%End

@@ -718,7 +718,7 @@ void QgsSimpleLineSymbolLayer::drawPathWithDashPatternTweaks( QPainter *painter,
// add first dash from current buffer
QPolygonF firstDashSubstring = QgsSymbolLayerUtils::polylineSubstring( bufferedPoints, 0, compressed.first() * scaleFactor );
if ( !firstDashSubstring.empty() )
previousSegmentBuffer << firstDashSubstring;
QgsSymbolLayerUtils::appendPolyline( previousSegmentBuffer, firstDashSubstring );

// then we skip over the first dash and gap for this segment
bufferedPoints = QgsSymbolLayerUtils::polylineSubstring( bufferedPoints, ( compressed.first() + compressed.at( 1 ) ) * scaleFactor, 0 );
@@ -4165,6 +4165,18 @@ bool QgsSymbolLayerUtils::isSharpCorner( QPointF p1, QPointF p2, QPointF p3 )
return vertexAngle < M_PI * 135.0 / 180.0 || vertexAngle > M_PI * 225.0 / 180.0;
}

void QgsSymbolLayerUtils::appendPolyline( QPolygonF &target, const QPolygonF &line )
{
target.reserve( target.size() + line.size() );
for ( const QPointF &pt : line )
{
if ( !target.empty() && target.last() == pt )
continue;

target << pt;
}
}

QgsExpression *QgsSymbolLayerUtils::fieldOrExpressionToExpression( const QString &fieldOrExpression )
{
if ( fieldOrExpression.isEmpty() )
@@ -669,6 +669,15 @@ class CORE_EXPORT QgsSymbolLayerUtils
*/
static bool isSharpCorner( QPointF p1, QPointF p2, QPointF p3 );

/**
* Appends a polyline \a line to an existing \a target polyline.
*
* Any duplicate points at the start \a line which match the end point from \a target will be skipped.
*
* \since QGIS 3.16
*/
static void appendPolyline( QPolygonF &target, const QPolygonF &line );

/**
* Returns a new valid expression instance for given field or expression string.
* If the input is not a valid expression, it is assumed that it is a field name and gets properly quoted.
@@ -160,6 +160,7 @@ def testDashCornerTweakDashRender(self):
s.symbolLayer(0).setPenStyle(Qt.DashDotDotLine)
s.symbolLayer(0).setAlignDashPattern(True)
s.symbolLayer(0).setTweakDashPatternOnCorners(True)
s.symbolLayer(0).setPenJoinStyle(Qt.RoundJoin)

g = QgsGeometry.fromWkt('LineString(0 0, 2 1, 3 1, 10 0, 10 10, 5 5)')
rendered_image = self.renderGeometry(s, g)
@@ -298,6 +298,17 @@ def testPolylineSubstring(self):
res = QgsSymbolLayerUtils.polylineSubstring(QPolygonF([QPointF(11, 2), QPointF(11, 12), QPointF(111, 12)]), 1, -90)
self.assertEqual([p for p in res], [QPointF(11, 3), QPointF(11, 12), QPointF(21, 12)])

def testAppendPolyline(self):
line = QPolygonF([QPointF(11, 2), QPointF(11, 12), QPointF(111, 12)])
line2 = QPolygonF([QPointF(111, 12), QPointF(111, 12), QPointF(111, 14), QPointF(111, 15)])
QgsSymbolLayerUtils.appendPolyline(line, line2)
self.assertEqual([p for p in line], [QPointF(11.0, 2.0), QPointF(11.0, 12.0), QPointF(111.0, 12.0), QPointF(111.0, 14.0), QPointF(111.0, 15.0)])

line = QPolygonF([QPointF(11, 2), QPointF(11, 12), QPointF(111, 12)])
line2 = QPolygonF([QPointF(111, 14), QPointF(111, 15)])
QgsSymbolLayerUtils.appendPolyline(line, line2)
self.assertEqual([p for p in line], [QPointF(11.0, 2.0), QPointF(11.0, 12.0), QPointF(111.0, 12.0), QPointF(111.0, 14.0), QPointF(111.0, 15.0)])


if __name__ == '__main__':
unittest.main()
Binary file not shown.

0 comments on commit e2a370f

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