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" ) ) )
182 return QStringLiteral(
"SimpleLine" );
189 mPen.setColor( penColor );
191 mPen.setWidthF( scaledWidth );
194 mPen.setStyle( Qt::CustomDashLine );
197 double dashWidthDiv = scaledWidth;
199 QStringList versionSplit = QString( qVersion() ).split(
'.' );
200 if ( versionSplit.size() > 1
201 && versionSplit.at( 1 ).toInt() >= 8
202 && scaledWidth < 1.0 )
206 QVector<qreal> scaledVector;
213 mPen.setDashPattern( scaledVector );
225 selColor.setAlphaF( context.
opacity() );
246 QPainterPath clipPath;
247 clipPath.addPolygon( points );
252 QList<QPolygonF>::const_iterator it = rings->constBegin();
253 for ( ; it != rings->constEnd(); ++it )
255 QPolygonF ring = *it;
256 clipPath.addPolygon( ring );
261 p->setClipPath( clipPath, Qt::IntersectClip );
268 Q_FOREACH (
const QPolygonF &ring, *rings )
290 applyDataDefinedSymbology( context,
mPen,
mSelPen, offset );
293 p->setBrush( Qt::NoBrush );
296 if ( points.size() <= 2 &&
299 ( p->renderHints() & QPainter::Antialiasing ) )
301 p->setRenderHint( QPainter::Antialiasing,
false );
303 p->drawPolyline( points );
306 path.addPolygon( points );
309 p->setRenderHint( QPainter::Antialiasing,
true );
316 p->drawPolyline( points );
319 path.addPolygon( points );
327 for (
int part = 0; part < mline.count(); ++part )
330 p->drawPolyline( mline );
333 path.addPolygon( mline[ part ] );
344 map[QStringLiteral(
"line_width" )] = QString::number(
mWidth );
350 map[QStringLiteral(
"offset" )] = QString::number(
mOffset );
353 map[QStringLiteral(
"use_custom_dash" )] = (
mUseCustomDashPattern ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
357 map[QStringLiteral(
"draw_inside_polygon" )] = (
mDrawInsidePolygon ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
386 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:LineSymbolizer" ) );
387 if ( !props.value( QStringLiteral(
"uom" ), QLatin1String(
"" ) ).isEmpty() )
388 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QLatin1String(
"" ) ) );
389 element.appendChild( symbolizerElem );
395 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
396 symbolizerElem.appendChild( strokeElem );
407 QDomElement perpOffsetElem = doc.createElement( QStringLiteral(
"se:PerpendicularOffset" ) );
410 symbolizerElem.appendChild( perpOffsetElem );
433 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
434 if ( strokeElem.isNull() )
446 &penJoinStyle, &penCapStyle,
447 &customDashVector ) )
451 QDomElement perpOffsetElem = element.firstChildElement( QStringLiteral(
"PerpendicularOffset" ) );
452 if ( !perpOffsetElem.isNull() )
455 double d = perpOffsetElem.firstChild().nodeValue().toDouble( &ok );
460 QString uom = element.attribute( QStringLiteral(
"uom" ) );
480 bool hasStrokeWidthExpression =
false;
487 pen.setWidthF( scaledWidth );
488 selPen.setWidthF( scaledWidth );
489 hasStrokeWidthExpression =
true;
510 double dashWidthDiv =
mPen.widthF();
512 if ( hasStrokeWidthExpression )
514 dashWidthDiv = pen.widthF();
515 scaledWidth = pen.widthF();
519 QStringList versionSplit = QString( qVersion() ).split(
'.' );
520 if ( versionSplit.size() > 1
521 && versionSplit.at( 1 ).toInt() >= 8
522 && scaledWidth < 1.0 )
527 QVector<qreal> dashVector;
529 if ( exprVal.isValid() )
531 QStringList dashList = exprVal.toString().split(
';' );
532 QStringList::const_iterator dashIt = dashList.constBegin();
533 for ( ; dashIt != dashList.constEnd(); ++dashIt )
537 pen.setDashPattern( dashVector );
546 if ( exprVal.isValid() )
555 if ( exprVal.isValid() )
564 if ( exprVal.isValid() )
647 MyLine( QPointF p1, QPointF p2 )
649 , mIncreasing(
false )
661 mIncreasing = ( p2.y() > p1.y() );
666 mT = float( p2.y() - p1.y() ) / ( p2.x() - p1.x() );
667 mIncreasing = ( p2.x() > p1.x() );
671 double x = ( p2.x() - p1.x() );
672 double y = ( p2.y() - p1.y() );
673 mLength = std::sqrt( x * x + y * y );
679 double a = ( mVertical ? M_PI_2 : std::atan( mT ) );
687 QPointF diffForInterval(
double interval )
690 return ( mIncreasing ? QPointF( 0, interval ) : QPointF( 0, -interval ) );
692 double alpha = std::atan( mT );
693 double dx = std::cos( alpha ) * interval;
694 double dy = std::sin( alpha ) * interval;
695 return ( mIncreasing ? QPointF( dx, dy ) : QPointF( -dx, -dy ) );
698 double length() {
return mLength; }
711 mRotateMarker = rotateMarker;
712 mInterval = interval;
715 mPlacement = Interval;
716 mOffsetAlongLine = 0;
728 if ( props.contains( QStringLiteral(
"interval" ) ) )
729 interval = props[QStringLiteral(
"interval" )].toDouble();
730 if ( props.contains( QStringLiteral(
"rotate" ) ) )
731 rotate = ( props[QStringLiteral(
"rotate" )] == QLatin1String(
"1" ) );
734 if ( props.contains( QStringLiteral(
"offset" ) ) )
736 x->
setOffset( props[QStringLiteral(
"offset" )].toDouble() );
738 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
742 if ( props.contains( QStringLiteral(
"interval_unit" ) ) )
746 if ( props.contains( QStringLiteral(
"offset_along_line" ) ) )
750 if ( props.contains( QStringLiteral(
"offset_along_line_unit" ) ) )
754 if ( props.contains( ( QStringLiteral(
"offset_along_line_map_unit_scale" ) ) ) )
759 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
763 if ( props.contains( QStringLiteral(
"interval_map_unit_scale" ) ) )
768 if ( props.contains( QStringLiteral(
"placement" ) ) )
770 if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"vertex" ) )
772 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"lastvertex" ) )
774 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"firstvertex" ) )
776 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"centralpoint" ) )
778 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"curvepoint" ) )
791 return QStringLiteral(
"MarkerLine" );
796 mMarker->setColor( color );
802 return mMarker ? mMarker->color() :
mColor;
807 mMarker->setOpacity( context.
opacity() );
810 QgsSymbol::RenderHints hints =
nullptr;
813 mMarker->setRenderHints( hints );
838 if ( exprVal.isValid() )
840 QString placementString = exprVal.toString();
841 if ( placementString.compare( QLatin1String(
"interval" ), Qt::CaseInsensitive ) == 0 )
843 placement = Interval;
845 else if ( placementString.compare( QLatin1String(
"vertex" ), Qt::CaseInsensitive ) == 0 )
849 else if ( placementString.compare( QLatin1String(
"lastvertex" ), Qt::CaseInsensitive ) == 0 )
851 placement = LastVertex;
853 else if ( placementString.compare( QLatin1String(
"firstvertex" ), Qt::CaseInsensitive ) == 0 )
855 placement = FirstVertex;
857 else if ( placementString.compare( QLatin1String(
"centerpoint" ), Qt::CaseInsensitive ) == 0 )
859 placement = CentralPoint;
861 else if ( placementString.compare( QLatin1String(
"curvepoint" ), Qt::CaseInsensitive ) == 0 )
863 placement = CurvePoint;
867 placement = Interval;
877 if ( placement == Interval )
878 renderPolylineInterval( points, context );
879 else if ( placement == CentralPoint )
880 renderPolylineCentral( points, context );
882 renderPolylineVertex( points, context, placement );
889 for (
int part = 0; part < mline.count(); ++part )
891 const QPolygonF &points2 = mline[ part ];
893 if ( placement == Interval )
894 renderPolylineInterval( points2, context );
895 else if ( placement == CentralPoint )
896 renderPolylineCentral( points2, context );
898 renderPolylineVertex( points2, context, placement );
917 for (
int i = 0; i < rings->size(); ++i )
931 if ( points.isEmpty() )
934 QPointF lastPt = points[0];
935 double lengthLeft = 0;
938 double interval = mInterval;
952 double offsetAlongLine = mOffsetAlongLine;
959 double painterUnitInterval = rc.
convertToPainterUnits( interval, mIntervalUnit, mIntervalMapUnitScale );
960 lengthLeft = painterUnitInterval - rc.
convertToPainterUnits( offsetAlongLine, mIntervalUnit, mIntervalMapUnitScale );
963 for (
int i = 1; i < points.count(); ++i )
965 const QPointF &pt = points[i];
971 MyLine l( lastPt, pt );
972 QPointF diff = l.diffForInterval( painterUnitInterval );
976 double c = 1 - lengthLeft / painterUnitInterval;
978 lengthLeft += l.length();
983 mMarker->setLineAngle( l.angle() * 180 / M_PI );
988 while ( lengthLeft > painterUnitInterval )
992 lengthLeft -= painterUnitInterval;
994 mMarker->renderPoint( lastPt, context.
feature(), rc, -1, context.
selected() );
1004 static double _averageAngle( QPointF prevPt, QPointF pt, QPointF nextPt )
1007 double a1 = MyLine( prevPt, pt ).angle();
1008 double a2 = MyLine( pt, nextPt ).angle();
1009 double unitX = std::cos( a1 ) + std::cos( a2 ), unitY = std::sin( a1 ) + std::sin( a2 );
1011 return std::atan2( unitY, unitX );
1016 if ( points.isEmpty() )
1021 double origAngle = mMarker->angle();
1023 bool isRing =
false;
1029 double offsetAlongLine = mOffsetAlongLine;
1038 offsetAlongLine = rc.
convertToPainterUnits( offsetAlongLine, mOffsetAlongLineUnit, mOffsetAlongLineMapUnitScale );
1060 x = vPoint.
x(), y = vPoint.
y();
1069 if ( mRotateMarker )
1072 mMarker->setAngle( angle * 180 / M_PI );
1074 mMarker->renderPoint( mapPoint, context.
feature(), rc, -1, context.
selected() );
1082 if ( placement == FirstVertex )
1087 else if ( placement == LastVertex )
1089 i = points.count() - 1;
1090 maxCount = points.count();
1092 else if ( placement == Vertex )
1095 maxCount = points.count();
1096 if ( points.first() == points.last() )
1105 if ( offsetAlongLine > 0 && ( placement == FirstVertex || placement == LastVertex ) )
1108 distance = placement == FirstVertex ? offsetAlongLine : -offsetAlongLine;
1109 renderOffsetVertexAlongLine( points, i, distance, context );
1111 mMarker->setAngle( origAngle );
1118 for ( ; i < maxCount; ++i )
1122 if ( isRing && placement == Vertex && i == points.count() - 1 )
1127 if ( mRotateMarker )
1129 double angle = markerAngle( points, isRing, i );
1130 mMarker->setAngle( origAngle + angle * 180 / M_PI );
1133 mMarker->renderPoint( points.at( i ), context.
feature(), rc, -1, context.
selected() );
1137 mMarker->setAngle( origAngle );
1145 const QPointF &pt = points[vertex];
1147 if ( isRing || ( vertex > 0 && vertex < points.count() - 1 ) )
1149 int prevIndex = vertex - 1;
1150 int nextIndex = vertex + 1;
1152 if ( isRing && ( vertex == 0 || vertex == points.count() - 1 ) )
1154 prevIndex = points.count() - 2;
1158 QPointF prevPoint, nextPoint;
1159 while ( prevIndex >= 0 )
1161 prevPoint = points[ prevIndex ];
1162 if ( prevPoint != pt )
1169 while ( nextIndex < points.count() )
1171 nextPoint = points[ nextIndex ];
1172 if ( nextPoint != pt )
1179 if ( prevIndex >= 0 && nextIndex < points.count() )
1181 angle = _averageAngle( prevPoint, pt, nextPoint );
1188 while ( vertex < points.size() - 1 )
1190 const QPointF &nextPt = points[vertex + 1];
1193 angle = MyLine( pt, nextPt ).angle();
1202 while ( vertex >= 1 )
1204 const QPointF &prevPt = points[vertex - 1];
1207 angle = MyLine( prevPt, pt ).angle();
1217 void QgsMarkerLineSymbolLayer::renderOffsetVertexAlongLine(
const QPolygonF &points,
int vertex,
double distance,
QgsSymbolRenderContext &context )
1219 if ( points.isEmpty() )
1223 double origAngle = mMarker->angle();
1227 if ( mRotateMarker )
1229 bool isRing =
false;
1230 if ( points.first() == points.last() )
1232 double angle = markerAngle( points, isRing, vertex );
1233 mMarker->setAngle( origAngle + angle * 180 / M_PI );
1235 mMarker->renderPoint( points[vertex], context.
feature(), rc, -1, context.
selected() );
1239 int pointIncrement = distance > 0 ? 1 : -1;
1240 QPointF previousPoint = points[vertex];
1241 int startPoint = distance > 0 ? std::min( vertex + 1, points.count() - 1 ) : std::max( vertex - 1, 0 );
1242 int endPoint = distance > 0 ? points.count() - 1 : 0;
1243 double distanceLeft = std::fabs( distance );
1245 for (
int i = startPoint; pointIncrement > 0 ? i <= endPoint : i >= endPoint; i += pointIncrement )
1247 const QPointF &pt = points[i];
1249 if ( previousPoint == pt )
1253 MyLine l( previousPoint, pt );
1255 if ( distanceLeft < l.length() )
1258 QPointF markerPoint = previousPoint + l.diffForInterval( distanceLeft );
1260 if ( mRotateMarker )
1262 mMarker->setAngle( origAngle + ( l.angle() * 180 / M_PI ) );
1264 mMarker->renderPoint( markerPoint, context.
feature(), rc, -1, context.
selected() );
1268 distanceLeft -= l.length();
1277 if ( !points.isEmpty() )
1281 QPolygonF::const_iterator it = points.constBegin();
1283 for ( ++it; it != points.constEnd(); ++it )
1285 length += std::sqrt( ( last.x() - it->x() ) * ( last.x() - it->x() ) +
1286 ( last.y() - it->y() ) * ( last.y() - it->y() ) );
1291 it = points.constBegin();
1293 qreal last_at = 0, next_at = 0;
1296 for ( ++it; it != points.constEnd(); ++it )
1299 next_at += std::sqrt( ( last.x() - it->x() ) * ( last.x() - it->x() ) +
1300 ( last.y() - it->y() ) * ( last.y() - it->y() ) );
1301 if ( next_at >= length / 2 )
1309 MyLine l( last, next );
1310 qreal k = ( length * 0.5 - last_at ) / ( next_at - last_at );
1311 QPointF pt = last + ( next - last ) * k;
1314 double origAngle = mMarker->angle();
1315 if ( mRotateMarker )
1316 mMarker->setAngle( origAngle + l.angle() * 180 / M_PI );
1318 if ( mRotateMarker )
1319 mMarker->setAngle( origAngle );
1327 map[QStringLiteral(
"rotate" )] = ( mRotateMarker ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
1328 map[QStringLiteral(
"interval" )] = QString::number( mInterval );
1329 map[QStringLiteral(
"offset" )] = QString::number(
mOffset );
1330 map[QStringLiteral(
"offset_along_line" )] = QString::number( mOffsetAlongLine );
1337 if ( mPlacement == Vertex )
1338 map[QStringLiteral(
"placement" )] = QStringLiteral(
"vertex" );
1339 else if ( mPlacement == LastVertex )
1340 map[QStringLiteral(
"placement" )] = QStringLiteral(
"lastvertex" );
1341 else if ( mPlacement == FirstVertex )
1342 map[QStringLiteral(
"placement" )] = QStringLiteral(
"firstvertex" );
1343 else if ( mPlacement == CentralPoint )
1344 map[QStringLiteral(
"placement" )] = QStringLiteral(
"centralpoint" );
1345 else if ( mPlacement == CurvePoint )
1346 map[QStringLiteral(
"placement" )] = QStringLiteral(
"curvepoint" );
1348 map[QStringLiteral(
"placement" )] = QStringLiteral(
"interval" );
1354 return mMarker.get();
1365 mMarker.reset( static_cast<QgsMarkerSymbol *>( symbol ) );
1366 mColor = mMarker->color();
1390 for (
int i = 0; i < mMarker->symbolLayerCount(); i++ )
1392 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:LineSymbolizer" ) );
1393 if ( !props.value( QStringLiteral(
"uom" ), QLatin1String(
"" ) ).isEmpty() )
1394 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QLatin1String(
"" ) ) );
1395 element.appendChild( symbolizerElem );
1401 switch ( mPlacement )
1422 if ( !mRotateMarker )
1430 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
1431 symbolizerElem.appendChild( strokeElem );
1434 QDomElement graphicStrokeElem = doc.createElement( QStringLiteral(
"se:GraphicStroke" ) );
1435 strokeElem.appendChild( graphicStrokeElem );
1441 graphicStrokeElem.appendChild( doc.createComment( QStringLiteral(
"MarkerSymbolLayerV2 expected, %1 found. Skip it." ).arg( layer->
layerType() ) ) );
1448 if ( !gap.isEmpty() )
1450 QDomElement gapElem = doc.createElement( QStringLiteral(
"se:Gap" ) );
1452 graphicStrokeElem.appendChild( gapElem );
1457 QDomElement perpOffsetElem = doc.createElement( QStringLiteral(
"se:PerpendicularOffset" ) );
1459 perpOffsetElem.appendChild( doc.createTextNode(
qgsDoubleToString( offset ) ) );
1460 symbolizerElem.appendChild( perpOffsetElem );
1469 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1470 if ( strokeElem.isNull() )
1473 QDomElement graphicStrokeElem = strokeElem.firstChildElement( QStringLiteral(
"GraphicStroke" ) );
1474 if ( graphicStrokeElem.isNull() )
1478 bool rotateMarker =
true;
1482 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
1484 if ( it.key() == QLatin1String(
"placement" ) )
1486 if ( it.value() == QLatin1String(
"points" ) ) placement = Vertex;
1487 else if ( it.value() == QLatin1String(
"firstPoint" ) ) placement = FirstVertex;
1488 else if ( it.value() == QLatin1String(
"lastPoint" ) ) placement = LastVertex;
1489 else if ( it.value() == QLatin1String(
"centralPoint" ) ) placement = CentralPoint;
1491 else if ( it.value() == QLatin1String(
"rotateMarker" ) )
1493 rotateMarker = it.value() == QLatin1String(
"0" );
1497 std::unique_ptr< QgsMarkerSymbol > marker;
1510 double interval = 0.0;
1511 QDomElement gapElem = graphicStrokeElem.firstChildElement( QStringLiteral(
"Gap" ) );
1512 if ( !gapElem.isNull() )
1515 double d = gapElem.firstChild().nodeValue().toDouble( &ok );
1521 QDomElement perpOffsetElem = graphicStrokeElem.firstChildElement( QStringLiteral(
"PerpendicularOffset" ) );
1522 if ( !perpOffsetElem.isNull() )
1525 double d = perpOffsetElem.firstChild().nodeValue().toDouble( &ok );
1530 QString uom = element.attribute( QStringLiteral(
"uom" ) );
1545 mMarker->setSize( width );
1552 mMarker->setDataDefinedSize( property );
1559 return mMarker->size();
1565 mMarker->setOutputUnit( unit );
1566 mIntervalUnit = unit;
1568 mOffsetAlongLineUnit = unit;
1574 if ( mIntervalUnit != unit ||
mOffsetUnit != unit || mOffsetAlongLineUnit != unit )
1584 mIntervalMapUnitScale = scale;
1586 mOffsetAlongLineMapUnitScale = scale;
1604 attr.unite( mMarker->usedAttributes( context ) );
1610 return context.
convertToPainterUnits( ( mMarker->size() / 2.0 ), mMarker->sizeUnit(), mMarker->sizeMapUnitScale() ) +
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.
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)
const QgsCurve * interiorRing(int i) const
#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
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
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.
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, or an invalid transform is no coordinate tr...
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
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)
void startRender(QgsSymbolRenderContext &context) override
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 setColor(const QColor &color) override
The fill color.
SimplifyHints simplifyHints() const
Gets the simplification hints of the vector layer managed.
void setDrawInsidePolygon(bool drawInsidePolygon)
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
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
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.