30 #include <QDomDocument> 31 #include <QDomElement> 36 : mPenStyle( penStyle )
86 if ( props.contains( QStringLiteral(
"line_color" ) ) )
90 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
94 else if ( props.contains( QStringLiteral(
"color" ) ) )
99 if ( props.contains( QStringLiteral(
"line_width" ) ) )
101 width = props[QStringLiteral(
"line_width" )].toDouble();
103 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
105 width = props[QStringLiteral(
"outline_width" )].toDouble();
107 else if ( props.contains( QStringLiteral(
"width" ) ) )
110 width = props[QStringLiteral(
"width" )].toDouble();
112 if ( props.contains( QStringLiteral(
"line_style" ) ) )
116 else if ( props.contains( QStringLiteral(
"outline_style" ) ) )
120 else if ( props.contains( QStringLiteral(
"penstyle" ) ) )
126 if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
130 else if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
134 else if ( props.contains( QStringLiteral(
"width_unit" ) ) )
139 if ( props.contains( QStringLiteral(
"width_map_unit_scale" ) ) )
141 if ( props.contains( QStringLiteral(
"offset" ) ) )
142 l->
setOffset( props[QStringLiteral(
"offset" )].toDouble() );
143 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
145 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
147 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
149 if ( props.contains( QStringLiteral(
"capstyle" ) ) )
152 if ( props.contains( QStringLiteral(
"use_custom_dash" ) ) )
156 if ( props.contains( QStringLiteral(
"customdash" ) ) )
160 if ( props.contains( QStringLiteral(
"customdash_unit" ) ) )
164 if ( props.contains( QStringLiteral(
"customdash_map_unit_scale" ) ) )
169 if ( props.contains( QStringLiteral(
"draw_inside_polygon" ) ) )
174 if ( props.contains( QStringLiteral(
"ring_filter" ) ) )
176 l->
setRingFilter( static_cast< RenderRingFilter>( props[QStringLiteral(
"ring_filter" )].toInt() ) );
187 return QStringLiteral(
"SimpleLine" );
194 mPen.setColor( penColor );
196 mPen.setWidthF( scaledWidth );
199 mPen.setStyle( Qt::CustomDashLine );
202 double dashWidthDiv =
qgsDoubleNear( scaledWidth, 0 ) ? 1.0 : scaledWidth;
205 QStringList versionSplit = QString( qVersion() ).split(
'.' );
206 if ( versionSplit.size() > 1
207 && versionSplit.at( 1 ).toInt() >= 8
208 && scaledWidth < 1.0 )
212 QVector<qreal> scaledVector;
219 mPen.setDashPattern( scaledVector );
231 selColor.setAlphaF( context.
opacity() );
259 QPainterPath clipPath;
260 clipPath.addPolygon( points );
265 QList<QPolygonF>::const_iterator it = rings->constBegin();
266 for ( ; it != rings->constEnd(); ++it )
268 QPolygonF ring = *it;
269 clipPath.addPolygon( ring );
274 p->setClipPath( clipPath, Qt::IntersectClip );
293 for (
const QPolygonF &ring : qgis::as_const( *rings ) )
320 applyDataDefinedSymbology( context,
mPen,
mSelPen, offset );
323 p->setBrush( Qt::NoBrush );
326 if ( points.size() <= 2 &&
329 ( p->renderHints() & QPainter::Antialiasing ) )
331 p->setRenderHint( QPainter::Antialiasing,
false );
333 p->drawPolyline( points );
336 path.addPolygon( points );
339 p->setRenderHint( QPainter::Antialiasing,
true );
346 p->drawPolyline( points );
349 path.addPolygon( points );
357 for (
int part = 0; part < mline.count(); ++part )
360 p->drawPolyline( mline );
363 path.addPolygon( mline[ part ] );
374 map[QStringLiteral(
"line_width" )] = QString::number(
mWidth );
380 map[QStringLiteral(
"offset" )] = QString::number(
mOffset );
383 map[QStringLiteral(
"use_custom_dash" )] = (
mUseCustomDashPattern ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
387 map[QStringLiteral(
"draw_inside_polygon" )] = (
mDrawInsidePolygon ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
388 map[QStringLiteral(
"ring_filter" )] = QString::number( static_cast< int >(
mRingFilter ) );
418 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:LineSymbolizer" ) );
419 if ( !props.value( QStringLiteral(
"uom" ), QString() ).isEmpty() )
420 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ) );
421 element.appendChild( symbolizerElem );
427 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
428 symbolizerElem.appendChild( strokeElem );
439 QDomElement perpOffsetElem = doc.createElement( QStringLiteral(
"se:PerpendicularOffset" ) );
442 symbolizerElem.appendChild( perpOffsetElem );
465 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
466 if ( strokeElem.isNull() )
478 &penJoinStyle, &penCapStyle,
479 &customDashVector ) )
483 QDomElement perpOffsetElem = element.firstChildElement( QStringLiteral(
"PerpendicularOffset" ) );
484 if ( !perpOffsetElem.isNull() )
487 double d = perpOffsetElem.firstChild().nodeValue().toDouble( &ok );
492 QString uom = element.attribute( QStringLiteral(
"uom" ) );
512 bool hasStrokeWidthExpression =
false;
519 pen.setWidthF( scaledWidth );
520 selPen.setWidthF( scaledWidth );
521 hasStrokeWidthExpression =
true;
542 double dashWidthDiv =
mPen.widthF();
544 if ( hasStrokeWidthExpression )
546 dashWidthDiv = pen.widthF();
547 scaledWidth = pen.widthF();
551 QStringList versionSplit = QString( qVersion() ).split(
'.' );
552 if ( versionSplit.size() > 1
553 && versionSplit.at( 1 ).toInt() >= 8
554 && scaledWidth < 1.0 )
559 QVector<qreal> dashVector;
561 if ( exprVal.isValid() )
563 QStringList dashList = exprVal.toString().split(
';' );
564 QStringList::const_iterator dashIt = dashList.constBegin();
565 for ( ; dashIt != dashList.constEnd(); ++dashIt )
569 pen.setDashPattern( dashVector );
578 if ( exprVal.isValid() )
587 if ( exprVal.isValid() )
596 if ( exprVal.isValid() )
679 MyLine( QPointF p1, QPointF p2 )
681 , mIncreasing(
false )
693 mIncreasing = ( p2.y() > p1.y() );
698 mT = float( p2.y() - p1.y() ) / ( p2.x() - p1.x() );
699 mIncreasing = ( p2.x() > p1.x() );
703 double x = ( p2.x() - p1.x() );
704 double y = ( p2.y() - p1.y() );
705 mLength = std::sqrt( x * x + y * y );
711 double a = ( mVertical ? M_PI_2 : std::atan( mT ) );
719 QPointF diffForInterval(
double interval )
722 return ( mIncreasing ? QPointF( 0, interval ) : QPointF( 0, -interval ) );
724 double alpha = std::atan( mT );
725 double dx = std::cos( alpha ) * interval;
726 double dy = std::sin( alpha ) * interval;
727 return ( mIncreasing ? QPointF( dx, dy ) : QPointF( -dx, -dy ) );
730 double length() {
return mLength; }
743 mRotateMarker = rotateMarker;
744 mInterval = interval;
747 mPlacement = Interval;
748 mOffsetAlongLine = 0;
760 if ( props.contains( QStringLiteral(
"interval" ) ) )
761 interval = props[QStringLiteral(
"interval" )].toDouble();
762 if ( props.contains( QStringLiteral(
"rotate" ) ) )
763 rotate = ( props[QStringLiteral(
"rotate" )] == QLatin1String(
"1" ) );
766 if ( props.contains( QStringLiteral(
"offset" ) ) )
768 x->
setOffset( props[QStringLiteral(
"offset" )].toDouble() );
770 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
774 if ( props.contains( QStringLiteral(
"interval_unit" ) ) )
778 if ( props.contains( QStringLiteral(
"offset_along_line" ) ) )
782 if ( props.contains( QStringLiteral(
"offset_along_line_unit" ) ) )
786 if ( props.contains( ( QStringLiteral(
"offset_along_line_map_unit_scale" ) ) ) )
791 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
795 if ( props.contains( QStringLiteral(
"interval_map_unit_scale" ) ) )
800 if ( props.contains( QStringLiteral(
"placement" ) ) )
802 if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"vertex" ) )
804 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"lastvertex" ) )
806 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"firstvertex" ) )
808 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"centralpoint" ) )
810 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"curvepoint" ) )
816 if ( props.contains( QStringLiteral(
"ring_filter" ) ) )
818 x->
setRingFilter( static_cast< RenderRingFilter>( props[QStringLiteral(
"ring_filter" )].toInt() ) );
828 return QStringLiteral(
"MarkerLine" );
833 mMarker->setColor( color );
839 return mMarker ? mMarker->color() :
mColor;
844 mMarker->setOpacity( context.
opacity() );
847 QgsSymbol::RenderHints hints =
nullptr;
850 mMarker->setRenderHints( hints );
875 if ( exprVal.isValid() )
877 QString placementString = exprVal.toString();
878 if ( placementString.compare( QLatin1String(
"interval" ), Qt::CaseInsensitive ) == 0 )
880 placement = Interval;
882 else if ( placementString.compare( QLatin1String(
"vertex" ), Qt::CaseInsensitive ) == 0 )
886 else if ( placementString.compare( QLatin1String(
"lastvertex" ), Qt::CaseInsensitive ) == 0 )
888 placement = LastVertex;
890 else if ( placementString.compare( QLatin1String(
"firstvertex" ), Qt::CaseInsensitive ) == 0 )
892 placement = FirstVertex;
894 else if ( placementString.compare( QLatin1String(
"centerpoint" ), Qt::CaseInsensitive ) == 0 )
896 placement = CentralPoint;
898 else if ( placementString.compare( QLatin1String(
"curvepoint" ), Qt::CaseInsensitive ) == 0 )
900 placement = CurvePoint;
904 placement = Interval;
914 if ( placement == Interval )
915 renderPolylineInterval( points, context );
916 else if ( placement == CentralPoint )
917 renderPolylineCentral( points, context );
919 renderPolylineVertex( points, context, placement );
926 for (
int part = 0; part < mline.count(); ++part )
928 const QPolygonF &points2 = mline[ part ];
930 if ( placement == Interval )
931 renderPolylineInterval( points2, context );
932 else if ( placement == CentralPoint )
933 renderPolylineCentral( points2, context );
935 renderPolylineVertex( points2, context, placement );
969 for (
int i = 0; i < rings->size(); ++i )
988 if ( points.isEmpty() )
991 QPointF lastPt = points[0];
992 double lengthLeft = 0;
995 double interval = mInterval;
1005 if ( interval <= 0 )
1009 double offsetAlongLine = mOffsetAlongLine;
1016 double painterUnitInterval = rc.
convertToPainterUnits( interval, mIntervalUnit, mIntervalMapUnitScale );
1017 lengthLeft = painterUnitInterval - rc.
convertToPainterUnits( offsetAlongLine, mOffsetAlongLineUnit, mOffsetAlongLineMapUnitScale );
1020 for (
int i = 1; i < points.count(); ++i )
1025 const QPointF &pt = points[i];
1031 MyLine l( lastPt, pt );
1032 QPointF diff = l.diffForInterval( painterUnitInterval );
1036 double c = 1 - lengthLeft / painterUnitInterval;
1038 lengthLeft += l.length();
1041 if ( mRotateMarker )
1043 mMarker->setLineAngle( l.angle() * 180 / M_PI );
1048 while ( lengthLeft > painterUnitInterval )
1055 lengthLeft -= painterUnitInterval;
1057 mMarker->renderPoint( lastPt, context.
feature(), rc, -1, context.
selected() );
1067 static double _averageAngle( QPointF prevPt, QPointF pt, QPointF nextPt )
1070 double a1 = MyLine( prevPt, pt ).angle();
1071 double a2 = MyLine( pt, nextPt ).angle();
1072 double unitX = std::cos( a1 ) + std::cos( a2 ), unitY = std::sin( a1 ) + std::sin( a2 );
1074 return std::atan2( unitY, unitX );
1079 if ( points.isEmpty() )
1084 double origAngle = mMarker->angle();
1086 bool isRing =
false;
1092 double offsetAlongLine = mOffsetAlongLine;
1101 offsetAlongLine = rc.
convertToPainterUnits( offsetAlongLine, mOffsetAlongLineUnit, mOffsetAlongLineMapUnitScale );
1136 if ( mRotateMarker )
1139 mMarker->setAngle( angle * 180 / M_PI );
1141 mMarker->renderPoint( mapPoint, context.
feature(), rc, -1, context.
selected() );
1149 if ( placement == FirstVertex )
1154 else if ( placement == LastVertex )
1156 i = points.count() - 1;
1157 maxCount = points.count();
1159 else if ( placement == Vertex )
1162 maxCount = points.count();
1163 if ( points.first() == points.last() )
1172 if ( offsetAlongLine > 0 && ( placement == FirstVertex || placement == LastVertex ) )
1175 distance = placement == FirstVertex ? offsetAlongLine : -offsetAlongLine;
1176 renderOffsetVertexAlongLine( points, i, distance, context );
1178 mMarker->setAngle( origAngle );
1185 for ( ; i < maxCount; ++i )
1189 if ( isRing && placement == Vertex && i == points.count() - 1 )
1194 if ( mRotateMarker )
1196 double angle = markerAngle( points, isRing, i );
1197 mMarker->setAngle( origAngle + angle * 180 / M_PI );
1200 mMarker->renderPoint( points.at( i ), context.
feature(), rc, -1, context.
selected() );
1204 mMarker->setAngle( origAngle );
1212 const QPointF &pt = points[vertex];
1214 if ( isRing || ( vertex > 0 && vertex < points.count() - 1 ) )
1216 int prevIndex = vertex - 1;
1217 int nextIndex = vertex + 1;
1219 if ( isRing && ( vertex == 0 || vertex == points.count() - 1 ) )
1221 prevIndex = points.count() - 2;
1225 QPointF prevPoint, nextPoint;
1226 while ( prevIndex >= 0 )
1228 prevPoint = points[ prevIndex ];
1229 if ( prevPoint != pt )
1236 while ( nextIndex < points.count() )
1238 nextPoint = points[ nextIndex ];
1239 if ( nextPoint != pt )
1246 if ( prevIndex >= 0 && nextIndex < points.count() )
1248 angle = _averageAngle( prevPoint, pt, nextPoint );
1255 while ( vertex < points.size() - 1 )
1257 const QPointF &nextPt = points[vertex + 1];
1260 angle = MyLine( pt, nextPt ).angle();
1269 while ( vertex >= 1 )
1271 const QPointF &prevPt = points[vertex - 1];
1274 angle = MyLine( prevPt, pt ).angle();
1284 void QgsMarkerLineSymbolLayer::renderOffsetVertexAlongLine(
const QPolygonF &points,
int vertex,
double distance,
QgsSymbolRenderContext &context )
1286 if ( points.isEmpty() )
1290 double origAngle = mMarker->angle();
1294 if ( mRotateMarker )
1296 bool isRing =
false;
1297 if ( points.first() == points.last() )
1299 double angle = markerAngle( points, isRing, vertex );
1300 mMarker->setAngle( origAngle + angle * 180 / M_PI );
1302 mMarker->renderPoint( points[vertex], context.
feature(), rc, -1, context.
selected() );
1306 int pointIncrement = distance > 0 ? 1 : -1;
1307 QPointF previousPoint = points[vertex];
1308 int startPoint = distance > 0 ? std::min( vertex + 1, points.count() - 1 ) : std::max( vertex - 1, 0 );
1309 int endPoint = distance > 0 ? points.count() - 1 : 0;
1310 double distanceLeft = std::fabs( distance );
1312 for (
int i = startPoint; pointIncrement > 0 ? i <= endPoint : i >= endPoint; i += pointIncrement )
1314 const QPointF &pt = points[i];
1316 if ( previousPoint == pt )
1320 MyLine l( previousPoint, pt );
1322 if ( distanceLeft < l.length() )
1325 QPointF markerPoint = previousPoint + l.diffForInterval( distanceLeft );
1327 if ( mRotateMarker )
1329 mMarker->setAngle( origAngle + ( l.angle() * 180 / M_PI ) );
1331 mMarker->renderPoint( markerPoint, context.
feature(), rc, -1, context.
selected() );
1335 distanceLeft -= l.length();
1344 if ( !points.isEmpty() )
1348 QPolygonF::const_iterator it = points.constBegin();
1350 for ( ++it; it != points.constEnd(); ++it )
1352 length += std::sqrt( ( last.x() - it->x() ) * ( last.x() - it->x() ) +
1353 ( last.y() - it->y() ) * ( last.y() - it->y() ) );
1358 it = points.constBegin();
1360 qreal last_at = 0, next_at = 0;
1363 for ( ++it; it != points.constEnd(); ++it )
1366 next_at += std::sqrt( ( last.x() - it->x() ) * ( last.x() - it->x() ) +
1367 ( last.y() - it->y() ) * ( last.y() - it->y() ) );
1368 if ( next_at >= length / 2 )
1376 MyLine l( last, next );
1377 qreal k = ( length * 0.5 - last_at ) / ( next_at - last_at );
1378 QPointF pt = last + ( next - last ) * k;
1381 double origAngle = mMarker->angle();
1382 if ( mRotateMarker )
1383 mMarker->setAngle( origAngle + l.angle() * 180 / M_PI );
1385 if ( mRotateMarker )
1386 mMarker->setAngle( origAngle );
1394 map[QStringLiteral(
"rotate" )] = ( mRotateMarker ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
1395 map[QStringLiteral(
"interval" )] = QString::number( mInterval );
1396 map[QStringLiteral(
"offset" )] = QString::number(
mOffset );
1397 map[QStringLiteral(
"offset_along_line" )] = QString::number( mOffsetAlongLine );
1404 if ( mPlacement == Vertex )
1405 map[QStringLiteral(
"placement" )] = QStringLiteral(
"vertex" );
1406 else if ( mPlacement == LastVertex )
1407 map[QStringLiteral(
"placement" )] = QStringLiteral(
"lastvertex" );
1408 else if ( mPlacement == FirstVertex )
1409 map[QStringLiteral(
"placement" )] = QStringLiteral(
"firstvertex" );
1410 else if ( mPlacement == CentralPoint )
1411 map[QStringLiteral(
"placement" )] = QStringLiteral(
"centralpoint" );
1412 else if ( mPlacement == CurvePoint )
1413 map[QStringLiteral(
"placement" )] = QStringLiteral(
"curvepoint" );
1415 map[QStringLiteral(
"placement" )] = QStringLiteral(
"interval" );
1417 map[QStringLiteral(
"ring_filter" )] = QString::number( static_cast< int >(
mRingFilter ) );
1423 return mMarker.get();
1434 mMarker.reset( static_cast<QgsMarkerSymbol *>( symbol ) );
1435 mColor = mMarker->color();
1460 for (
int i = 0; i < mMarker->symbolLayerCount(); i++ )
1462 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:LineSymbolizer" ) );
1463 if ( !props.value( QStringLiteral(
"uom" ), QString() ).isEmpty() )
1464 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ) );
1465 element.appendChild( symbolizerElem );
1471 switch ( mPlacement )
1492 if ( !mRotateMarker )
1500 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
1501 symbolizerElem.appendChild( strokeElem );
1504 QDomElement graphicStrokeElem = doc.createElement( QStringLiteral(
"se:GraphicStroke" ) );
1505 strokeElem.appendChild( graphicStrokeElem );
1511 graphicStrokeElem.appendChild( doc.createComment( QStringLiteral(
"MarkerSymbolLayerV2 expected, %1 found. Skip it." ).arg( layer->
layerType() ) ) );
1518 if ( !gap.isEmpty() )
1520 QDomElement gapElem = doc.createElement( QStringLiteral(
"se:Gap" ) );
1522 graphicStrokeElem.appendChild( gapElem );
1527 QDomElement perpOffsetElem = doc.createElement( QStringLiteral(
"se:PerpendicularOffset" ) );
1529 perpOffsetElem.appendChild( doc.createTextNode(
qgsDoubleToString( offset ) ) );
1530 symbolizerElem.appendChild( perpOffsetElem );
1539 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1540 if ( strokeElem.isNull() )
1543 QDomElement graphicStrokeElem = strokeElem.firstChildElement( QStringLiteral(
"GraphicStroke" ) );
1544 if ( graphicStrokeElem.isNull() )
1548 bool rotateMarker =
true;
1552 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
1554 if ( it.key() == QLatin1String(
"placement" ) )
1556 if ( it.value() == QLatin1String(
"points" ) ) placement = Vertex;
1557 else if ( it.value() == QLatin1String(
"firstPoint" ) ) placement = FirstVertex;
1558 else if ( it.value() == QLatin1String(
"lastPoint" ) ) placement = LastVertex;
1559 else if ( it.value() == QLatin1String(
"centralPoint" ) ) placement = CentralPoint;
1561 else if ( it.value() == QLatin1String(
"rotateMarker" ) )
1563 rotateMarker = it.value() == QLatin1String(
"0" );
1567 std::unique_ptr< QgsMarkerSymbol > marker;
1580 double interval = 0.0;
1581 QDomElement gapElem = graphicStrokeElem.firstChildElement( QStringLiteral(
"Gap" ) );
1582 if ( !gapElem.isNull() )
1585 double d = gapElem.firstChild().nodeValue().toDouble( &ok );
1591 QDomElement perpOffsetElem = graphicStrokeElem.firstChildElement( QStringLiteral(
"PerpendicularOffset" ) );
1592 if ( !perpOffsetElem.isNull() )
1595 double d = perpOffsetElem.firstChild().nodeValue().toDouble( &ok );
1600 QString uom = element.attribute( QStringLiteral(
"uom" ) );
1615 mMarker->setSize( width );
1622 mMarker->setDataDefinedSize( property );
1629 return mMarker->size();
1634 return mMarker->size( context );
1640 mMarker->setOutputUnit( unit );
1641 mIntervalUnit = unit;
1643 mOffsetAlongLineUnit = unit;
1649 if ( mIntervalUnit != unit ||
mOffsetUnit != unit || mOffsetAlongLineUnit != unit )
1659 mIntervalMapUnitScale = scale;
1661 mOffsetAlongLineMapUnitScale = scale;
1679 attr.unite( mMarker->usedAttributes( context ) );
1687 if ( mMarker && mMarker->hasDataDefinedProperties() )
1694 return ( mMarker->size( context ) / 2.0 ) +
QgsUnitTypes::RenderUnit widthUnit() const
Returns the units for the line's width.
void renderPolygonStroke(const QPolygonF &points, QList< QPolygonF > *rings, QgsSymbolRenderContext &context) override
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
const QgsCurve * exteriorRing() const
Returns the curve polygon's exterior ring.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
Single variable definition for use within a QgsExpressionContextScope.
void setMapUnitScale(const QgsMapUnitScale &scale) override
double dxfOffset(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets offset.
float threshold() const
Gets the simplification threshold of the vector layer managed.
void setMapUnitScale(const QgsMapUnitScale &scale) override
static QDomElement createVendorOptionElement(QDomDocument &doc, const QString &name, const QString &value)
void renderPolygonStroke(const QPolygonF &points, QList< QPolygonF > *rings, QgsSymbolRenderContext &context) override
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
static const QString EXPR_GEOMETRY_POINT_COUNT
Inbuilt variable name for point count variable.
double symbologyScale() const
Returns the reference scale for output.
Abstract base class for all rendered symbols.
void setUseCustomDashPattern(bool b)
virtual bool hasCurvedSegments() const
Returns true if the geometry contains curved segments.
QColor selectionColor() const
Returns the color to use when rendering selected features.
const QgsVectorSimplifyMethod & vectorSimplifyMethod() const
Added in QGIS v2.4.
bool mUseCustomDashPattern
QgsWkbTypes::GeometryType originalGeometryType() const
Returns the geometry type for the original feature geometry being rendered.
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const override
double convertToPainterUnits(double size, QgsUnitTypes::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale()) const
Converts a size from the specified units to painter units (pixels).
static QgsSymbolLayer * createFromSld(QDomElement &element)
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.
#define DEFAULT_MARKERLINE_INTERVAL
virtual double vertexAngle(QgsVertexId vertex) const =0
Returns approximate angle at a vertex.
Curve polygon geometry type.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
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.
Qt::PenStyle penStyle() const
Qt::PenJoinStyle mPenJoinStyle
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
virtual bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const =0
Returns next vertex id and coordinates.
void clipValueToMapUnitScale(double &value, const QgsMapUnitScale &scale, double pixelToMMFactor) const
Clips value to scale minimum/maximum.
virtual void writeSldMarker(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const
Writes the symbol layer definition as a SLD XML element.
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.
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.
void setWidth(double width) override
void renderPolylineCentral(const QPolygonF &points, QgsSymbolRenderContext &context)
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
void setInterval(double interval)
Sets the interval between individual markers.
static QVector< qreal > decodeRealVector(const QString &s)
void setCustomDashPatternUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for lengths used in the custom dash pattern.
static QString encodeColor(const QColor &color)
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
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.
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.
void transformInPlace(double &x, double &y) const
Transform device coordinates to map coordinates.
Placement
Defines how/where the marker should be placed on the line.
Qt::PenCapStyle mPenCapStyle
QgsMapUnitScale mapUnitScale() const override
virtual bool setSubSymbol(QgsSymbol *symbol)
Sets layer's subsymbol. takes ownership of the passed symbol.
QgsUnitTypes::DistanceUnit mapUnits() const
Retrieve map units.
void setPlacement(Placement p)
The placement of the markers.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void renderPolylineInterval(const QPolygonF &points, QgsSymbolRenderContext &context)
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
Create a new MarkerLineSymbolLayerV2.
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'...
bool renderingStopped() const
Returns TRUE if the rendering operation has been stopped and any ongoing rendering should be canceled...
static QgsStringMap getVendorOptionList(QDomElement &element)
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties...
Render the interior rings only.
QString qgsDoubleToString(double a, int precision=17)
Returns a string representation of a double.
void renderPolyline(const QPolygonF &points, QgsSymbolRenderContext &context) override
QgsPropertyCollection & dataDefinedProperties()
Returns a reference to the symbol layer's property collection, used for data defined overrides...
QVector< qreal > customDashVector() const
#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
static QgsSymbolLayer * createMarkerLayerFromSld(QDomElement &element)
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
QgsUnitTypes::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QList< QgsSymbolLayer * > QgsSymbolLayerList
#define DEFAULT_SIMPLELINE_COLOR
QgsSimpleLineSymbolLayer(const QColor &color=DEFAULT_SIMPLELINE_COLOR, double width=DEFAULT_SIMPLELINE_WIDTH, Qt::PenStyle penStyle=DEFAULT_SIMPLELINE_PENSTYLE)
double mapUnitsPerPixel() const
Returns current map units per pixel.
static Qt::PenCapStyle decodePenCapStyle(const QString &str)
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)
Single scope for storing variables and functions for use within a QgsExpressionContext.
A store for object properties.
QgsMapUnitScale mWidthMapUnitScale
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
void setOffsetAlongLineMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale used for calculating the offset in map units along line for markers...
void setIntervalMapUnitScale(const QgsMapUnitScale &scale)
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.
static QgsSymbolLayer * create(const QgsStringMap &properties=QgsStringMap())
void setMapUnitScale(const QgsMapUnitScale &scale) override
double width() const override
Returns the estimated width for the line symbol layer.
void renderPolylineVertex(const QPolygonF &points, QgsSymbolRenderContext &context, Placement placement=Vertex)
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...
void setOffsetAlongLineUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit used for calculating the offset along line for markers.
Qt::PenJoinStyle penJoinStyle() const
static void createGeometryElement(QDomDocument &doc, QDomElement &element, const QString &geomFunc)
QgsFields fields() const
Fields of the layer.
static Q_INVOKABLE QString encodeUnit(QgsUnitTypes::DistanceUnit unit)
Encodes a distance unit to a string.
void setPenCapStyle(Qt::PenCapStyle style)
QgsExpressionContext & expressionContext()
Gets the expression context.
qreal opacity() const
Returns the opacity for the symbol.
double dxfWidth(const QgsDxfExport &e, QgsSymbolRenderContext &context) const override
Gets line width.
QgsStringMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
#define DEFAULT_SIMPLELINE_WIDTH
virtual double width() const
Returns the estimated width for the line symbol layer.
void setOutputUnit(QgsUnitTypes::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
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 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)
Contains information about the context of a rendering operation.
Abstract base class for marker symbol layers.
void startRender(QgsSymbolRenderContext &context) override
QgsSimpleLineSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QPainter * painter()
Returns the destination QPainter for the render operation.
double markerAngle(const QPolygonF &points, bool isRing, int vertex)
RenderRingFilter mRingFilter
void startRender(QgsSymbolRenderContext &context) override
Struct for storing maximum and minimum scales for measurements in map units.
void setCustomDashPatternMapUnitScale(const QgsMapUnitScale &scale)
const QgsAbstractGeometry * geometry() const
Returns pointer to the unsegmentized geometry.
void setWidthMapUnitScale(const QgsMapUnitScale &scale)
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
const QgsCurve * interiorRing(int i) const
Retrieves an interior ring from the curve polygon.
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
QgsUnitTypes::RenderUnit mWidthUnit
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
void setIntervalUnit(QgsUnitTypes::RenderUnit unit)
Sets the units for the interval between markers.
void setOffsetUnit(QgsUnitTypes::RenderUnit unit)
Sets the units 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.
const QgsFeature * feature() const
Current feature being rendered - may be null.
SimplifyHints simplifyHints() const
Gets the simplification hints of the vector layer managed.
SymbolType type() const
Returns the symbol's type.
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)
void setCustomDashVector(const QVector< qreal > &vector)
QVector< qreal > mCustomDashVector
Vector with an even number of entries for the.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QgsUnitTypes::RenderUnit mCustomDashPatternUnit
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)
QgsMapUnitScale mCustomDashPatternMapUnitScale
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties...
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
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)
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the line's offset.
void setOffsetAlongLine(double offsetAlongLine)
Sets the the offset along the line for the marker placement.
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
static QString encodePenCapStyle(Qt::PenCapStyle style)
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
Qt::PenCapStyle penCapStyle() const
static QgsSymbolLayer * createFromSld(QDomElement &element)
Create a new MarkerLineSymbolLayerV2 from SLD.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
QVector< qreal > dxfCustomDashPattern(QgsUnitTypes::RenderUnit &unit) const override
Gets dash pattern.
QgsMapUnitScale mapUnitScale() const override
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.
virtual QColor color() const
The fill color.
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.
QColor dxfColor(QgsSymbolRenderContext &context) const override
Gets color.
Qt::PenStyle dxfPenStyle() const override
Gets pen style.
#define DEFAULT_MARKERLINE_ROTATE
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
QgsPropertyCollection mDataDefinedProperties
QColor color() const override
The fill color.
QgsMapUnitScale mapUnitScale() const override
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 setPenJoinStyle(Qt::PenJoinStyle style)
void setOffset(double offset)
virtual QString layerType() const =0
Returns a string that represents this layer type.