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 = scaledWidth;
204 QStringList versionSplit = QString( qVersion() ).split(
'.' );
205 if ( versionSplit.size() > 1
206 && versionSplit.at( 1 ).toInt() >= 8
207 && scaledWidth < 1.0 )
211 QVector<qreal> scaledVector;
218 mPen.setDashPattern( scaledVector );
230 selColor.setAlphaF( context.
opacity() );
258 QPainterPath clipPath;
259 clipPath.addPolygon( points );
264 QList<QPolygonF>::const_iterator it = rings->constBegin();
265 for ( ; it != rings->constEnd(); ++it )
267 QPolygonF ring = *it;
268 clipPath.addPolygon( ring );
273 p->setClipPath( clipPath, Qt::IntersectClip );
292 for (
const QPolygonF &ring : qgis::as_const( *rings ) )
319 applyDataDefinedSymbology( context,
mPen,
mSelPen, offset );
322 p->setBrush( Qt::NoBrush );
325 if ( points.size() <= 2 &&
328 ( p->renderHints() & QPainter::Antialiasing ) )
330 p->setRenderHint( QPainter::Antialiasing,
false );
332 p->drawPolyline( points );
335 path.addPolygon( points );
338 p->setRenderHint( QPainter::Antialiasing,
true );
345 p->drawPolyline( points );
348 path.addPolygon( points );
356 for (
int part = 0; part < mline.count(); ++part )
359 p->drawPolyline( mline );
362 path.addPolygon( mline[ part ] );
373 map[QStringLiteral(
"line_width" )] = QString::number(
mWidth );
379 map[QStringLiteral(
"offset" )] = QString::number(
mOffset );
382 map[QStringLiteral(
"use_custom_dash" )] = (
mUseCustomDashPattern ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
386 map[QStringLiteral(
"draw_inside_polygon" )] = (
mDrawInsidePolygon ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
387 map[QStringLiteral(
"ring_filter" )] = QString::number( static_cast< int >(
mRingFilter ) );
417 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:LineSymbolizer" ) );
418 if ( !props.value( QStringLiteral(
"uom" ), QString() ).isEmpty() )
419 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ) );
420 element.appendChild( symbolizerElem );
426 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
427 symbolizerElem.appendChild( strokeElem );
438 QDomElement perpOffsetElem = doc.createElement( QStringLiteral(
"se:PerpendicularOffset" ) );
441 symbolizerElem.appendChild( perpOffsetElem );
464 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
465 if ( strokeElem.isNull() )
477 &penJoinStyle, &penCapStyle,
478 &customDashVector ) )
482 QDomElement perpOffsetElem = element.firstChildElement( QStringLiteral(
"PerpendicularOffset" ) );
483 if ( !perpOffsetElem.isNull() )
486 double d = perpOffsetElem.firstChild().nodeValue().toDouble( &ok );
491 QString uom = element.attribute( QStringLiteral(
"uom" ) );
511 bool hasStrokeWidthExpression =
false;
518 pen.setWidthF( scaledWidth );
519 selPen.setWidthF( scaledWidth );
520 hasStrokeWidthExpression =
true;
541 double dashWidthDiv =
mPen.widthF();
543 if ( hasStrokeWidthExpression )
545 dashWidthDiv = pen.widthF();
546 scaledWidth = pen.widthF();
550 QStringList versionSplit = QString( qVersion() ).split(
'.' );
551 if ( versionSplit.size() > 1
552 && versionSplit.at( 1 ).toInt() >= 8
553 && scaledWidth < 1.0 )
558 QVector<qreal> dashVector;
560 if ( exprVal.isValid() )
562 QStringList dashList = exprVal.toString().split(
';' );
563 QStringList::const_iterator dashIt = dashList.constBegin();
564 for ( ; dashIt != dashList.constEnd(); ++dashIt )
568 pen.setDashPattern( dashVector );
577 if ( exprVal.isValid() )
586 if ( exprVal.isValid() )
595 if ( exprVal.isValid() )
678 MyLine( QPointF p1, QPointF p2 )
680 , mIncreasing(
false )
692 mIncreasing = ( p2.y() > p1.y() );
697 mT = float( p2.y() - p1.y() ) / ( p2.x() - p1.x() );
698 mIncreasing = ( p2.x() > p1.x() );
702 double x = ( p2.x() - p1.x() );
703 double y = ( p2.y() - p1.y() );
704 mLength = std::sqrt( x * x + y * y );
710 double a = ( mVertical ? M_PI_2 : std::atan( mT ) );
718 QPointF diffForInterval(
double interval )
721 return ( mIncreasing ? QPointF( 0, interval ) : QPointF( 0, -interval ) );
723 double alpha = std::atan( mT );
724 double dx = std::cos( alpha ) * interval;
725 double dy = std::sin( alpha ) * interval;
726 return ( mIncreasing ? QPointF( dx, dy ) : QPointF( -dx, -dy ) );
729 double length() {
return mLength; }
742 mRotateMarker = rotateMarker;
743 mInterval = interval;
746 mPlacement = Interval;
747 mOffsetAlongLine = 0;
759 if ( props.contains( QStringLiteral(
"interval" ) ) )
760 interval = props[QStringLiteral(
"interval" )].toDouble();
761 if ( props.contains( QStringLiteral(
"rotate" ) ) )
762 rotate = ( props[QStringLiteral(
"rotate" )] == QLatin1String(
"1" ) );
765 if ( props.contains( QStringLiteral(
"offset" ) ) )
767 x->
setOffset( props[QStringLiteral(
"offset" )].toDouble() );
769 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
773 if ( props.contains( QStringLiteral(
"interval_unit" ) ) )
777 if ( props.contains( QStringLiteral(
"offset_along_line" ) ) )
781 if ( props.contains( QStringLiteral(
"offset_along_line_unit" ) ) )
785 if ( props.contains( ( QStringLiteral(
"offset_along_line_map_unit_scale" ) ) ) )
790 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
794 if ( props.contains( QStringLiteral(
"interval_map_unit_scale" ) ) )
799 if ( props.contains( QStringLiteral(
"placement" ) ) )
801 if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"vertex" ) )
803 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"lastvertex" ) )
805 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"firstvertex" ) )
807 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"centralpoint" ) )
809 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"curvepoint" ) )
815 if ( props.contains( QStringLiteral(
"ring_filter" ) ) )
817 x->
setRingFilter( static_cast< RenderRingFilter>( props[QStringLiteral(
"ring_filter" )].toInt() ) );
827 return QStringLiteral(
"MarkerLine" );
832 mMarker->setColor( color );
838 return mMarker ? mMarker->color() :
mColor;
843 mMarker->setOpacity( context.
opacity() );
846 QgsSymbol::RenderHints hints =
nullptr;
849 mMarker->setRenderHints( hints );
874 if ( exprVal.isValid() )
876 QString placementString = exprVal.toString();
877 if ( placementString.compare( QLatin1String(
"interval" ), Qt::CaseInsensitive ) == 0 )
879 placement = Interval;
881 else if ( placementString.compare( QLatin1String(
"vertex" ), Qt::CaseInsensitive ) == 0 )
885 else if ( placementString.compare( QLatin1String(
"lastvertex" ), Qt::CaseInsensitive ) == 0 )
887 placement = LastVertex;
889 else if ( placementString.compare( QLatin1String(
"firstvertex" ), Qt::CaseInsensitive ) == 0 )
891 placement = FirstVertex;
893 else if ( placementString.compare( QLatin1String(
"centerpoint" ), Qt::CaseInsensitive ) == 0 )
895 placement = CentralPoint;
897 else if ( placementString.compare( QLatin1String(
"curvepoint" ), Qt::CaseInsensitive ) == 0 )
899 placement = CurvePoint;
903 placement = Interval;
913 if ( placement == Interval )
914 renderPolylineInterval( points, context );
915 else if ( placement == CentralPoint )
916 renderPolylineCentral( points, context );
918 renderPolylineVertex( points, context, placement );
925 for (
int part = 0; part < mline.count(); ++part )
927 const QPolygonF &points2 = mline[ part ];
929 if ( placement == Interval )
930 renderPolylineInterval( points2, context );
931 else if ( placement == CentralPoint )
932 renderPolylineCentral( points2, context );
934 renderPolylineVertex( points2, context, placement );
968 for (
int i = 0; i < rings->size(); ++i )
987 if ( points.isEmpty() )
990 QPointF lastPt = points[0];
991 double lengthLeft = 0;
994 double interval = mInterval;
1004 if ( interval <= 0 )
1008 double offsetAlongLine = mOffsetAlongLine;
1015 double painterUnitInterval = rc.
convertToPainterUnits( interval, mIntervalUnit, mIntervalMapUnitScale );
1016 lengthLeft = painterUnitInterval - rc.
convertToPainterUnits( offsetAlongLine, mIntervalUnit, mIntervalMapUnitScale );
1019 for (
int i = 1; i < points.count(); ++i )
1021 const QPointF &pt = points[i];
1027 MyLine l( lastPt, pt );
1028 QPointF diff = l.diffForInterval( painterUnitInterval );
1032 double c = 1 - lengthLeft / painterUnitInterval;
1034 lengthLeft += l.length();
1037 if ( mRotateMarker )
1039 mMarker->setLineAngle( l.angle() * 180 / M_PI );
1044 while ( lengthLeft > painterUnitInterval )
1048 lengthLeft -= painterUnitInterval;
1050 mMarker->renderPoint( lastPt, context.
feature(), rc, -1, context.
selected() );
1060 static double _averageAngle( QPointF prevPt, QPointF pt, QPointF nextPt )
1063 double a1 = MyLine( prevPt, pt ).angle();
1064 double a2 = MyLine( pt, nextPt ).angle();
1065 double unitX = std::cos( a1 ) + std::cos( a2 ), unitY = std::sin( a1 ) + std::sin( a2 );
1067 return std::atan2( unitY, unitX );
1072 if ( points.isEmpty() )
1077 double origAngle = mMarker->angle();
1079 bool isRing =
false;
1085 double offsetAlongLine = mOffsetAlongLine;
1094 offsetAlongLine = rc.
convertToPainterUnits( offsetAlongLine, mOffsetAlongLineUnit, mOffsetAlongLineMapUnitScale );
1126 if ( mRotateMarker )
1129 mMarker->setAngle( angle * 180 / M_PI );
1131 mMarker->renderPoint( mapPoint, context.
feature(), rc, -1, context.
selected() );
1139 if ( placement == FirstVertex )
1144 else if ( placement == LastVertex )
1146 i = points.count() - 1;
1147 maxCount = points.count();
1149 else if ( placement == Vertex )
1152 maxCount = points.count();
1153 if ( points.first() == points.last() )
1162 if ( offsetAlongLine > 0 && ( placement == FirstVertex || placement == LastVertex ) )
1165 distance = placement == FirstVertex ? offsetAlongLine : -offsetAlongLine;
1166 renderOffsetVertexAlongLine( points, i, distance, context );
1168 mMarker->setAngle( origAngle );
1175 for ( ; i < maxCount; ++i )
1179 if ( isRing && placement == Vertex && i == points.count() - 1 )
1184 if ( mRotateMarker )
1186 double angle = markerAngle( points, isRing, i );
1187 mMarker->setAngle( origAngle + angle * 180 / M_PI );
1190 mMarker->renderPoint( points.at( i ), context.
feature(), rc, -1, context.
selected() );
1194 mMarker->setAngle( origAngle );
1202 const QPointF &pt = points[vertex];
1204 if ( isRing || ( vertex > 0 && vertex < points.count() - 1 ) )
1206 int prevIndex = vertex - 1;
1207 int nextIndex = vertex + 1;
1209 if ( isRing && ( vertex == 0 || vertex == points.count() - 1 ) )
1211 prevIndex = points.count() - 2;
1215 QPointF prevPoint, nextPoint;
1216 while ( prevIndex >= 0 )
1218 prevPoint = points[ prevIndex ];
1219 if ( prevPoint != pt )
1226 while ( nextIndex < points.count() )
1228 nextPoint = points[ nextIndex ];
1229 if ( nextPoint != pt )
1236 if ( prevIndex >= 0 && nextIndex < points.count() )
1238 angle = _averageAngle( prevPoint, pt, nextPoint );
1245 while ( vertex < points.size() - 1 )
1247 const QPointF &nextPt = points[vertex + 1];
1250 angle = MyLine( pt, nextPt ).angle();
1259 while ( vertex >= 1 )
1261 const QPointF &prevPt = points[vertex - 1];
1264 angle = MyLine( prevPt, pt ).angle();
1274 void QgsMarkerLineSymbolLayer::renderOffsetVertexAlongLine(
const QPolygonF &points,
int vertex,
double distance,
QgsSymbolRenderContext &context )
1276 if ( points.isEmpty() )
1280 double origAngle = mMarker->angle();
1284 if ( mRotateMarker )
1286 bool isRing =
false;
1287 if ( points.first() == points.last() )
1289 double angle = markerAngle( points, isRing, vertex );
1290 mMarker->setAngle( origAngle + angle * 180 / M_PI );
1292 mMarker->renderPoint( points[vertex], context.
feature(), rc, -1, context.
selected() );
1296 int pointIncrement = distance > 0 ? 1 : -1;
1297 QPointF previousPoint = points[vertex];
1298 int startPoint = distance > 0 ? std::min( vertex + 1, points.count() - 1 ) : std::max( vertex - 1, 0 );
1299 int endPoint = distance > 0 ? points.count() - 1 : 0;
1300 double distanceLeft = std::fabs( distance );
1302 for (
int i = startPoint; pointIncrement > 0 ? i <= endPoint : i >= endPoint; i += pointIncrement )
1304 const QPointF &pt = points[i];
1306 if ( previousPoint == pt )
1310 MyLine l( previousPoint, pt );
1312 if ( distanceLeft < l.length() )
1315 QPointF markerPoint = previousPoint + l.diffForInterval( distanceLeft );
1317 if ( mRotateMarker )
1319 mMarker->setAngle( origAngle + ( l.angle() * 180 / M_PI ) );
1321 mMarker->renderPoint( markerPoint, context.
feature(), rc, -1, context.
selected() );
1325 distanceLeft -= l.length();
1334 if ( !points.isEmpty() )
1338 QPolygonF::const_iterator it = points.constBegin();
1340 for ( ++it; it != points.constEnd(); ++it )
1342 length += std::sqrt( ( last.x() - it->x() ) * ( last.x() - it->x() ) +
1343 ( last.y() - it->y() ) * ( last.y() - it->y() ) );
1348 it = points.constBegin();
1350 qreal last_at = 0, next_at = 0;
1353 for ( ++it; it != points.constEnd(); ++it )
1356 next_at += std::sqrt( ( last.x() - it->x() ) * ( last.x() - it->x() ) +
1357 ( last.y() - it->y() ) * ( last.y() - it->y() ) );
1358 if ( next_at >= length / 2 )
1366 MyLine l( last, next );
1367 qreal k = ( length * 0.5 - last_at ) / ( next_at - last_at );
1368 QPointF pt = last + ( next - last ) * k;
1371 double origAngle = mMarker->angle();
1372 if ( mRotateMarker )
1373 mMarker->setAngle( origAngle + l.angle() * 180 / M_PI );
1375 if ( mRotateMarker )
1376 mMarker->setAngle( origAngle );
1384 map[QStringLiteral(
"rotate" )] = ( mRotateMarker ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
1385 map[QStringLiteral(
"interval" )] = QString::number( mInterval );
1386 map[QStringLiteral(
"offset" )] = QString::number(
mOffset );
1387 map[QStringLiteral(
"offset_along_line" )] = QString::number( mOffsetAlongLine );
1394 if ( mPlacement == Vertex )
1395 map[QStringLiteral(
"placement" )] = QStringLiteral(
"vertex" );
1396 else if ( mPlacement == LastVertex )
1397 map[QStringLiteral(
"placement" )] = QStringLiteral(
"lastvertex" );
1398 else if ( mPlacement == FirstVertex )
1399 map[QStringLiteral(
"placement" )] = QStringLiteral(
"firstvertex" );
1400 else if ( mPlacement == CentralPoint )
1401 map[QStringLiteral(
"placement" )] = QStringLiteral(
"centralpoint" );
1402 else if ( mPlacement == CurvePoint )
1403 map[QStringLiteral(
"placement" )] = QStringLiteral(
"curvepoint" );
1405 map[QStringLiteral(
"placement" )] = QStringLiteral(
"interval" );
1407 map[QStringLiteral(
"ring_filter" )] = QString::number( static_cast< int >(
mRingFilter ) );
1413 return mMarker.get();
1424 mMarker.reset( static_cast<QgsMarkerSymbol *>( symbol ) );
1425 mColor = mMarker->color();
1450 for (
int i = 0; i < mMarker->symbolLayerCount(); i++ )
1452 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:LineSymbolizer" ) );
1453 if ( !props.value( QStringLiteral(
"uom" ), QString() ).isEmpty() )
1454 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QString() ) );
1455 element.appendChild( symbolizerElem );
1461 switch ( mPlacement )
1482 if ( !mRotateMarker )
1490 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
1491 symbolizerElem.appendChild( strokeElem );
1494 QDomElement graphicStrokeElem = doc.createElement( QStringLiteral(
"se:GraphicStroke" ) );
1495 strokeElem.appendChild( graphicStrokeElem );
1501 graphicStrokeElem.appendChild( doc.createComment( QStringLiteral(
"MarkerSymbolLayerV2 expected, %1 found. Skip it." ).arg( layer->
layerType() ) ) );
1508 if ( !gap.isEmpty() )
1510 QDomElement gapElem = doc.createElement( QStringLiteral(
"se:Gap" ) );
1512 graphicStrokeElem.appendChild( gapElem );
1517 QDomElement perpOffsetElem = doc.createElement( QStringLiteral(
"se:PerpendicularOffset" ) );
1519 perpOffsetElem.appendChild( doc.createTextNode(
qgsDoubleToString( offset ) ) );
1520 symbolizerElem.appendChild( perpOffsetElem );
1529 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1530 if ( strokeElem.isNull() )
1533 QDomElement graphicStrokeElem = strokeElem.firstChildElement( QStringLiteral(
"GraphicStroke" ) );
1534 if ( graphicStrokeElem.isNull() )
1538 bool rotateMarker =
true;
1542 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
1544 if ( it.key() == QLatin1String(
"placement" ) )
1546 if ( it.value() == QLatin1String(
"points" ) ) placement = Vertex;
1547 else if ( it.value() == QLatin1String(
"firstPoint" ) ) placement = FirstVertex;
1548 else if ( it.value() == QLatin1String(
"lastPoint" ) ) placement = LastVertex;
1549 else if ( it.value() == QLatin1String(
"centralPoint" ) ) placement = CentralPoint;
1551 else if ( it.value() == QLatin1String(
"rotateMarker" ) )
1553 rotateMarker = it.value() == QLatin1String(
"0" );
1557 std::unique_ptr< QgsMarkerSymbol > marker;
1570 double interval = 0.0;
1571 QDomElement gapElem = graphicStrokeElem.firstChildElement( QStringLiteral(
"Gap" ) );
1572 if ( !gapElem.isNull() )
1575 double d = gapElem.firstChild().nodeValue().toDouble( &ok );
1581 QDomElement perpOffsetElem = graphicStrokeElem.firstChildElement( QStringLiteral(
"PerpendicularOffset" ) );
1582 if ( !perpOffsetElem.isNull() )
1585 double d = perpOffsetElem.firstChild().nodeValue().toDouble( &ok );
1590 QString uom = element.attribute( QStringLiteral(
"uom" ) );
1605 mMarker->setSize( width );
1612 mMarker->setDataDefinedSize( property );
1619 return mMarker->size();
1624 return mMarker->size( context );
1630 mMarker->setOutputUnit( unit );
1631 mIntervalUnit = unit;
1633 mOffsetAlongLineUnit = unit;
1639 if ( mIntervalUnit != unit ||
mOffsetUnit != unit || mOffsetAlongLineUnit != unit )
1649 mIntervalMapUnitScale = scale;
1651 mOffsetAlongLineMapUnitScale = scale;
1669 attr.unite( mMarker->usedAttributes( context ) );
1677 if ( mMarker && mMarker->hasDataDefinedProperties() )
1684 return ( mMarker->size( context ) / 2.0 ) +
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.
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...
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.
double symbologyScale() const
Returns the reference scale for output.
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
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
const QgsVectorSimplifyMethod & vectorSimplifyMethod() const
Added in QGIS v2.4.
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)
bool mUseCustomDashPattern
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const override
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.
const QgsCurve * interiorRing(int i) const
Retrieves an interior ring from the curve polygon.
#define DEFAULT_MARKERLINE_INTERVAL
virtual double vertexAngle(QgsVertexId vertex) const =0
Returns approximate angle at a vertex.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
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::PenJoinStyle mPenJoinStyle
QgsUnitTypes::DistanceUnit mapUnits() const
Retrieve map units.
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
QgsUnitTypes::RenderUnit offsetUnit() const
Returns the units for the line's offset.
virtual bool nextVertex(QgsVertexId &id, QgsPoint &vertex) const =0
Returns next vertex id and coordinates.
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.
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.
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)
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties...
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
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.
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.
void setPlacement(Placement p)
The placement of the markers.
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.
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
static QgsStringMap getVendorOptionList(QDomElement &element)
qreal opacity() const
Returns the opacity for the symbol.
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.
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...
#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
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.
float threshold() const
Gets the simplification threshold of the vector layer managed.
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)
QgsCoordinateTransform coordinateTransform() const
Returns the current coordinate transform for the context.
static Qt::PenCapStyle decodePenCapStyle(const QString &str)
Qt::PenJoinStyle penJoinStyle() const
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.
double mapUnitsPerPixel() const
Returns current map units per pixel.
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)
void setOffsetAlongLineUnit(QgsUnitTypes::RenderUnit unit)
Sets the unit used for calculating the offset along line for markers.
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 setPenCapStyle(Qt::PenCapStyle style)
QgsExpressionContext & expressionContext()
Gets the expression context.
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
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.
Contains information about the context of a rendering operation.
Abstract base class for marker symbol layers.
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.
QPainter * painter()
Returns the destination QPainter for the render operation.
const QgsMapToPixel & mapToPixel() const
double markerAngle(const QPolygonF &points, bool isRing, int vertex)
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)
void setWidthMapUnitScale(const QgsMapUnitScale &scale)
Qt::PenStyle penStyle() const
void appendScope(QgsExpressionContextScope *scope)
Appends a scope to the end of the context.
QgsUnitTypes::RenderUnit mWidthUnit
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
const QgsFeature * feature() const
Current feature being rendered - may be null.
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.
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)
void setCustomDashVector(const QVector< qreal > &vector)
QVector< qreal > mCustomDashVector
Vector with an even number of entries for the.
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...
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 setOffsetAlongLine(double offsetAlongLine)
Sets the the offset along the line for the marker placement.
static QString encodePenCapStyle(Qt::PenCapStyle style)
QgsExpressionContextScope * popScope()
Removes the last scope from the expression context and return it.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Create a new MarkerLineSymbolLayerV2 from SLD.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
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
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
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.
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 copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
void setPenJoinStyle(Qt::PenJoinStyle style)
void setOffset(double offset)
virtual QString layerType() const =0
Returns a string that represents this layer type.