21 #include "qgsexpression.h" 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() )
638 MyLine( QPointF p1, QPointF p2 )
640 , mIncreasing(
false )
652 mIncreasing = ( p2.y() > p1.y() );
657 mT = float( p2.y() - p1.y() ) / ( p2.x() - p1.x() );
658 mIncreasing = ( p2.x() > p1.x() );
662 double x = ( p2.x() - p1.x() );
663 double y = ( p2.y() - p1.y() );
664 mLength = std::sqrt( x * x + y * y );
670 double a = ( mVertical ? M_PI_2 : std::atan( mT ) );
678 QPointF diffForInterval(
double interval )
681 return ( mIncreasing ? QPointF( 0, interval ) : QPointF( 0, -interval ) );
683 double alpha = std::atan( mT );
684 double dx = std::cos( alpha ) * interval;
685 double dy = std::sin( alpha ) * interval;
686 return ( mIncreasing ? QPointF( dx, dy ) : QPointF( -dx, -dy ) );
689 double length() {
return mLength; }
702 mRotateMarker = rotateMarker;
703 mInterval = interval;
706 mPlacement = Interval;
707 mOffsetAlongLine = 0;
719 if ( props.contains( QStringLiteral(
"interval" ) ) )
720 interval = props[QStringLiteral(
"interval" )].toDouble();
721 if ( props.contains( QStringLiteral(
"rotate" ) ) )
722 rotate = ( props[QStringLiteral(
"rotate" )] == QLatin1String(
"1" ) );
725 if ( props.contains( QStringLiteral(
"offset" ) ) )
727 x->
setOffset( props[QStringLiteral(
"offset" )].toDouble() );
729 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
733 if ( props.contains( QStringLiteral(
"interval_unit" ) ) )
737 if ( props.contains( QStringLiteral(
"offset_along_line" ) ) )
741 if ( props.contains( QStringLiteral(
"offset_along_line_unit" ) ) )
745 if ( props.contains( ( QStringLiteral(
"offset_along_line_map_unit_scale" ) ) ) )
750 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
754 if ( props.contains( QStringLiteral(
"interval_map_unit_scale" ) ) )
759 if ( props.contains( QStringLiteral(
"placement" ) ) )
761 if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"vertex" ) )
763 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"lastvertex" ) )
765 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"firstvertex" ) )
767 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"centralpoint" ) )
769 else if ( props[QStringLiteral(
"placement" )] == QLatin1String(
"curvepoint" ) )
782 return QStringLiteral(
"MarkerLine" );
787 mMarker->setColor( color );
793 return mMarker ? mMarker->color() :
mColor;
798 mMarker->setOpacity( context.
opacity() );
801 QgsSymbol::RenderHints hints =
nullptr;
804 mMarker->setRenderHints( hints );
829 if ( exprVal.isValid() )
831 QString placementString = exprVal.toString();
832 if ( placementString.compare( QLatin1String(
"interval" ), Qt::CaseInsensitive ) == 0 )
834 placement = Interval;
836 else if ( placementString.compare( QLatin1String(
"vertex" ), Qt::CaseInsensitive ) == 0 )
840 else if ( placementString.compare( QLatin1String(
"lastvertex" ), Qt::CaseInsensitive ) == 0 )
842 placement = LastVertex;
844 else if ( placementString.compare( QLatin1String(
"firstvertex" ), Qt::CaseInsensitive ) == 0 )
846 placement = FirstVertex;
848 else if ( placementString.compare( QLatin1String(
"centerpoint" ), Qt::CaseInsensitive ) == 0 )
850 placement = CentralPoint;
852 else if ( placementString.compare( QLatin1String(
"curvepoint" ), Qt::CaseInsensitive ) == 0 )
854 placement = CurvePoint;
858 placement = Interval;
868 if ( placement == Interval )
869 renderPolylineInterval( points, context );
870 else if ( placement == CentralPoint )
871 renderPolylineCentral( points, context );
873 renderPolylineVertex( points, context, placement );
880 for (
int part = 0; part < mline.count(); ++part )
882 const QPolygonF &points2 = mline[ part ];
884 if ( placement == Interval )
885 renderPolylineInterval( points2, context );
886 else if ( placement == CentralPoint )
887 renderPolylineCentral( points2, context );
889 renderPolylineVertex( points2, context, placement );
908 for (
int i = 0; i < rings->size(); ++i )
922 if ( points.isEmpty() )
925 QPointF lastPt = points[0];
926 double lengthLeft = 0;
929 double interval = mInterval;
943 double offsetAlongLine = mOffsetAlongLine;
950 double painterUnitInterval = rc.
convertToPainterUnits( interval, mIntervalUnit, mIntervalMapUnitScale );
951 lengthLeft = painterUnitInterval - rc.
convertToPainterUnits( offsetAlongLine, mIntervalUnit, mIntervalMapUnitScale );
954 for (
int i = 1; i < points.count(); ++i )
956 const QPointF &pt = points[i];
962 MyLine l( lastPt, pt );
963 QPointF diff = l.diffForInterval( painterUnitInterval );
967 double c = 1 - lengthLeft / painterUnitInterval;
969 lengthLeft += l.length();
974 mMarker->setLineAngle( l.angle() * 180 / M_PI );
979 while ( lengthLeft > painterUnitInterval )
983 lengthLeft -= painterUnitInterval;
985 mMarker->renderPoint( lastPt, context.
feature(), rc, -1, context.
selected() );
995 static double _averageAngle( QPointF prevPt, QPointF pt, QPointF nextPt )
998 double a1 = MyLine( prevPt, pt ).angle();
999 double a2 = MyLine( pt, nextPt ).angle();
1000 double unitX = std::cos( a1 ) + std::cos( a2 ), unitY = std::sin( a1 ) + std::sin( a2 );
1002 return std::atan2( unitY, unitX );
1007 if ( points.isEmpty() )
1012 double origAngle = mMarker->angle();
1014 bool isRing =
false;
1020 double offsetAlongLine = mOffsetAlongLine;
1029 offsetAlongLine = rc.
convertToPainterUnits( offsetAlongLine, mOffsetAlongLineUnit, mOffsetAlongLineMapUnitScale );
1051 x = vPoint.
x(), y = vPoint.
y();
1060 if ( mRotateMarker )
1063 mMarker->setAngle( angle * 180 / M_PI );
1065 mMarker->renderPoint( mapPoint, context.
feature(), rc, -1, context.
selected() );
1073 if ( placement == FirstVertex )
1078 else if ( placement == LastVertex )
1080 i = points.count() - 1;
1081 maxCount = points.count();
1083 else if ( placement == Vertex )
1086 maxCount = points.count();
1087 if ( points.first() == points.last() )
1096 if ( offsetAlongLine > 0 && ( placement == FirstVertex || placement == LastVertex ) )
1099 distance = placement == FirstVertex ? offsetAlongLine : -offsetAlongLine;
1100 renderOffsetVertexAlongLine( points, i, distance, context );
1102 mMarker->setAngle( origAngle );
1109 for ( ; i < maxCount; ++i )
1113 if ( isRing && placement == Vertex && i == points.count() - 1 )
1118 if ( mRotateMarker )
1120 double angle = markerAngle( points, isRing, i );
1121 mMarker->setAngle( origAngle + angle * 180 / M_PI );
1124 mMarker->renderPoint( points.at( i ), context.
feature(), rc, -1, context.
selected() );
1128 mMarker->setAngle( origAngle );
1136 const QPointF &pt = points[vertex];
1138 if ( isRing || ( vertex > 0 && vertex < points.count() - 1 ) )
1140 int prevIndex = vertex - 1;
1141 int nextIndex = vertex + 1;
1143 if ( isRing && ( vertex == 0 || vertex == points.count() - 1 ) )
1145 prevIndex = points.count() - 2;
1149 QPointF prevPoint, nextPoint;
1150 while ( prevIndex >= 0 )
1152 prevPoint = points[ prevIndex ];
1153 if ( prevPoint != pt )
1160 while ( nextIndex < points.count() )
1162 nextPoint = points[ nextIndex ];
1163 if ( nextPoint != pt )
1170 if ( prevIndex >= 0 && nextIndex < points.count() )
1172 angle = _averageAngle( prevPoint, pt, nextPoint );
1179 while ( vertex < points.size() - 1 )
1181 const QPointF &nextPt = points[vertex + 1];
1184 angle = MyLine( pt, nextPt ).angle();
1193 while ( vertex >= 1 )
1195 const QPointF &prevPt = points[vertex - 1];
1198 angle = MyLine( prevPt, pt ).angle();
1208 void QgsMarkerLineSymbolLayer::renderOffsetVertexAlongLine(
const QPolygonF &points,
int vertex,
double distance,
QgsSymbolRenderContext &context )
1210 if ( points.isEmpty() )
1214 double origAngle = mMarker->angle();
1218 if ( mRotateMarker )
1220 bool isRing =
false;
1221 if ( points.first() == points.last() )
1223 double angle = markerAngle( points, isRing, vertex );
1224 mMarker->setAngle( origAngle + angle * 180 / M_PI );
1226 mMarker->renderPoint( points[vertex], context.
feature(), rc, -1, context.
selected() );
1230 int pointIncrement = distance > 0 ? 1 : -1;
1231 QPointF previousPoint = points[vertex];
1232 int startPoint = distance > 0 ? std::min( vertex + 1, points.count() - 1 ) : std::max( vertex - 1, 0 );
1233 int endPoint = distance > 0 ? points.count() - 1 : 0;
1234 double distanceLeft = std::fabs( distance );
1236 for (
int i = startPoint; pointIncrement > 0 ? i <= endPoint : i >= endPoint; i += pointIncrement )
1238 const QPointF &pt = points[i];
1240 if ( previousPoint == pt )
1244 MyLine l( previousPoint, pt );
1246 if ( distanceLeft < l.length() )
1249 QPointF markerPoint = previousPoint + l.diffForInterval( distanceLeft );
1251 if ( mRotateMarker )
1253 mMarker->setAngle( origAngle + ( l.angle() * 180 / M_PI ) );
1255 mMarker->renderPoint( markerPoint, context.
feature(), rc, -1, context.
selected() );
1259 distanceLeft -= l.length();
1268 if ( !points.isEmpty() )
1272 QPolygonF::const_iterator it = points.constBegin();
1274 for ( ++it; it != points.constEnd(); ++it )
1276 length += std::sqrt( ( last.x() - it->x() ) * ( last.x() - it->x() ) +
1277 ( last.y() - it->y() ) * ( last.y() - it->y() ) );
1282 it = points.constBegin();
1284 qreal last_at = 0, next_at = 0;
1287 for ( ++it; it != points.constEnd(); ++it )
1290 next_at += std::sqrt( ( last.x() - it->x() ) * ( last.x() - it->x() ) +
1291 ( last.y() - it->y() ) * ( last.y() - it->y() ) );
1292 if ( next_at >= length / 2 )
1300 MyLine l( last, next );
1301 qreal k = ( length * 0.5 - last_at ) / ( next_at - last_at );
1302 QPointF pt = last + ( next - last ) * k;
1305 double origAngle = mMarker->angle();
1306 if ( mRotateMarker )
1307 mMarker->setAngle( origAngle + l.angle() * 180 / M_PI );
1309 if ( mRotateMarker )
1310 mMarker->setAngle( origAngle );
1318 map[QStringLiteral(
"rotate" )] = ( mRotateMarker ? QStringLiteral(
"1" ) : QStringLiteral(
"0" ) );
1319 map[QStringLiteral(
"interval" )] = QString::number( mInterval );
1320 map[QStringLiteral(
"offset" )] = QString::number(
mOffset );
1321 map[QStringLiteral(
"offset_along_line" )] = QString::number( mOffsetAlongLine );
1328 if ( mPlacement == Vertex )
1329 map[QStringLiteral(
"placement" )] = QStringLiteral(
"vertex" );
1330 else if ( mPlacement == LastVertex )
1331 map[QStringLiteral(
"placement" )] = QStringLiteral(
"lastvertex" );
1332 else if ( mPlacement == FirstVertex )
1333 map[QStringLiteral(
"placement" )] = QStringLiteral(
"firstvertex" );
1334 else if ( mPlacement == CentralPoint )
1335 map[QStringLiteral(
"placement" )] = QStringLiteral(
"centralpoint" );
1336 else if ( mPlacement == CurvePoint )
1337 map[QStringLiteral(
"placement" )] = QStringLiteral(
"curvepoint" );
1339 map[QStringLiteral(
"placement" )] = QStringLiteral(
"interval" );
1345 return mMarker.get();
1356 mMarker.reset( static_cast<QgsMarkerSymbol *>( symbol ) );
1357 mColor = mMarker->color();
1381 for (
int i = 0; i < mMarker->symbolLayerCount(); i++ )
1383 QDomElement symbolizerElem = doc.createElement( QStringLiteral(
"se:LineSymbolizer" ) );
1384 if ( !props.value( QStringLiteral(
"uom" ), QLatin1String(
"" ) ).isEmpty() )
1385 symbolizerElem.setAttribute( QStringLiteral(
"uom" ), props.value( QStringLiteral(
"uom" ), QLatin1String(
"" ) ) );
1386 element.appendChild( symbolizerElem );
1392 switch ( mPlacement )
1413 if ( !mRotateMarker )
1421 QDomElement strokeElem = doc.createElement( QStringLiteral(
"se:Stroke" ) );
1422 symbolizerElem.appendChild( strokeElem );
1425 QDomElement graphicStrokeElem = doc.createElement( QStringLiteral(
"se:GraphicStroke" ) );
1426 strokeElem.appendChild( graphicStrokeElem );
1432 graphicStrokeElem.appendChild( doc.createComment( QStringLiteral(
"MarkerSymbolLayerV2 expected, %1 found. Skip it." ).arg( layer->
layerType() ) ) );
1439 if ( !gap.isEmpty() )
1441 QDomElement gapElem = doc.createElement( QStringLiteral(
"se:Gap" ) );
1443 graphicStrokeElem.appendChild( gapElem );
1448 QDomElement perpOffsetElem = doc.createElement( QStringLiteral(
"se:PerpendicularOffset" ) );
1450 perpOffsetElem.appendChild( doc.createTextNode(
qgsDoubleToString( offset ) ) );
1451 symbolizerElem.appendChild( perpOffsetElem );
1460 QDomElement strokeElem = element.firstChildElement( QStringLiteral(
"Stroke" ) );
1461 if ( strokeElem.isNull() )
1464 QDomElement graphicStrokeElem = strokeElem.firstChildElement( QStringLiteral(
"GraphicStroke" ) );
1465 if ( graphicStrokeElem.isNull() )
1469 bool rotateMarker =
true;
1473 for ( QgsStringMap::iterator it = vendorOptions.begin(); it != vendorOptions.end(); ++it )
1475 if ( it.key() == QLatin1String(
"placement" ) )
1477 if ( it.value() == QLatin1String(
"points" ) ) placement = Vertex;
1478 else if ( it.value() == QLatin1String(
"firstPoint" ) ) placement = FirstVertex;
1479 else if ( it.value() == QLatin1String(
"lastPoint" ) ) placement = LastVertex;
1480 else if ( it.value() == QLatin1String(
"centralPoint" ) ) placement = CentralPoint;
1482 else if ( it.value() == QLatin1String(
"rotateMarker" ) )
1484 rotateMarker = it.value() == QLatin1String(
"0" );
1488 std::unique_ptr< QgsMarkerSymbol > marker;
1501 double interval = 0.0;
1502 QDomElement gapElem = graphicStrokeElem.firstChildElement( QStringLiteral(
"Gap" ) );
1503 if ( !gapElem.isNull() )
1506 double d = gapElem.firstChild().nodeValue().toDouble( &ok );
1512 QDomElement perpOffsetElem = graphicStrokeElem.firstChildElement( QStringLiteral(
"PerpendicularOffset" ) );
1513 if ( !perpOffsetElem.isNull() )
1516 double d = perpOffsetElem.firstChild().nodeValue().toDouble( &ok );
1521 QString uom = element.attribute( QStringLiteral(
"uom" ) );
1536 mMarker->setSize( width );
1543 mMarker->setDataDefinedSize( property );
1550 return mMarker->size();
1556 mMarker->setOutputUnit( unit );
1557 mIntervalUnit = unit;
1559 mOffsetAlongLineUnit = unit;
1565 if ( mIntervalUnit != unit ||
mOffsetUnit != unit || mOffsetAlongLineUnit != unit )
1575 mIntervalMapUnitScale = scale;
1577 mOffsetAlongLineMapUnitScale = scale;
1595 attr.unite( mMarker->usedAttributes( context ) );
1601 return context.
convertToPainterUnits( ( mMarker->size() / 2.0 ), mMarker->sizeUnit(), mMarker->sizeMapUnitScale() ) +
const QgsCurve * interiorRing(int i) const
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
get offset
double symbologyScale() const
Returns the reference scale for output.
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.
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
static double mapUnitScaleFactor(double scale, QgsUnitTypes::RenderUnit symbolUnits, QgsUnitTypes::DistanceUnit mapUnits)
Calculates a scaling factor to convert from map units to a specified symbol unit. ...
void toSld(QDomDocument &doc, QDomElement &element, const QgsStringMap &props) const override
static QgsSymbolLayer * createFromSld(QDomElement &element)
#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
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.
bool qgsDoubleNear(double a, double b, double epsilon=4 *DBL_EPSILON)
Compare two doubles (but allow some difference)
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)
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)
set 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
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.
A store for object properties.
QgsMapUnitScale mWidthMapUnitScale
const QgsCurve * exteriorRing() const
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
get 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)
QVector< qreal > dxfCustomDashPattern(QgsUnitTypes::RenderUnit &unit) const override
get 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
set layer's subsymbol. takes ownership of the passed symbol
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
get color
Qt::PenStyle dxfPenStyle() const override
get 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.