31 #include <QDomDocument> 32 #include <QDomElement> 37 : mPenStyle( penStyle )
41 mCustomDashVector << 5 << 2;
49 mCustomDashPatternUnit = unit;
67 mCustomDashPatternMapUnitScale = scale;
87 if ( props.contains( QStringLiteral(
"line_color" ) ) )
91 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
95 else if ( props.contains( QStringLiteral(
"color" ) ) )
100 if ( props.contains( QStringLiteral(
"line_width" ) ) )
102 width = props[QStringLiteral(
"line_width" )].toDouble();
104 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
106 width = props[QStringLiteral(
"outline_width" )].toDouble();
108 else if ( props.contains( QStringLiteral(
"width" ) ) )
111 width = props[QStringLiteral(
"width" )].toDouble();
113 if ( props.contains( QStringLiteral(
"line_style" ) ) )
117 else if ( props.contains( QStringLiteral(
"outline_style" ) ) )
121 else if ( props.contains( QStringLiteral(
"penstyle" ) ) )
127 if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
131 else if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
135 else if ( props.contains( QStringLiteral(
"width_unit" ) ) )
140 if ( props.contains( QStringLiteral(
"width_map_unit_scale" ) ) )
142 if ( props.contains( QStringLiteral(
"offset" ) ) )
143 l->
setOffset( props[QStringLiteral(
"offset" )].toDouble() );
144 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
146 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
148 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
150 if ( props.contains( QStringLiteral(
"capstyle" ) ) )
153 if ( props.contains( QStringLiteral(
"use_custom_dash" ) ) )
157 if ( props.contains( QStringLiteral(
"customdash" ) ) )
161 if ( props.contains( QStringLiteral(
"customdash_unit" ) ) )
165 if ( props.contains( QStringLiteral(
"customdash_map_unit_scale" ) ) )
170 if ( props.contains( QStringLiteral(
"draw_inside_polygon" ) ) )
175 if ( props.contains( QStringLiteral(
"ring_filter" ) ) )
177 l->
setRingFilter( static_cast< RenderRingFilter>( props[QStringLiteral(
"ring_filter" )].toInt() ) );
188 return QStringLiteral(
"SimpleLine" );
195 mPen.setColor( penColor );
197 mPen.setWidthF( scaledWidth );
198 if ( mUseCustomDashPattern )
200 mPen.setStyle( Qt::CustomDashLine );
203 double dashWidthDiv =
qgsDoubleNear( scaledWidth, 0 ) ? 1.0 : scaledWidth;
206 QStringList versionSplit = QString( qVersion() ).split(
'.' );
207 if ( versionSplit.size() > 1
208 && versionSplit.at( 1 ).toInt() >= 8
209 && scaledWidth < 1.0 )
213 QVector<qreal> scaledVector;
214 QVector<qreal>::const_iterator it = mCustomDashVector.constBegin();
215 for ( ; it != mCustomDashVector.constEnd(); ++it )
220 mPen.setDashPattern( scaledVector );
224 mPen.setStyle( mPenStyle );
226 mPen.setJoinStyle( mPenJoinStyle );
227 mPen.setCapStyle( mPenCapStyle );
232 selColor.setAlphaF( context.
opacity() );
233 mSelPen.setColor( selColor );
249 if ( mDrawInsidePolygon )
257 if ( mDrawInsidePolygon )
260 QPainterPath clipPath;
261 clipPath.addPolygon( points );
266 QList<QPolygonF>::const_iterator it = rings->constBegin();
267 for ( ; it != rings->constEnd(); ++it )
269 QPolygonF ring = *it;
270 clipPath.addPolygon( ring );
275 p->setClipPath( clipPath, Qt::IntersectClip );
294 for (
const QPolygonF &ring : qgis::as_const( *rings ) )
304 if ( mDrawInsidePolygon )
321 applyDataDefinedSymbology( context, mPen, mSelPen, offset );
323 p->setPen( context.
selected() ? mSelPen : mPen );
324 p->setBrush( Qt::NoBrush );
327 if ( points.size() <= 2 &&
330 ( p->renderHints() & QPainter::Antialiasing ) )
332 p->setRenderHint( QPainter::Antialiasing,
false );
334 p->drawPolyline( points );
337 path.addPolygon( points );
340 p->setRenderHint( QPainter::Antialiasing,
true );
347 p->drawPolyline( points );
350 path.addPolygon( points );
358 for (
int part = 0; part < mline.count(); ++part )
361 p->drawPolyline( mline );
364 path.addPolygon( mline[ part ] );
375 map[QStringLiteral(
"line_width" )] = QString::number(
mWidth );
381 map[QStringLiteral(
"offset" )] = QString::number(
mOffset );
384 map[QStringLiteral(
"use_custom_dash" )] = ( mUseCustomDashPattern ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
388 map[QStringLiteral(
"draw_inside_polygon" )] = ( mDrawInsidePolygon ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
389 map[QStringLiteral(
"ring_filter" )] = QString::number( static_cast< int >(
mRingFilter ) );
416 if ( mPenStyle == Qt::NoPen )
419 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:LineSymbolizer" ) );
420 if ( !props.value( QStringLiteral(
"uom" ), QString() ).isEmpty() )
421 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ) );
422 element.appendChild( symbolizerElem );
428 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
429 symbolizerElem.appendChild( strokeElem );
431 Qt::PenStyle
penStyle = mUseCustomDashPattern ? Qt::CustomDashLine : mPenStyle;
435 &mPenJoinStyle, &mPenCapStyle, &customDashVector );
440 QDomElement perpOffsetElem = doc.createElement( QStringLiteral(
"se:PerpendicularOffset" ) );
443 symbolizerElem.appendChild( perpOffsetElem );
449 if ( mUseCustomDashPattern )
452 mPen.color(), mPenJoinStyle,
453 mPenCapStyle,
mOffset, &mCustomDashVector );
466 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
467 if ( strokeElem.isNull() )
479 &penJoinStyle, &penCapStyle,
480 &customDashVector ) )
484 QDomElement perpOffsetElem = element.firstChildElement( QStringLiteral(
"PerpendicularOffset" ) );
485 if ( !perpOffsetElem.isNull() )
488 double d = perpOffsetElem.firstChild().nodeValue().toDouble( &ok );
493 QString uom = element.attribute( QStringLiteral(
"uom" ) );
513 bool hasStrokeWidthExpression =
false;
520 pen.setWidthF( scaledWidth );
521 selPen.setWidthF( scaledWidth );
522 hasStrokeWidthExpression =
true;
543 double dashWidthDiv = mPen.widthF();
545 if ( hasStrokeWidthExpression )
547 dashWidthDiv = pen.widthF();
548 scaledWidth = pen.widthF();
552 QStringList versionSplit = QString( qVersion() ).split(
'.' );
553 if ( versionSplit.size() > 1
554 && versionSplit.at( 1 ).toInt() >= 8
555 && scaledWidth < 1.0 )
560 QVector<qreal> dashVector;
562 if ( exprVal.isValid() )
564 QStringList dashList = exprVal.toString().split(
';' );
565 QStringList::const_iterator dashIt = dashList.constBegin();
566 for ( ; dashIt != dashList.constEnd(); ++dashIt )
570 pen.setDashPattern( dashVector );
579 if ( exprVal.isValid() )
588 if ( exprVal.isValid() )
597 if ( exprVal.isValid() )
604 if ( mDrawInsidePolygon )
618 unit = mCustomDashPatternUnit;
619 return mUseCustomDashPattern ? mCustomDashVector : QVector<qreal>();
680 MyLine( QPointF p1, QPointF p2 )
682 , mIncreasing(
false )
694 mIncreasing = ( p2.y() > p1.y() );
699 mT = ( p2.y() - p1.y() ) / ( p2.x() - p1.x() );
700 mIncreasing = ( p2.x() > p1.x() );
704 double x = ( p2.x() - p1.x() );
705 double y = ( p2.y() - p1.y() );
706 mLength = std::sqrt( x * x + y * y );
712 double a = ( mVertical ? M_PI_2 : std::atan( mT ) );
720 QPointF diffForInterval(
double interval )
723 return ( mIncreasing ? QPointF( 0, interval ) : QPointF( 0, -interval ) );
725 double alpha = std::atan( mT );
726 double dx = std::cos( alpha ) * interval;
727 double dy = std::sin( alpha ) * interval;
728 return ( mIncreasing ? QPointF( dx, dy ) : QPointF( -dx, -dy ) );
731 double length() {
return mLength; }
746 : mRotateSymbols( rotateSymbol )
747 , mInterval( interval )
767 if ( exprVal.isValid() )
769 QString placementString = exprVal.toString();
770 if ( placementString.compare( QLatin1String(
"interval" ), Qt::CaseInsensitive ) == 0 )
774 else if ( placementString.compare( QLatin1String(
"vertex" ), Qt::CaseInsensitive ) == 0 )
778 else if ( placementString.compare( QLatin1String(
"lastvertex" ), Qt::CaseInsensitive ) == 0 )
782 else if ( placementString.compare( QLatin1String(
"firstvertex" ), Qt::CaseInsensitive ) == 0 )
786 else if ( placementString.compare( QLatin1String(
"centerpoint" ), Qt::CaseInsensitive ) == 0 )
790 else if ( placementString.compare( QLatin1String(
"curvepoint" ), Qt::CaseInsensitive ) == 0 )
794 else if ( placementString.compare( QLatin1String(
"segmentcenter" ), Qt::CaseInsensitive ) == 0 )
808 double averageOver = mAverageAngleLength;
821 renderPolylineInterval( points, context, averageOver );
825 renderPolylineCentral( points, context, averageOver );
833 renderPolylineVertex( points, context, placement );
842 for (
int part = 0; part < mline.count(); ++part )
844 const QPolygonF &points2 = mline[ part ];
849 renderPolylineInterval( points2, context, averageOver );
853 renderPolylineCentral( points2, context, averageOver );
861 renderPolylineVertex( points2, context, placement );
897 for (
int i = 0; i < rings->size(); ++i )
946 map[QStringLiteral(
"rotate" )] = (
rotateSymbols() ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
947 map[QStringLiteral(
"interval" )] = QString::number(
interval() );
948 map[QStringLiteral(
"offset" )] = QString::number(
mOffset );
949 map[QStringLiteral(
"offset_along_line" )] = QString::number(
offsetAlongLine() );
956 map[QStringLiteral(
"average_angle_length" )] = QString::number( mAverageAngleLength );
960 switch ( mPlacement )
963 map[QStringLiteral(
"placement" )] = QStringLiteral(
"vertex" );
966 map[QStringLiteral(
"placement" )] = QStringLiteral(
"lastvertex" );
969 map[QStringLiteral(
"placement" )] = QStringLiteral(
"firstvertex" );
972 map[QStringLiteral(
"placement" )] = QStringLiteral(
"centralpoint" );
975 map[QStringLiteral(
"placement" )] = QStringLiteral(
"curvepoint" );
978 map[QStringLiteral(
"placement" )] = QStringLiteral(
"interval" );
981 map[QStringLiteral(
"placement" )] = QStringLiteral(
"segmentcenter" );
985 map[QStringLiteral(
"ring_filter" )] = QString::number( static_cast< int >(
mRingFilter ) );
1011 if ( properties.contains( QStringLiteral(
"offset" ) ) )
1013 destLayer->
setOffset( properties[QStringLiteral(
"offset" )].toDouble() );
1015 if ( properties.contains( QStringLiteral(
"offset_unit" ) ) )
1019 if ( properties.contains( QStringLiteral(
"interval_unit" ) ) )
1023 if ( properties.contains( QStringLiteral(
"offset_along_line" ) ) )
1025 destLayer->
setOffsetAlongLine( properties[QStringLiteral(
"offset_along_line" )].toDouble() );
1027 if ( properties.contains( QStringLiteral(
"offset_along_line_unit" ) ) )
1031 if ( properties.contains( ( QStringLiteral(
"offset_along_line_map_unit_scale" ) ) ) )
1036 if ( properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1040 if ( properties.contains( QStringLiteral(
"interval_map_unit_scale" ) ) )
1045 if ( properties.contains( QStringLiteral(
"average_angle_length" ) ) )
1047 destLayer->
setAverageAngleLength( properties[QStringLiteral(
"average_angle_length" )].toDouble() );
1049 if ( properties.contains( QStringLiteral(
"average_angle_unit" ) ) )
1053 if ( properties.contains( ( QStringLiteral(
"average_angle_map_unit_scale" ) ) ) )
1058 if ( properties.contains( QStringLiteral(
"placement" ) ) )
1060 if ( properties[QStringLiteral(
"placement" )] == QLatin1String(
"vertex" ) )
1062 else if ( properties[QStringLiteral(
"placement" )] == QLatin1String(
"lastvertex" ) )
1064 else if ( properties[QStringLiteral(
"placement" )] == QLatin1String(
"firstvertex" ) )
1066 else if ( properties[QStringLiteral(
"placement" )] == QLatin1String(
"centralpoint" ) )
1068 else if ( properties[QStringLiteral(
"placement" )] == QLatin1String(
"curvepoint" ) )
1070 else if ( properties[QStringLiteral(
"placement" )] == QLatin1String(
"segmentcenter" ) )
1076 if ( properties.contains( QStringLiteral(
"ring_filter" ) ) )
1078 destLayer->
setRingFilter( static_cast< RenderRingFilter>( properties[QStringLiteral(
"ring_filter" )].toInt() ) );
1084 void QgsTemplatedLineSymbolLayerBase::renderPolylineInterval(
const QPolygonF &points,
QgsSymbolRenderContext &context,
double averageOver )
1086 if ( points.isEmpty() )
1089 double lengthLeft = 0;
1102 if ( interval <= 0 )
1115 if ( painterUnitInterval < 0 )
1119 lengthLeft = painterUnitInterval - painterUnitOffsetAlongLine;
1121 if ( averageOver > 0 && !
qgsDoubleNear( averageOver, 0.0 ) )
1123 QVector< QPointF > angleStartPoints;
1124 QVector< QPointF > symbolPoints;
1125 QVector< QPointF > angleEndPoints;
1133 collectOffsetPoints( points, symbolPoints, painterUnitInterval, lengthLeft );
1135 if ( symbolPoints.empty() )
1141 if ( symbolPoints.count() > 1 && symbolPoints.constFirst() == symbolPoints.constLast() )
1144 symbolPoints.pop_back();
1147 angleEndPoints.reserve( symbolPoints.size() );
1148 angleStartPoints.reserve( symbolPoints.size() );
1149 if ( averageOver <= painterUnitOffsetAlongLine )
1151 collectOffsetPoints( points, angleStartPoints, painterUnitInterval, lengthLeft + averageOver, 0, symbolPoints.size() );
1155 collectOffsetPoints( points, angleStartPoints, painterUnitInterval, 0, averageOver - painterUnitOffsetAlongLine, symbolPoints.size() );
1157 collectOffsetPoints( points, angleEndPoints, painterUnitInterval, lengthLeft - averageOver, 0, symbolPoints.size() );
1160 for (
int i = 0; i < symbolPoints.size(); ++ i )
1165 const QPointF pt = symbolPoints[i];
1166 const QPointF startPt = angleStartPoints[i];
1167 const QPointF endPt = angleEndPoints[i];
1169 MyLine l( startPt, endPt );
1184 QPointF lastPt = points[0];
1185 for (
int i = 1; i < points.count(); ++i )
1190 const QPointF &pt = points[i];
1196 MyLine l( lastPt, pt );
1197 QPointF diff = l.diffForInterval( painterUnitInterval );
1201 double c = 1 - lengthLeft / painterUnitInterval;
1203 lengthLeft += l.length();
1212 while ( lengthLeft > painterUnitInterval )
1216 lengthLeft -= painterUnitInterval;
1228 static double _averageAngle( QPointF prevPt, QPointF pt, QPointF nextPt )
1231 double a1 = MyLine( prevPt, pt ).angle();
1232 double a2 = MyLine( pt, nextPt ).angle();
1233 double unitX = std::cos( a1 ) + std::cos( a2 ), unitY = std::sin( a1 ) + std::sin( a2 );
1235 return std::atan2( unitY, unitX );
1240 if ( points.isEmpty() )
1246 int i = -1, maxCount = 0;
1247 bool isRing =
false;
1309 switch ( placement )
1320 i = points.count() - 1;
1321 maxCount = points.count();
1328 i = placement ==
Vertex ? 0 : 1;
1329 maxCount = points.count();
1330 if ( points.first() == points.last() )
1347 renderOffsetVertexAlongLine( points, i, distance, context );
1357 prevPoint = points.at( 0 );
1359 QPointF symbolPoint;
1360 for ( ; i < maxCount; ++i )
1371 QPointF currentPoint = points.at( i );
1372 symbolPoint = QPointF( 0.5 * ( currentPoint.x() + prevPoint.x() ),
1373 0.5 * ( currentPoint.y() + prevPoint.y() ) );
1376 double angle = std::atan2( currentPoint.y() - prevPoint.y(),
1377 currentPoint.x() - prevPoint.x() );
1380 prevPoint = currentPoint;
1384 symbolPoint = points.at( i );
1388 double angle = markerAngle( points, isRing, i );
1400 double QgsTemplatedLineSymbolLayerBase::markerAngle(
const QPolygonF &points,
bool isRing,
int vertex )
1403 const QPointF &pt = points[vertex];
1405 if ( isRing || ( vertex > 0 && vertex < points.count() - 1 ) )
1407 int prevIndex = vertex - 1;
1408 int nextIndex = vertex + 1;
1410 if ( isRing && ( vertex == 0 || vertex == points.count() - 1 ) )
1412 prevIndex = points.count() - 2;
1416 QPointF prevPoint, nextPoint;
1417 while ( prevIndex >= 0 )
1419 prevPoint = points[ prevIndex ];
1420 if ( prevPoint != pt )
1427 while ( nextIndex < points.count() )
1429 nextPoint = points[ nextIndex ];
1430 if ( nextPoint != pt )
1437 if ( prevIndex >= 0 && nextIndex < points.count() )
1439 angle = _averageAngle( prevPoint, pt, nextPoint );
1446 while ( vertex < points.size() - 1 )
1448 const QPointF &nextPt = points[vertex + 1];
1451 angle = MyLine( pt, nextPt ).angle();
1460 while ( vertex >= 1 )
1462 const QPointF &prevPt = points[vertex - 1];
1465 angle = MyLine( prevPt, pt ).angle();
1475 void QgsTemplatedLineSymbolLayerBase::renderOffsetVertexAlongLine(
const QPolygonF &points,
int vertex,
double distance,
QgsSymbolRenderContext &context )
1477 if ( points.isEmpty() )
1487 bool isRing =
false;
1488 if ( points.first() == points.last() )
1490 double angle = markerAngle( points, isRing, vertex );
1497 int pointIncrement = distance > 0 ? 1 : -1;
1498 QPointF previousPoint = points[vertex];
1499 int startPoint = distance > 0 ? std::min( vertex + 1, points.count() - 1 ) : std::max( vertex - 1, 0 );
1500 int endPoint = distance > 0 ? points.count() - 1 : 0;
1501 double distanceLeft = std::fabs( distance );
1503 for (
int i = startPoint; pointIncrement > 0 ? i <= endPoint : i >= endPoint; i += pointIncrement )
1505 const QPointF &pt = points[i];
1507 if ( previousPoint == pt )
1511 MyLine l( previousPoint, pt );
1513 if ( distanceLeft < l.length() )
1516 QPointF markerPoint = previousPoint + l.diffForInterval( distanceLeft );
1526 distanceLeft -= l.length();
1533 void QgsTemplatedLineSymbolLayerBase::collectOffsetPoints(
const QVector<QPointF> &p, QVector<QPointF> &dest,
double intervalPainterUnits,
double initialOffset,
double initialLag,
int numberPointsRequired )
1538 QVector< QPointF > points = p;
1539 const bool closedRing = points.first() == points.last();
1541 double lengthLeft = initialOffset;
1543 double initialLagLeft = initialLag > 0 ? -initialLag : 1;
1544 if ( initialLagLeft < 0 && closedRing )
1547 QPointF lastPt = points.constLast();
1548 QVector< QPointF > pseudoPoints;
1549 for (
int i = points.count() - 2; i > 0; --i )
1551 if ( initialLagLeft >= 0 )
1556 const QPointF &pt = points[i];
1561 MyLine l( lastPt, pt );
1562 initialLagLeft += l.length();
1567 std::reverse( pseudoPoints.begin(), pseudoPoints.end() );
1569 points = pseudoPoints;
1574 while ( initialLagLeft < 0 )
1576 dest << points.constFirst();
1577 initialLagLeft += intervalPainterUnits;
1580 if ( initialLag > 0 )
1582 lengthLeft += intervalPainterUnits - initialLagLeft;
1585 QPointF lastPt = points[0];
1586 for (
int i = 1; i < points.count(); ++i )
1588 const QPointF &pt = points[i];
1592 if ( closedRing && i == points.count() - 1 && numberPointsRequired > 0 && dest.size() < numberPointsRequired )
1601 MyLine l( lastPt, pt );
1602 QPointF diff = l.diffForInterval( intervalPainterUnits );
1606 double c = 1 - lengthLeft / intervalPainterUnits;
1608 lengthLeft += l.length();
1611 while ( lengthLeft > intervalPainterUnits ||
qgsDoubleNear( lengthLeft, intervalPainterUnits, 0.000000001 ) )
1615 lengthLeft -= intervalPainterUnits;
1618 if ( numberPointsRequired > 0 && dest.size() >= numberPointsRequired )
1623 if ( numberPointsRequired > 0 && dest.size() >= numberPointsRequired )
1627 if ( closedRing && i == points.count() - 1 && numberPointsRequired > 0 && dest.size() < numberPointsRequired )
1634 if ( !closedRing && numberPointsRequired > 0 && dest.size() < numberPointsRequired )
1637 while ( dest.size() < numberPointsRequired )
1638 dest << points.constLast();
1642 void QgsTemplatedLineSymbolLayerBase::renderPolylineCentral(
const QPolygonF &points,
QgsSymbolRenderContext &context,
double averageAngleOver )
1644 if ( !points.isEmpty() )
1648 QPolygonF::const_iterator it = points.constBegin();
1650 for ( ++it; it != points.constEnd(); ++it )
1652 length += std::sqrt( ( last.x() - it->x() ) * ( last.x() - it->x() ) +
1653 ( last.y() - it->y() ) * ( last.y() - it->y() ) );
1657 const double midPoint = length / 2;
1660 double thisSymbolAngle = 0;
1662 if ( averageAngleOver > 0 && !
qgsDoubleNear( averageAngleOver, 0.0 ) )
1664 QVector< QPointF > angleStartPoints;
1665 QVector< QPointF > symbolPoints;
1666 QVector< QPointF > angleEndPoints;
1668 collectOffsetPoints( points, symbolPoints, midPoint, midPoint, 0.0, 2 );
1669 collectOffsetPoints( points, angleStartPoints, midPoint, 0, averageAngleOver, 2 );
1670 collectOffsetPoints( points, angleEndPoints, midPoint, midPoint - averageAngleOver, 0, 2 );
1672 pt = symbolPoints.at( 1 );
1673 MyLine l( angleStartPoints.at( 1 ), angleEndPoints.at( 1 ) );
1674 thisSymbolAngle = l.angle();
1679 it = points.constBegin();
1681 qreal last_at = 0, next_at = 0;
1684 for ( ++it; it != points.constEnd(); ++it )
1687 next_at += std::sqrt( ( last.x() - it->x() ) * ( last.x() - it->x() ) +
1688 ( last.y() - it->y() ) * ( last.y() - it->y() ) );
1689 if ( next_at >= midPoint )
1697 MyLine l( last, next );
1698 qreal k = ( length * 0.5 - last_at ) / ( next_at - last_at );
1699 pt = last + ( next - last ) * k;
1700 thisSymbolAngle = l.angle();
1715 return mMarker.get();
1726 mMarker.reset( static_cast<QgsMarkerSymbol *>( symbol ) );
1727 mColor = mMarker->color();
1748 if ( props.contains( QStringLiteral(
"interval" ) ) )
1749 interval = props[QStringLiteral(
"interval" )].toDouble();
1750 if ( props.contains( QStringLiteral(
"rotate" ) ) )
1751 rotate = ( props[QStringLiteral(
"rotate" )] == QLatin1String(
"1" ) );
1753 std::unique_ptr< QgsMarkerLineSymbolLayer > x = qgis::make_unique< QgsMarkerLineSymbolLayer >( rotate,
interval );
1760 return QStringLiteral(
"MarkerLine" );
1779 QgsSymbol::RenderHints hints =
nullptr;
1782 mMarker->setRenderHints( hints );
1795 std::unique_ptr< QgsMarkerLineSymbolLayer > x = qgis::make_unique< QgsMarkerLineSymbolLayer >(
rotateSymbols(),
interval() );
1802 for (
int i = 0; i <
mMarker->symbolLayerCount(); i++ )
1804 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:LineSymbolizer" ) );
1805 if ( !props.value( QStringLiteral(
"uom" ), QString() ).isEmpty() )
1806 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ) );
1807 element.appendChild( symbolizerElem );
1842 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
1843 symbolizerElem.appendChild( strokeElem );
1846 QDomElement graphicStrokeElem = doc.createElement( QStringLiteral(
"se:GraphicStroke" ) );
1847 strokeElem.appendChild( graphicStrokeElem );
1853 graphicStrokeElem.appendChild( doc.createComment( QStringLiteral(
"MarkerSymbolLayerV2 expected, %1 found. Skip it." ).arg( layer->
layerType() ) ) );
1860 if ( !gap.isEmpty() )
1862 QDomElement gapElem = doc.createElement( QStringLiteral(
"se:Gap" ) );
1864 graphicStrokeElem.appendChild( gapElem );
1869 QDomElement perpOffsetElem = doc.createElement( QStringLiteral(
"se:PerpendicularOffset" ) );
1871 perpOffsetElem.appendChild( doc.createTextNode(
qgsDoubleToString( offset ) ) );
1872 symbolizerElem.appendChild( perpOffsetElem );
1881 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1882 if ( strokeElem.isNull() )
1885 QDomElement graphicStrokeElem = strokeElem.firstChildElement( QStringLiteral(
"GraphicStroke" ) );
1886 if ( graphicStrokeElem.isNull() )
1894 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
1896 if ( it.key() == QLatin1String(
"placement" ) )
1898 if ( it.value() == QLatin1String(
"points" ) )
1900 else if ( it.value() == QLatin1String(
"firstPoint" ) )
1902 else if ( it.value() == QLatin1String(
"lastPoint" ) )
1904 else if ( it.value() == QLatin1String(
"centralPoint" ) )
1907 else if ( it.value() == QLatin1String(
"rotateMarker" ) )
1909 rotateMarker = it.value() == QLatin1String(
"0" );
1913 std::unique_ptr< QgsMarkerSymbol > marker;
1927 QDomElement gapElem = graphicStrokeElem.firstChildElement( QStringLiteral(
"Gap" ) );
1928 if ( !gapElem.isNull() )
1931 double d = gapElem.firstChild().nodeValue().toDouble( &ok );
1937 QDomElement perpOffsetElem = graphicStrokeElem.firstChildElement( QStringLiteral(
"PerpendicularOffset" ) );
1938 if ( !perpOffsetElem.isNull() )
1941 double d = perpOffsetElem.firstChild().nodeValue().toDouble( &ok );
1946 QString uom = element.attribute( QStringLiteral(
"uom" ) );
1968 mMarker->setDataDefinedSize( property );
1975 mMarker->setLineAngle( angle );
1990 mMarker->renderPoint( point, feature, context, layer, selected );
2000 return mMarker->size( context );
2006 mMarker->setOutputUnit( unit );
2017 attr.unite(
mMarker->usedAttributes( context ) );
2032 return (
mMarker->size( context ) / 2.0 ) +
2052 if ( props.contains( QStringLiteral(
"interval" ) ) )
2053 interval = props[QStringLiteral(
"interval" )].toDouble();
2054 if ( props.contains( QStringLiteral(
"rotate" ) ) )
2055 rotate = ( props[QStringLiteral(
"rotate" )] == QLatin1String(
"1" ) );
2057 std::unique_ptr< QgsHashedLineSymbolLayer > x = qgis::make_unique< QgsHashedLineSymbolLayer >( rotate,
interval );
2059 if ( props.contains( QStringLiteral(
"hash_angle" ) ) )
2061 x->setHashAngle( props[QStringLiteral(
"hash_angle" )].toDouble() );
2064 if ( props.contains( QStringLiteral(
"hash_length" ) ) )
2065 x->setHashLength( props[QStringLiteral(
"hash_length" )].toDouble() );
2067 if ( props.contains( QStringLiteral(
"hash_length_unit" ) ) )
2070 if ( props.contains( QStringLiteral(
"hash_length_map_unit_scale" ) ) )
2078 return QStringLiteral(
"HashLine" );
2083 mHashSymbol->setOpacity( context.
opacity() );
2086 QgsSymbol::RenderHints hints =
nullptr;
2089 mHashSymbol->setRenderHints( hints );
2102 map[ QStringLiteral(
"hash_angle" ) ] = QString::number( mHashAngle );
2104 map[QStringLiteral(
"hash_length" )] = QString::number( mHashLength );
2113 std::unique_ptr< QgsHashedLineSymbolLayer > x = qgis::make_unique< QgsHashedLineSymbolLayer >(
rotateSymbols(),
interval() );
2115 x->setHashAngle( mHashAngle );
2116 x->setHashLength( mHashLength );
2117 x->setHashLengthUnit( mHashLengthUnit );
2118 x->setHashLengthMapUnitScale( mHashLengthMapUnitScale );
2124 mHashSymbol->setColor( color );
2130 return mHashSymbol ? mHashSymbol->color() :
mColor;
2135 return mHashSymbol.get();
2146 mHashSymbol.reset( static_cast<QgsLineSymbol *>( symbol ) );
2147 mColor = mHashSymbol->color();
2153 mHashLength =
width;
2168 return ( mHashSymbol->width( context ) / 2.0 )
2176 mHashSymbol->setOutputUnit( unit );
2186 attr.unite( mHashSymbol->usedAttributes( context ) );
2194 if ( mHashSymbol && mHashSymbol->hasDataDefinedProperties() )
2203 mHashSymbol->setDataDefinedWidth( property );
2210 mSymbolLineAngle =
angle;
2215 return mSymbolAngle;
2220 mSymbolAngle =
angle;
2225 double lineLength = mHashLength;
2231 const double w = context.
convertToPainterUnits( lineLength, mHashLengthUnit, mHashLengthMapUnitScale ) / 2.0;
2241 QgsPointXY start = center.
project( w, 180 - ( mSymbolAngle + mSymbolLineAngle + hashAngle ) );
2242 QgsPointXY end = center.
project( -w, 180 - ( mSymbolAngle + mSymbolLineAngle + hashAngle ) );
2245 points << QPointF( start.
x(), start.
y() ) << QPointF( end.
x(), end.
y() );
2247 mHashSymbol->renderPolyline( points, feature, context, layer, selected );
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void setOffsetAlongLine(double offsetAlongLine)
Sets the the offset along the line for the symbol placement.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
QColor valueAsColor(int key, const QgsExpressionContext &context, const QColor &defaultColor=QColor(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a color...
Place symbols on the first vertex in the line.
Single variable definition for use within a QgsExpressionContextScope.
void setMapUnitScale(const QgsMapUnitScale &scale) override
double symbolAngle() const override
Returns the symbol's current angle, in degrees clockwise.
double dxfOffset(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets offset.
double symbologyScale() const
Returns the reference scale for output.
QgsHashedLineSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void setMapUnitScale(const QgsMapUnitScale &scale) override
void clipValueToMapUnitScale(double &value, const QgsMapUnitScale &scale, double pixelToMMFactor) const
Clips value to scale minimum/maximum.
static QDomElement createVendorOptionElement(QDomDocument &doc, const QString &name, const QString &value)
void renderPolygonStroke(const QPolygonF &points, QList< QPolygonF > *rings, QgsSymbolRenderContext &context) override
Renders the line symbol layer along the outline of polygon, using the given render context...
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void setPlacement(Placement placement)
Sets the placement of the symbols.
const QgsVectorSimplifyMethod & vectorSimplifyMethod() const
Returns the simplification settings to use when rendering vector layers.
QgsFields fields() const
Fields of the layer.
static const QString EXPR_GEOMETRY_POINT_COUNT
Inbuilt variable name for point count variable.
Abstract base class for all rendered symbols.
double valueAsDouble(int key, const QgsExpressionContext &context, double defaultValue=0.0, bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a double...
void setUseCustomDashPattern(bool b)
Sets whether the line uses a custom dash pattern.
virtual QgsSymbol * subSymbol()
Returns the symbol's sub symbol, if present.
void renderPolyline(const QPolygonF &points, QgsSymbolRenderContext &context) FINAL
Renders the line symbol layer along the line joining points, using the given render context...
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const override
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsSimpleLineSymbolLayer from an SLD XML DOM element.
A class to represent a 2D point.
void setSymbolLineAngle(double angle) override
Sets the line angle modification for the symbol's angle.
A simple line symbol layer, which renders lines using a line in a variety of styles (e...
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
Render both exterior and interior rings.
const QgsCurve * interiorRing(int i) const
Retrieves an interior ring from the curve polygon.
virtual void setSymbolLineAngle(double angle)=0
Sets the line angle modification for the symbol's angle.
void renderSymbol(const QPointF &point, const QgsFeature *feature, QgsRenderContext &context, int layer=-1, bool selected=false) override
Renders the templated symbol at the specified point, using the given render context.
#define DEFAULT_MARKERLINE_INTERVAL
virtual double vertexAngle(QgsVertexId vertex) const =0
Returns approximate angle at a vertex.
bool renderingStopped() const
Returns true if the rendering operation has been stopped and any ongoing rendering should be canceled...
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
Curve polygon geometry type.
QgsUnitTypes::RenderUnit mOffsetUnit
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
void restoreOldDataDefinedProperties(const QgsStringMap &stringMap)
Restores older data defined properties from string map.
static double sizeInPixelsFromSldUom(const QString &uom, double size)
Returns the size scaled in pixels according to the uom attribute.
QgsUnitTypes::DistanceUnit mapUnits() const
Retrieve map units.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsHashedLineSymbolLayer, using the settings serialized in the properties map (correspo...
void copyTemplateSymbolProperties(QgsTemplatedLineSymbolLayerBase *destLayer) const
Copies all common properties of this layer to another templated symbol layer.
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the line's offset.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
virtual bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const =0
Returns next vertex id and coordinates.
Place symbols on every vertex in the line.
QgsUnitTypes::RenderUnit intervalUnit() const
Returns the units for the interval between symbols.
QgsHashedLineSymbolLayer(bool rotateSymbol=true, double interval=3)
Constructor for QgsHashedLineSymbolLayer.
double interval() const
Returns the interval between individual symbols.
static bool createExpressionElement(QDomDocument &doc, QDomElement &element, const QString &function)
Creates a OGC Expression element based on the provided function expression.
QMap< QString, QString > QgsStringMap
Rotation of symbol may be changed during rendering and symbol should not be cached.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
void addVariable(const QgsExpressionContextScope::StaticVariable &variable)
Adds a variable into the context scope.
void setInterval(double interval)
Sets the interval between individual symbols.
virtual double width() const
Returns the estimated width for the line symbol layer.
A marker symbol type, for rendering Point and MultiPoint geometries.
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
void setWidthUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the line's width.
A line symbol type, for rendering LineString and MultiLineString geometries.
void setWidth(double width) override
Sets the width of the line symbol layer.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
Place symbols at every virtual curve point in the line (used when rendering curved geometry types onl...
static QVector< qreal > decodeRealVector(const QString &s)
void setCustomDashPatternUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for lengths used in the custom dash pattern.
static QString encodeColor(const QColor &color)
double symbolAngle() const override
Returns the symbol's current angle, in degrees clockwise.
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties...
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
Place symbols at the center of every line segment.
void setAverageAngleUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the length over which the line's direction is averaged when calculating individual ...
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
std::unique_ptr< QgsMarkerSymbol > mMarker
void transformInPlace(double &x, double &y) const
Transform device coordinates to map coordinates.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const override
Returns the calculated value of the property with the specified key from within the collection...
QString layerType() const override
Returns a string that represents this layer type.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
static QString encodePenStyle(Qt::PenStyle style)
Perform transforms between map coordinates and device coordinates.
virtual void writeSldMarker(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const
Writes the symbol layer definition as a SLD XML element.
static double rescaleUom(double size, QgsUnitTypes::RenderUnit unit, const QgsStringMap &props)
Rescales the given size based on the uomScale found in the props, if any is found, otherwise returns the value un-modified.
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
void setOffsetAlongLineMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale used for calculating the offset in map units along line for symbols...
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
void setIntervalUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the interval between symbols.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsMarkerLineSymbolLayer, using the settings serialized in the properties map (correspo...
QgsUnitTypes::RenderUnit widthUnit() const
Returns the units for the line's width.
Utility class for identifying a unique vertex within a geometry.
void setGeometry(const QgsAbstractGeometry *geometry)
Sets pointer to original (unsegmentized) geometry.
The geometries can be rendered with 'AntiAliasing' disabled because of it is '1-pixel size'...
QVector< qreal > customDashVector() const
Returns the custom dash vector, which is the pattern of alternating drawn/skipped lengths used while ...
static QgsStringMap getVendorOptionList(QDomElement &element)
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties...
qreal opacity() const
Returns the opacity for the symbol.
static void setCommonProperties(QgsTemplatedLineSymbolLayerBase *destLayer, const QgsStringMap &properties)
Sets all common symbol properties in the destLayer, using the settings serialized in the properties m...
const QgsAbstractGeometry * geometry() const
Returns pointer to the unsegmentized geometry.
Render the interior rings only.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
QgsTemplatedLineSymbolLayerBase(bool rotateSymbol=true, double interval=3)
Constructor for QgsTemplatedLineSymbolLayerBase.
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides...
Line symbol layer type which draws repeating line sections along a line feature.
virtual QgsSymbolLayer * clone() const =0
Shall be reimplemented by subclasses to create a deep copy of the instance.
#define DEFAULT_SIMPLELINE_PENSTYLE
static double mapUnitScaleFactor(double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
QgsMapUnitScale mOffsetMapUnitScale
virtual QColor color() const
The fill color.
static QgsSymbolLayer * createMarkerLayerFromSld(QDomElement &element)
QColor selectionColor() const
Returns the color to use when rendering selected features.
QgsMarkerLineSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void renderPolyline(const QPolygonF &points, QgsSymbolRenderContext &context) override
Renders the line symbol layer along the line joining points, using the given render context...
double width() const override
Returns the estimated width for the line symbol layer.
virtual double symbolAngle() const =0
Returns the symbol's current angle, in degrees clockwise.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
float threshold() const
Gets the simplification threshold of the vector layer managed.
QList< QgsSymbolLayer * > QgsSymbolLayerList
void stopRender(QgsSymbolRenderContext &context) override
#define DEFAULT_SIMPLELINE_COLOR
QgsUnitTypes::RenderUnit offsetAlongLineUnit() const
Returns the unit used for calculating the offset along line for symbols.
QgsSimpleLineSymbolLayer(const QColor &color=DEFAULT_SIMPLELINE_COLOR, double width=DEFAULT_SIMPLELINE_WIDTH, Qt::PenStyle penStyle=DEFAULT_SIMPLELINE_PENSTYLE)
Constructor for QgsSimpleLineSymbolLayer.
QgsPointXY project(double distance, double bearing) const
Returns a new point which corresponds to this point projected by a specified distance in a specified ...
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
static Qt::PenCapStyle decodePenCapStyle(const QString &str)
Qt::PenJoinStyle penJoinStyle() const
Returns the pen join style used to render the line (e.g.
QgsUnitTypes::RenderUnit outputUnit() const FINAL
Returns the units to use for sizes and widths within the symbol layer.
double offset() const
Returns the line's offset.
void stopRender(QgsSymbolRenderContext &context) override
void setDataDefinedProperty(QgsSymbolLayer::Property key, const QgsProperty &property) override
Sets a data defined property for the layer.
static Q_INVOKABLE QgsUnitTypes::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static bool lineFromSld(QDomElement &element, Qt::PenStyle &penStyle, QColor &color, double &width, Qt::PenJoinStyle *penJoinStyle=nullptr, Qt::PenCapStyle *penCapStyle=nullptr, QVector< qreal > *customDashPattern=nullptr, double *dashOffset=nullptr)
Base class for templated line symbols, e.g.
Single scope for storing variables and functions for use within a QgsExpressionContext.
double mapUnitsPerPixel() const
Returns current map units per pixel.
Q_DECL_DEPRECATED bool rotateMarker() const
Shall the marker be rotated.
A store for object properties.
QgsMapUnitScale mWidthMapUnitScale
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
void setHashAngle(double angle)
Sets the angle to use when drawing the hashed lines sections, in degrees clockwise.
void setSymbolAngle(double angle) override
Sets the symbol's angle, in degrees clockwise.
const QgsMapUnitScale & offsetAlongLineMapUnitScale() const
Returns the map unit scale used for calculating the offset in map units along line for symbols...
Point geometry type, with support for z-dimension and m-values.
static Qt::PenStyle decodePenStyle(const QString &str)
QString layerType() const override
Returns a string that represents this layer type.
bool selected() const
Returns true if symbols should be rendered using the selected symbol coloring and style...
void setMapUnitScale(const QgsMapUnitScale &scale) FINAL
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
Creates a new QgsSimpleLineSymbolLayer, using the settings serialized in the properties map (correspo...
double width() const override
Returns the estimated width for the line symbol layer.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
Place symbols at regular intervals.
static void createGeometryElement(QDomDocument &doc, QDomElement &element, const QString &geomFunc)
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
QgsWkbTypes::GeometryType originalGeometryType() const
Returns the geometry type for the original feature geometry being rendered.
void startRender(QgsSymbolRenderContext &context) override
void setPenCapStyle(Qt::PenCapStyle style)
Sets the pen cap style used to render the line (e.g.
QgsExpressionContext & expressionContext()
Gets the expression context.
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
Line angle, or angle of hash lines for hash line symbols.
#define DEFAULT_SIMPLELINE_WIDTH
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void stopRender(QgsSymbolRenderContext &context) override
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
Stroke style (eg solid, dashed)
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
double hashAngle() const
Returns the angle to use when drawing the hashed lines sections, in degrees clockwise.
Contains information about the context of a rendering operation.
Abstract base class for marker symbol layers.
QColor color() const override
The fill color.
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
void startRender(QgsSymbolRenderContext &context) override
QgsSimpleLineSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
const QgsMapUnitScale & intervalMapUnitScale() const
Returns the map unit scale for the interval between symbols.
QPainter * painter()
Returns the destination QPainter for the render operation.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
void setWidth(double width) override
Sets the width of the line symbol layer.
Line symbol layer type which draws repeating marker symbols along a line feature. ...
RenderRingFilter mRingFilter
void startRender(QgsSymbolRenderContext &context) override
SymbolType type() const
Returns the symbol's type.
Struct for storing maximum and minimum scales for measurements in map units.
void setCustomDashPatternMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for lengths used in the custom dash pattern.
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
Placement
Defines how/where the templated symbol should be placed on the line.
void setWidthMapUnitScale(const QgsMapUnitScale &scale)
void setIntervalMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the interval between symbols.
Qt::PenStyle penStyle() const
Returns the pen style used to render the line (e.g.
virtual void setSymbolAngle(double angle)=0
Sets the symbol's angle, in degrees clockwise.
QgsUnitTypes::RenderUnit mWidthUnit
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
const QgsFeature * feature() const
Returns the current feature being rendered.
Distance between lines, or length of lines for hash line symbols.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit for the line's offset.
void setRingFilter(QgsLineSymbolLayer::RenderRingFilter filter)
Sets the line symbol layer's ring filter, which controls which rings are rendered when the line symbo...
void setColor(const QColor &color) override
The fill color.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
SimplifyHints simplifyHints() const
Gets the simplification hints of the vector layer managed.
void setDrawInsidePolygon(bool drawInsidePolygon)
Sets whether the line should only be drawn inside polygons, and any portion of the line which falls o...
QgsMarkerLineSymbolLayer(bool rotateMarker=DEFAULT_MARKERLINE_ROTATE, double interval=DEFAULT_MARKERLINE_INTERVAL)
Constructor for QgsMarkerLineSymbolLayer.
void setCustomDashVector(const QVector< qreal > &vector)
Sets the custom dash vector, which is the pattern of alternating drawn/skipped lengths used while ren...
void setDataDefinedProperty(QgsSymbolLayer::Property key, const QgsProperty &property) override
Sets a data defined property for the layer.
QgsMapUnitScale mapUnitScale() const FINAL
static const QString EXPR_GEOMETRY_POINT_NUM
Inbuilt variable name for point number variable.
QList< QPolygonF > offsetLine(QPolygonF polyline, double dist, QgsWkbTypes::GeometryType geometryType)
calculate geometry shifted by a specified distance
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
Placement placement() const
Returns the placement of the symbols.
Place symbols on the last vertex in the line.
Length to average symbol angles over.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties...
void setOffsetAlongLineUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit used for calculating the offset along line for symbols.
Render the exterior ring only.
static void lineToSld(QDomDocument &doc, QDomElement &element, Qt::PenStyle penStyle, const QColor &color, double width=-1, const Qt::PenJoinStyle *penJoinStyle=nullptr, const Qt::PenCapStyle *penCapStyle=nullptr, const QVector< qreal > *customDashPattern=nullptr, double dashOffset=0.0)
void setAverageAngleLength(double length)
Sets the length of line over which the line's direction is averaged when calculating individual symbo...
void setSymbolLineAngle(double angle) override
Sets the line angle modification for the symbol's angle.
static QString encodePenCapStyle(Qt::PenCapStyle style)
Place symbols at the mid point of the line.
QString layerType() const override
Returns a string that represents this layer type.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsMarkerLineSymbolLayer from an SLD XML DOM element.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the line's offset.
const QgsCurve * exteriorRing() const
Returns the curve polygon's exterior ring.
QVector< qreal > dxfCustomDashPattern(QgsUnitTypes::RenderUnit &unit) const override
Gets dash pattern.
QgsMapUnitScale mapUnitScale() const override
void setAverageAngleMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the length over which the line's direction is averaged when calculating i...
void setColor(const QColor &color) override
The fill color.
static bool isGeneralizableByDeviceBoundingBox(const QgsRectangle &envelope, float mapToPixelTol=1.0f)
Returns whether the device-envelope can be replaced by its BBOX when is applied the specified toleran...
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const override
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
Qt::PenCapStyle penCapStyle() const
Returns the pen cap style used to render the line (e.g.
void renderPolygonStroke(const QPolygonF &points, QList< QPolygonF > *rings, QgsSymbolRenderContext &context) FINAL
Renders the line symbol layer along the outline of polygon, using the given render context...
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for the context.
static QString ogrFeatureStylePen(double width, double mmScaleFactor, double mapUnitsScaleFactor, const QColor &c, Qt::PenJoinStyle joinStyle=Qt::MiterJoin, Qt::PenCapStyle capStyle=Qt::FlatCap, double offset=0.0, const QVector< qreal > *dashPattern=nullptr)
Create ogr feature style string for pen.
virtual bool hasCurvedSegments() const
Returns true if the geometry contains curved segments.
QColor dxfColor(QgsSymbolRenderContext &context) const override
Gets color.
RAII class to pop scope from an expression context on destruction.
Qt::PenStyle dxfPenStyle() const override
Gets pen style.
#define DEFAULT_MARKERLINE_ROTATE
double offsetAlongLine() const
Returns the offset along the line for the symbol placement.
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
virtual void renderSymbol(const QPointF &point, const QgsFeature *feature, QgsRenderContext &context, int layer=-1, bool selected=false)=0
Renders the templated symbol at the specified point, using the given render context.
void setSymbolAngle(double angle) override
Sets the symbol's angle, in degrees clockwise.
QgsPropertyCollection mDataDefinedProperties
QColor color() const override
The fill color.
QgsMapUnitScale mapUnitScale() const override
void renderSymbol(const QPointF &point, const QgsFeature *feature, QgsRenderContext &context, int layer=-1, bool selected=false) override
Renders the templated symbol at the specified point, using the given render context.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
Property
Data definable properties.
static QString encodeRealVector(const QVector< qreal > &v)
RenderUnit
Rendering size units.
static QColor decodeColor(const QString &str)
virtual void setDataDefinedProperty(Property key, const QgsProperty &property)
Sets a data defined property for the layer.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the pen join style used to render the line (e.g.
void setOffset(double offset)
Sets the line's offset.
virtual QString layerType() const =0
Returns a string that represents this layer type.
bool rotateSymbols() const
Returns true if the repeating symbols be rotated to match their line segment orientation.