35#include <QSvgRenderer>
38#include <QDomDocument>
44static constexpr int MAX_FONT_CHARACTER_SIZE_IN_PIXELS = 500;
55 QList< Qgis::MarkerShape > shapes;
170 QTransform transform;
173 if ( !hasDataDefinedSize )
183 const double half = scaledSize / 2.0;
184 transform.scale( half, half );
190 transform.rotate(
mAngle );
217 bool hasDataDefinedSize =
false;
218 const double scaledSize =
calculateSize( context, hasDataDefinedSize );
220 bool hasDataDefinedRotation =
false;
226 bool createdNewPath =
false;
244 createdNewPath =
true;
253 QTransform transform;
256 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
259 if ( hasDataDefinedSize || createdNewPath )
268 const double half = s / 2.0;
269 transform.scale( half, half );
274 transform.rotate(
angle );
283 polygon = transform.map(
mPolygon );
287 path = transform.map(
mPath );
289 draw( context, symbol, polygon, path );
294 bool hasDataDefinedSize =
false;
295 double scaledSize =
calculateSize( context, hasDataDefinedSize );
297 bool hasDataDefinedRotation =
false;
304 QTransform transform;
307 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
310 transform.rotate(
angle );
312 return transform.mapRect( QRectF( -scaledSize / 2.0,
322 const QString cleaned = name.toLower().trimmed();
324 if ( cleaned == QLatin1String(
"square" ) || cleaned == QLatin1String(
"rectangle" ) )
326 else if ( cleaned == QLatin1String(
"trapezoid" ) )
328 else if ( cleaned == QLatin1String(
"parallelogram_right" ) )
330 else if ( cleaned == QLatin1String(
"parallelogram_left" ) )
332 else if ( cleaned == QLatin1String(
"square_with_corners" ) )
334 else if ( cleaned == QLatin1String(
"rounded_square" ) )
336 else if ( cleaned == QLatin1String(
"diamond" ) )
338 else if ( cleaned == QLatin1String(
"shield" ) )
340 else if ( cleaned == QLatin1String(
"pentagon" ) )
342 else if ( cleaned == QLatin1String(
"hexagon" ) )
344 else if ( cleaned == QLatin1String(
"octagon" ) )
346 else if ( cleaned == QLatin1String(
"decagon" ) )
348 else if ( cleaned == QLatin1String(
"triangle" ) )
350 else if ( cleaned == QLatin1String(
"equilateral_triangle" ) )
352 else if ( cleaned == QLatin1String(
"star_diamond" ) )
354 else if ( cleaned == QLatin1String(
"star" ) || cleaned == QLatin1String(
"regular_star" ) )
356 else if ( cleaned == QLatin1String(
"heart" ) )
358 else if ( cleaned == QLatin1String(
"arrow" ) )
360 else if ( cleaned == QLatin1String(
"circle" ) )
362 else if ( cleaned == QLatin1String(
"cross" ) )
364 else if ( cleaned == QLatin1String(
"cross_fill" ) )
366 else if ( cleaned == QLatin1String(
"cross2" ) || cleaned == QLatin1String(
"x" ) )
368 else if ( cleaned == QLatin1String(
"line" ) )
370 else if ( cleaned == QLatin1String(
"arrowhead" ) )
372 else if ( cleaned == QLatin1String(
"filled_arrowhead" ) )
374 else if ( cleaned == QLatin1String(
"semi_circle" ) )
376 else if ( cleaned == QLatin1String(
"third_circle" ) )
378 else if ( cleaned == QLatin1String(
"quarter_circle" ) )
380 else if ( cleaned == QLatin1String(
"quarter_square" ) )
382 else if ( cleaned == QLatin1String(
"half_square" ) )
384 else if ( cleaned == QLatin1String(
"diagonal_half_square" ) )
386 else if ( cleaned == QLatin1String(
"right_half_triangle" ) )
388 else if ( cleaned == QLatin1String(
"left_half_triangle" ) )
390 else if ( cleaned == QLatin1String(
"asterisk_fill" ) )
392 else if ( cleaned == QLatin1String(
"half_arc" ) )
394 else if ( cleaned == QLatin1String(
"third_arc" ) )
396 else if ( cleaned == QLatin1String(
"quarter_arc" ) )
409 return QStringLiteral(
"square" );
411 return QStringLiteral(
"quarter_square" );
413 return QStringLiteral(
"half_square" );
415 return QStringLiteral(
"diagonal_half_square" );
417 return QStringLiteral(
"parallelogram_right" );
419 return QStringLiteral(
"parallelogram_left" );
421 return QStringLiteral(
"trapezoid" );
423 return QStringLiteral(
"shield" );
425 return QStringLiteral(
"diamond" );
427 return QStringLiteral(
"pentagon" );
429 return QStringLiteral(
"hexagon" );
431 return QStringLiteral(
"octagon" );
433 return QStringLiteral(
"decagon" );
435 return QStringLiteral(
"square_with_corners" );
437 return QStringLiteral(
"rounded_square" );
439 return QStringLiteral(
"triangle" );
441 return QStringLiteral(
"equilateral_triangle" );
443 return QStringLiteral(
"left_half_triangle" );
445 return QStringLiteral(
"right_half_triangle" );
447 return QStringLiteral(
"star_diamond" );
449 return QStringLiteral(
"star" );
451 return QStringLiteral(
"heart" );
453 return QStringLiteral(
"arrow" );
455 return QStringLiteral(
"filled_arrowhead" );
457 return QStringLiteral(
"cross_fill" );
459 return QStringLiteral(
"circle" );
461 return QStringLiteral(
"cross" );
463 return QStringLiteral(
"cross2" );
465 return QStringLiteral(
"line" );
467 return QStringLiteral(
"arrowhead" );
469 return QStringLiteral(
"semi_circle" );
471 return QStringLiteral(
"third_circle" );
473 return QStringLiteral(
"quarter_circle" );
475 return QStringLiteral(
"asterisk_fill" );
477 return QStringLiteral(
"half_arc" );
479 return QStringLiteral(
"third_arc" );
481 return QStringLiteral(
"quarter_arc" );
498 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 1, 1 ) ) );
503 static constexpr double VERTEX_OFFSET_FROM_ORIGIN = 0.6072;
505 polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
506 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
507 << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
508 << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
509 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
510 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
511 << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
512 << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
513 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
518 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 0 ) ) );
522 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 1 ) ) );
526 polygon << QPointF( -1, -1 ) << QPointF( 1, 1 ) << QPointF( -1, 1 ) << QPointF( -1, -1 );
530 polygon << QPointF( 0.5, -0.5 )
532 << QPointF( -1, 0.5 )
533 << QPointF( -0.5, -0.5 )
534 << QPointF( 0.5, -0.5 );
538 polygon << QPointF( 0.5, 0.5 )
539 << QPointF( 1, -0.5 )
540 << QPointF( -0.5, -0.5 )
541 << QPointF( -1, 0.5 )
542 << QPointF( 0.5, 0.5 );
546 polygon << QPointF( 1, 0.5 )
547 << QPointF( 0.5, -0.5 )
548 << QPointF( -1, -0.5 )
549 << QPointF( -0.5, 0.5 )
550 << QPointF( 1, 0.5 );
554 polygon << QPointF( -1, 0 ) << QPointF( 0, 1 )
555 << QPointF( 1, 0 ) << QPointF( 0, -1 ) << QPointF( -1, 0 );
559 polygon << QPointF( 1, 0.5 )
562 << QPointF( -1, 0.5 )
564 << QPointF( 1, 0.5 );
574 polygon << QPointF( -0.9511, -0.3090 )
575 << QPointF( -0.5878, 0.8090 )
576 << QPointF( 0.5878, 0.8090 )
577 << QPointF( 0.9511, -0.3090 )
579 << QPointF( -0.9511, -0.3090 );
590 polygon << QPointF( -0.8660, -0.5 )
591 << QPointF( -0.8660, 0.5 )
593 << QPointF( 0.8660, 0.5 )
594 << QPointF( 0.8660, -0.5 )
596 << QPointF( -0.8660, -0.5 );
601 static constexpr double VERTEX_OFFSET_FROM_ORIGIN = 1.0 / ( 1 + M_SQRT2 );
603 polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
604 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
605 << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
606 << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
607 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
608 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
609 << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
610 << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
611 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
618 polygon << QPointF( 0.587785252, 0.809016994 )
619 << QPointF( 0.951056516, 0.309016994 )
620 << QPointF( 0.951056516, -0.309016994 )
621 << QPointF( 0.587785252, -0.809016994 )
623 << QPointF( -0.587785252, -0.809016994 )
624 << QPointF( -0.951056516, -0.309016994 )
625 << QPointF( -0.951056516, 0.309016994 )
626 << QPointF( -0.587785252, 0.809016994 )
628 << QPointF( 0.587785252, 0.809016994 );
633 polygon << QPointF( -1, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
641 polygon << QPointF( -0.8660, 0.5 )
642 << QPointF( 0.8660, 0.5 )
644 << QPointF( -0.8660, 0.5 );
648 polygon << QPointF( 0, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( 0, 1 );
652 polygon << QPointF( -1, 1 ) << QPointF( 0, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
657 const double inner_r = std::cos(
DEG2RAD( 72.0 ) ) / std::cos(
DEG2RAD( 36.0 ) );
659 polygon << QPointF( inner_r * std::sin(
DEG2RAD( 315.0 ) ), - inner_r * std::cos(
DEG2RAD( 315.0 ) ) )
660 << QPointF( std::sin(
DEG2RAD( 270 ) ), - std::cos(
DEG2RAD( 270 ) ) )
661 << QPointF( inner_r * std::sin(
DEG2RAD( 225.0 ) ), - inner_r * std::cos(
DEG2RAD( 225.0 ) ) )
662 << QPointF( std::sin(
DEG2RAD( 180 ) ), - std::cos(
DEG2RAD( 180 ) ) )
663 << QPointF( inner_r * std::sin(
DEG2RAD( 135.0 ) ), - inner_r * std::cos(
DEG2RAD( 135.0 ) ) )
664 << QPointF( std::sin(
DEG2RAD( 90 ) ), - std::cos(
DEG2RAD( 90 ) ) )
665 << QPointF( inner_r * std::sin(
DEG2RAD( 45.0 ) ), - inner_r * std::cos(
DEG2RAD( 45.0 ) ) )
666 << QPointF( std::sin(
DEG2RAD( 0 ) ), - std::cos(
DEG2RAD( 0 ) ) )
667 << QPointF( inner_r * std::sin(
DEG2RAD( 315.0 ) ), - inner_r * std::cos(
DEG2RAD( 315.0 ) ) );
673 const double inner_r = std::cos(
DEG2RAD( 72.0 ) ) / std::cos(
DEG2RAD( 36.0 ) );
675 polygon << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) )
676 << QPointF( std::sin(
DEG2RAD( 288.0 ) ), - std::cos(
DEG2RAD( 288 ) ) )
677 << QPointF( inner_r * std::sin(
DEG2RAD( 252.0 ) ), - inner_r * std::cos(
DEG2RAD( 252.0 ) ) )
678 << QPointF( std::sin(
DEG2RAD( 216.0 ) ), - std::cos(
DEG2RAD( 216.0 ) ) )
679 << QPointF( 0, inner_r )
680 << QPointF( std::sin(
DEG2RAD( 144.0 ) ), - std::cos(
DEG2RAD( 144.0 ) ) )
681 << QPointF( inner_r * std::sin(
DEG2RAD( 108.0 ) ), - inner_r * std::cos(
DEG2RAD( 108.0 ) ) )
682 << QPointF( std::sin(
DEG2RAD( 72.0 ) ), - std::cos(
DEG2RAD( 72.0 ) ) )
683 << QPointF( inner_r * std::sin(
DEG2RAD( 36.0 ) ), - inner_r * std::cos(
DEG2RAD( 36.0 ) ) )
685 << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) );
690 polygon << QPointF( 0, -1 )
691 << QPointF( 0.5, -0.5 )
692 << QPointF( 0.25, -0.5 )
693 << QPointF( 0.25, 1 )
694 << QPointF( -0.25, 1 )
695 << QPointF( -0.25, -0.5 )
696 << QPointF( -0.5, -0.5 )
701 polygon << QPointF( 0, 0 ) << QPointF( -1, 1 ) << QPointF( -1, -1 ) << QPointF( 0, 0 );
705 polygon << QPointF( -1, -0.2 )
706 << QPointF( -1, -0.2 )
707 << QPointF( -1, 0.2 )
708 << QPointF( -0.2, 0.2 )
709 << QPointF( -0.2, 1 )
711 << QPointF( 0.2, 0.2 )
713 << QPointF( 1, -0.2 )
714 << QPointF( 0.2, -0.2 )
715 << QPointF( 0.2, -1 )
716 << QPointF( -0.2, -1 )
717 << QPointF( -0.2, -0.2 )
718 << QPointF( -1, -0.2 );
723 static constexpr double THICKNESS = 0.3;
724 static constexpr double HALF_THICKNESS = THICKNESS / 2.0;
725 static constexpr double INTERSECTION_POINT = THICKNESS / M_SQRT2;
726 static constexpr double DIAGONAL1 = M_SQRT1_2 - INTERSECTION_POINT * 0.5;
727 static constexpr double DIAGONAL2 = M_SQRT1_2 + INTERSECTION_POINT * 0.5;
729 polygon << QPointF( -HALF_THICKNESS, -1 )
730 << QPointF( HALF_THICKNESS, -1 )
731 << QPointF( HALF_THICKNESS, -HALF_THICKNESS - INTERSECTION_POINT )
732 << QPointF( DIAGONAL1, -DIAGONAL2 )
733 << QPointF( DIAGONAL2, -DIAGONAL1 )
734 << QPointF( HALF_THICKNESS + INTERSECTION_POINT, -HALF_THICKNESS )
735 << QPointF( 1, -HALF_THICKNESS )
736 << QPointF( 1, HALF_THICKNESS )
737 << QPointF( HALF_THICKNESS + INTERSECTION_POINT, HALF_THICKNESS )
738 << QPointF( DIAGONAL2, DIAGONAL1 )
739 << QPointF( DIAGONAL1, DIAGONAL2 )
740 << QPointF( HALF_THICKNESS, HALF_THICKNESS + INTERSECTION_POINT )
741 << QPointF( HALF_THICKNESS, 1 )
742 << QPointF( -HALF_THICKNESS, 1 )
743 << QPointF( -HALF_THICKNESS, HALF_THICKNESS + INTERSECTION_POINT )
744 << QPointF( -DIAGONAL1, DIAGONAL2 )
745 << QPointF( -DIAGONAL2, DIAGONAL1 )
746 << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, HALF_THICKNESS )
747 << QPointF( -1, HALF_THICKNESS )
748 << QPointF( -1, -HALF_THICKNESS )
749 << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, -HALF_THICKNESS )
750 << QPointF( -DIAGONAL2, -DIAGONAL1 )
751 << QPointF( -DIAGONAL1, -DIAGONAL2 )
752 << QPointF( -HALF_THICKNESS, -HALF_THICKNESS - INTERSECTION_POINT )
753 << QPointF( -HALF_THICKNESS, -1 );
778 mPath = QPainterPath();
784 mPath.addEllipse( QRectF( -1, -1, 2, 2 ) );
788 mPath.moveTo( -1, -1 );
789 mPath.addRoundedRect( -1, -1, 2, 2, 0.25, 0.25 );
793 mPath.arcTo( -1, -1, 2, 2, 0, 180 );
794 mPath.lineTo( 0, 0 );
798 mPath.arcTo( -1, -1, 2, 2, 90, 120 );
799 mPath.lineTo( 0, 0 );
803 mPath.arcTo( -1, -1, 2, 2, 90, 90 );
804 mPath.lineTo( 0, 0 );
808 mPath.moveTo( 1, 0 );
809 mPath.arcTo( -1, -1, 2, 2, 0, 180 );
813 mPath.moveTo( 0, -1 );
814 mPath.arcTo( -1, -1, 2, 2, 90, 120 );
818 mPath.moveTo( 0, -1 );
819 mPath.arcTo( -1, -1, 2, 2, 90, 90 );
823 mPath.moveTo( -1, 0 );
824 mPath.lineTo( 1, 0 );
825 mPath.moveTo( 0, -1 );
826 mPath.lineTo( 0, 1 );
830 mPath.moveTo( -1, -1 );
831 mPath.lineTo( 1, 1 );
832 mPath.moveTo( 1, -1 );
833 mPath.lineTo( -1, 1 );
837 mPath.moveTo( 0, -1 );
838 mPath.lineTo( 0, 1 );
842 mPath.moveTo( -1, -1 );
843 mPath.lineTo( 0, 0 );
844 mPath.lineTo( -1, 1 );
848 mPath.moveTo( 0, 0.75 );
849 mPath.arcTo( 0, -1, 1, 1, -45, 210 );
850 mPath.arcTo( -1, -1, 1, 1, 15, 210 );
851 mPath.lineTo( 0, 0.75 );
885 double scaledSize =
mSize;
889 if ( hasDataDefinedSize )
896 if ( hasDataDefinedSize && ok )
901 scaledSize = std::sqrt( scaledSize );
916 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
917 offset = QPointF( offsetX, offsetY );
919 hasDataDefinedRotation =
false;
932 hasDataDefinedRotation =
true;
937 if ( hasDataDefinedRotation )
966 , mStrokeColor( strokeColor )
967 , mPenJoinStyle( penJoinStyle )
984 if ( props.contains( QStringLiteral(
"name" ) ) )
988 if ( props.contains( QStringLiteral(
"color" ) ) )
990 if ( props.contains( QStringLiteral(
"color_border" ) ) )
995 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
999 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
1003 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
1007 if ( props.contains( QStringLiteral(
"size" ) ) )
1008 size = props[QStringLiteral(
"size" )].toDouble();
1009 if ( props.contains( QStringLiteral(
"angle" ) ) )
1010 angle = props[QStringLiteral(
"angle" )].toDouble();
1011 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1015 if ( props.contains( QStringLiteral(
"offset" ) ) )
1017 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1019 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1021 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1023 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1026 if ( props.contains( QStringLiteral(
"outline_style" ) ) )
1030 else if ( props.contains( QStringLiteral(
"line_style" ) ) )
1034 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
1036 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
1038 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
1040 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
1042 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
1046 if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
1050 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
1055 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1059 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1064 if ( props.contains( QStringLiteral(
"cap_style" ) ) )
1077 return QStringLiteral(
"SimpleMarker" );
1089 QColor brushColor =
mColor;
1092 brushColor.setAlphaF(
mColor.alphaF() * context.
opacity() );
1095 mBrush = QBrush( brushColor );
1096 mPen = QPen( penColor );
1106 selBrushColor.setAlphaF( context.
opacity() );
1107 selPenColor.setAlphaF( context.
opacity() );
1110 mSelPen = QPen( selPenColor );
1126 mCachedOpacity = context.
opacity();
1132 mSelPen.setColor( selBrushColor );
1165 scaledSize = ( std::abs( std::sin(
mAngle * M_PI / 180 ) ) + std::abs( std::cos(
mAngle * M_PI / 180 ) ) ) * scaledSize;
1168 const double pw =
static_cast< int >( std::round( ( (
qgsDoubleNear(
mPen.widthF(), 0.0 ) ? 1 :
mPen.widthF() * 4 ) + 1 ) ) ) / 2 * 2;
1169 const int imageSize = (
static_cast< int >( scaledSize ) + pw ) / 2 * 2 + 1;
1170 const double center = imageSize / 2.0;
1176 mCache = QImage( QSize( imageSize * deviceRatio,
1177 imageSize * deviceRatio ), QImage::Format_ARGB32_Premultiplied );
1187 p.setRenderHint( QPainter::Antialiasing );
1188 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
1190 p.translate( QPointF( center, center ) );
1198 mSelCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
1202 p.setRenderHint( QPainter::Antialiasing );
1203 p.setBrush( needsBrush ?
mSelBrush : Qt::NoBrush );
1205 p.translate( QPointF( center, center ) );
1216 p.setRenderHint( QPainter::Antialiasing );
1217 p.fillRect( 0, 0, imageSize, imageSize, selColor );
1218 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
1220 p.translate( QPointF( center, center ) );
1239 QColor brushColor =
mColor;
1240 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
1241 mBrush.setColor( brushColor );
1244 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
1245 mPen.setColor( penColor );
1254 c.setAlphaF(
c.alphaF() * context.
opacity() );
1264 c.setAlphaF(
c.alphaF() * context.
opacity() );
1317 p->setBrush( Qt::NoBrush );
1321 if ( !polygon.isEmpty() )
1322 p->drawPolygon( polygon );
1324 p->drawPath( path );
1342 const double s = img.width() / img.devicePixelRatioF();
1344 bool hasDataDefinedSize =
false;
1345 const double scaledSize =
calculateSize( context, hasDataDefinedSize );
1347 bool hasDataDefinedRotation =
false;
1352 p->drawImage( QRectF( point.x() - s / 2.0 +
offset.x(),
1353 point.y() - s / 2.0 +
offset.y(),
1368 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1371 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1377 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
1410 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
1411 element.appendChild( graphicElem );
1427 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
1430 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
1447 Q_UNUSED( mmScaleFactor )
1448 Q_UNUSED( mapUnitScaleFactor )
1450 QString ogrType =
"3";
1451 if ( mName ==
"square" )
1455 else if ( mName ==
"triangle" )
1459 else if ( mName ==
"star" )
1463 else if ( mName ==
"circle" )
1467 else if ( mName ==
"cross" )
1471 else if ( mName ==
"x" || mName ==
"cross2" )
1475 else if ( mName ==
"line" )
1481 ogrString.append(
"SYMBOL(" );
1482 ogrString.append(
"id:" );
1483 ogrString.append(
'\"' );
1484 ogrString.append(
"ogr-sym-" );
1485 ogrString.append( ogrType );
1486 ogrString.append(
'\"' );
1487 ogrString.append(
",c:" );
1488 ogrString.append(
mColor.name() );
1489 ogrString.append(
",o:" );
1491 ogrString.append( QString(
",s:%1mm" ).arg(
mSize ) );
1492 ogrString.append(
')' );
1497 ogrString.append(
"PEN(" );
1498 ogrString.append(
"c:" );
1499 ogrString.append(
mColor.name() );
1500 ogrString.append(
",w:" );
1501 ogrString.append( QString::number(
mSize ) );
1502 ogrString.append(
"mm" );
1503 ogrString.append(
")" );
1511 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1512 if ( graphicElem.isNull() )
1515 QString name = QStringLiteral(
"square" );
1528 const double d = angleFunc.toDouble( &ok );
1538 double scaleFactor = 1.0;
1539 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
1566 p->drawPath(
mPath );
1579 if ( hasDataDefinedSize )
1598 size *= mmMapUnitScaleFactor;
1605 const double halfSize =
size / 2.0;
1622 QColor pc =
mPen.color();
1623 QColor bc =
mBrush.color();
1643 QPointF off( offsetX, offsetY );
1672 t.translate( shift.x() + off.x(), shift.y() - off.y() );
1680 t.scale( halfSize, -halfSize );
1682 polygon = t.map( polygon );
1685 p.reserve( polygon.size() );
1686 for (
int i = 0; i < polygon.size(); i++ )
1691 if (
mBrush.style() != Qt::NoBrush )
1693 if (
mPen.style() != Qt::NoPen )
1698 shift += QPointF( off.x(), -off.y() );
1699 if (
mBrush.style() != Qt::NoBrush )
1701 if (
mPen.style() != Qt::NoPen )
1706 const QPointF pt1 = t.map( QPointF( 0, -halfSize ) );
1707 const QPointF pt2 = t.map( QPointF( 0, halfSize ) );
1709 if (
mPen.style() != Qt::NoPen )
1714 if (
mPen.style() != Qt::NoPen )
1716 const QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
1717 const QPointF pt2 = t.map( QPointF( halfSize, 0 ) );
1718 const QPointF pt3 = t.map( QPointF( 0, -halfSize ) );
1719 const QPointF pt4 = t.map( QPointF( 0, halfSize ) );
1727 if (
mPen.style() != Qt::NoPen )
1729 const QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
1730 const QPointF pt2 = t.map( QPointF( halfSize, halfSize ) );
1731 const QPointF pt3 = t.map( QPointF( halfSize, -halfSize ) );
1732 const QPointF pt4 = t.map( QPointF( -halfSize, halfSize ) );
1740 if (
mPen.style() != Qt::NoPen )
1742 const QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
1743 const QPointF pt2 = t.map( QPointF( 0, 0 ) );
1744 const QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
1830 symbolBounds.adjust( -penWidth / 2.0, -penWidth / 2.0,
1831 penWidth / 2.0, penWidth / 2.0 );
1833 return symbolBounds;
1882 if ( props.contains( QStringLiteral(
"name" ) ) )
1883 name = props[QStringLiteral(
"name" )].toString();
1884 if ( props.contains( QStringLiteral(
"size" ) ) )
1885 size = props[QStringLiteral(
"size" )].toDouble();
1886 if ( props.contains( QStringLiteral(
"angle" ) ) )
1887 angle = props[QStringLiteral(
"angle" )].toDouble();
1888 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1892 if ( props.contains( QStringLiteral(
"offset" ) ) )
1894 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1896 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1898 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1900 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1902 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1906 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1920 return QStringLiteral(
"FilledMarker" );
1960 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1963 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2019 attr.unite( mFill->usedAttributes( context ) );
2027 if ( mFill && mFill->hasDataDefinedProperties() )
2036 mFill->setColor(
c );
2041 return mFill ? mFill->color() :
mColor;
2048 || ( mFill && mFill->usesMapUnits() );
2055 mFill->setOutputUnit( unit );
2069 const double prevOpacity = mFill->opacity();
2070 mFill->setOpacity( mFill->opacity() * context.
opacity() );
2074 p->setBrush( Qt::red );
2078 p->setBrush( Qt::NoBrush );
2080 p->setPen( Qt::black );
2086 if ( !polygon.isEmpty() )
2088 mFill->renderPolygon( polygon,
nullptr, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2092 const QPolygonF poly = path.toFillPolygon();
2093 mFill->renderPolygon( poly,
nullptr, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2098 mFill->setOpacity( prevOpacity );
2113 mColor = QColor( 35, 35, 35 );
2120 , mPath( other.mPath )
2121 , mDefaultAspectRatio( other.mDefaultAspectRatio )
2122 , mFixedAspectRatio( other.mFixedAspectRatio )
2123 , mHasFillParam( other.mHasFillParam )
2124 , mStrokeColor( other.mStrokeColor )
2125 , mStrokeWidth( other.mStrokeWidth )
2126 , mParameters( other.mParameters )
2127 , mStrokeWidthUnit( other.mStrokeWidthUnit )
2128 , mStrokeWidthMapUnitScale( other.mStrokeWidthMapUnitScale )
2141 if ( props.contains( QStringLiteral(
"name" ) ) )
2142 name = props[QStringLiteral(
"name" )].toString();
2143 if ( props.contains( QStringLiteral(
"size" ) ) )
2144 size = props[QStringLiteral(
"size" )].toDouble();
2145 if ( props.contains( QStringLiteral(
"angle" ) ) )
2146 angle = props[QStringLiteral(
"angle" )].toDouble();
2147 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
2152 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
2154 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
2156 if ( props.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
2158 if ( props.contains( QStringLiteral(
"offset" ) ) )
2160 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
2162 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2164 if ( props.contains( QStringLiteral(
"fill" ) ) )
2169 else if ( props.contains( QStringLiteral(
"color" ) ) )
2173 if ( props.contains( QStringLiteral(
"outline" ) ) )
2178 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
2182 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
2187 if ( props.contains( QStringLiteral(
"outline-width" ) ) )
2190 m->
setStrokeWidth( props[QStringLiteral(
"outline-width" )].toDouble() );
2192 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
2194 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
2196 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
2198 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
2201 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
2205 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
2209 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2212 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
2216 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
2225 if ( props.contains( QStringLiteral(
"parameters" ) ) )
2227 const QVariantMap
parameters = props[QStringLiteral(
"parameters" )].toMap();
2236 const QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
2255 QColor defaultFillColor, defaultStrokeColor;
2257 bool hasFillOpacityParam =
false, hasStrokeParam =
false, hasStrokeWidthParam =
false, hasStrokeOpacityParam =
false;
2258 bool hasDefaultFillColor =
false, hasDefaultFillOpacity =
false, hasDefaultStrokeColor =
false, hasDefaultStrokeWidth =
false, hasDefaultStrokeOpacity =
false;
2260 hasFillOpacityParam, hasDefaultFillOpacity, fillOpacity,
2261 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2262 hasStrokeWidthParam, hasDefaultStrokeWidth,
strokeWidth,
2263 hasStrokeOpacityParam, hasDefaultStrokeOpacity, strokeOpacity );
2265 const double newFillOpacity = hasFillOpacityParam ?
fillColor().alphaF() : 1.0;
2266 const double newStrokeOpacity = hasStrokeOpacityParam ?
strokeColor().alphaF() : 1.0;
2268 if ( hasDefaultFillColor )
2270 defaultFillColor.setAlphaF( newFillOpacity );
2273 if ( hasDefaultFillOpacity )
2276 c.setAlphaF( fillOpacity );
2279 if ( hasDefaultStrokeColor )
2281 defaultStrokeColor.setAlphaF( newStrokeOpacity );
2284 if ( hasDefaultStrokeWidth )
2288 if ( hasDefaultStrokeOpacity )
2291 c.setAlphaF( strokeOpacity );
2305 const double widthScaleFactor = 3.465;
2308 mDefaultAspectRatio = svgViewbox.isValid() ? svgViewbox.height() / svgViewbox.width() : 0.0;
2316 if ( aPreservedAspectRatio && !par )
2320 else if ( !aPreservedAspectRatio && par )
2335 return QStringLiteral(
"SvgMarker" );
2360 bool hasDataDefinedSize =
false;
2361 const double scaledWidth = calculateSize( context, hasDataDefinedSize );
2366 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
2373 bool hasDataDefinedAspectRatio =
false;
2374 const double aspectRatio =
calculateAspectRatio( context, scaledWidth, hasDataDefinedAspectRatio );
2418 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
2422 QPointF outputOffset;
2424 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
2426 p->translate( point + outputOffset );
2432 bool fitsInCache =
true;
2433 bool usePict =
true;
2435 if ( ( !context.
forceVectorRendering() && !rotated ) || ( useSelectedColor && rasterizeSelected ) )
2440 if ( fitsInCache && img.width() > 1 )
2444 if ( useSelectedColor )
2452 QImage transparentImage = img.copy();
2454 if ( devicePixelRatio == 1 )
2456 p->drawImage( -transparentImage.width() / 2.0, -transparentImage.height() / 2.0, transparentImage );
2460 p->drawImage( QRectF( -transparentImage.width() / 2.0 / devicePixelRatio, -transparentImage.height() / 2.0 / devicePixelRatio,
2461 transparentImage.width() / devicePixelRatio, transparentImage.height() / devicePixelRatio
2462 ), transparentImage );
2467 if ( devicePixelRatio == 1 )
2469 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
2473 p->drawImage( QRectF( -img.width() / 2.0 / devicePixelRatio, -img.height() / 2.0 / devicePixelRatio,
2474 img.width() / devicePixelRatio, img.height() / devicePixelRatio ), img );
2480 if ( usePict || !fitsInCache )
2482 p->setOpacity( context.
opacity() );
2486 if ( pct.width() > 1 )
2496double QgsSvgMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
2498 double scaledSize =
mSize;
2502 if ( hasDataDefinedSize )
2510 if ( hasDataDefinedSize )
2517 if ( hasDataDefinedSize && ok )
2522 scaledSize = std::sqrt( scaledSize );
2535 if ( !hasDataDefinedAspectRatio )
2545 const double defaultHeight =
mSize * scaledAspectRatio;
2546 scaledAspectRatio = defaultHeight / scaledSize;
2549 double scaledHeight = scaledSize * scaledAspectRatio;
2556 if ( hasDataDefinedAspectRatio && ok )
2561 scaledHeight = sqrt( scaledHeight );
2568 scaledAspectRatio = scaledHeight / scaledSize;
2570 return scaledAspectRatio;
2573void QgsSvgMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &angle )
const
2578 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
2579 offset = QPointF( offsetX, offsetY );
2589 if ( hasDataDefinedRotation )
2615 map[QStringLiteral(
"name" )] =
mPath;
2616 map[QStringLiteral(
"size" )] = QString::number(
mSize );
2619 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
2620 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2627 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
2684 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2685 element.appendChild( graphicElem );
2695 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2698 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
2716 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
2717 if ( graphicElem.isNull() )
2720 QString
path, mimeType;
2728 double scaleFactor = 1.0;
2729 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
2733 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2741 const double d = angleFunc.toDouble( &ok );
2750 QString realPath {
path };
2751 QUrl svgUrl {
path };
2754 QUrlQuery queryString;
2756 if ( svgUrl.hasQuery() && svgUrl.hasFragment() )
2758 const QString queryPart {
path.mid(
path.indexOf(
'?' ) + 1 ) };
2759 queryString.setQuery( queryPart );
2763 if ( svgUrl.scheme().isEmpty() || svgUrl.isLocalFile() )
2765 svgUrl.setQuery( QString() );
2766 realPath = svgUrl.path();
2771 QMap<QString, QgsProperty> params;
2775 if ( queryString.hasQueryItem( QStringLiteral(
"fill" ) ) )
2777 const QColor
fillColor { queryString.queryItemValue( QStringLiteral(
"fill" ) ) };
2781 if ( queryString.hasQueryItem( QStringLiteral(
"fill-opacity" ) ) )
2783 const double alpha { queryString.queryItemValue( QStringLiteral(
"fill-opacity" ) ).toDouble( &ok ) };
2790 if ( queryString.hasQueryItem( QStringLiteral(
"outline" ) ) )
2792 const QColor
strokeColor { queryString.queryItemValue( QStringLiteral(
"outline" ) ) };
2796 if ( queryString.hasQueryItem( QStringLiteral(
"outline-opacity" ) ) )
2798 const double alpha { queryString.queryItemValue( QStringLiteral(
"outline-opacity" ) ).toDouble( &ok ) };
2805 if ( queryString.hasQueryItem( QStringLiteral(
"outline-width" ) ) )
2807 const int width { queryString.queryItemValue( QStringLiteral(
"outline-width" ) ).toInt( &ok )};
2814 if ( ! params.isEmpty() )
2833 if ( hasDataDefinedSize )
2839 if ( hasDataDefinedSize && ok )
2853 size *= mmMapUnitScaleFactor;
2867 const double offsetX =
offset.x();
2868 const double offsetY =
offset.y();
2870 QPointF outputOffset( offsetX, offsetY );
2920 QSvgRenderer r( svgContent );
2927 QSizeF outSize( r.defaultSize() );
2928 outSize.scale(
size,
size, Qt::KeepAspectRatio );
2934 p.translate( r.defaultSize().width() / 2.0, r.defaultSize().height() / 2.0 );
2936 p.translate( -r.defaultSize().width() / 2.0, -r.defaultSize().height() / 2.0 );
2938 pd.
setShift( shift + QPointF( outputOffset.x(), -outputOffset.y() ) );
2939 pd.
setOutputSize( QRectF( -outSize.width() / 2.0, -outSize.height() / 2.0, outSize.width(), outSize.height() ) );
2948 bool hasDataDefinedSize =
false;
2949 double scaledWidth = calculateSize( context, hasDataDefinedSize );
2951 bool hasDataDefinedAspectRatio =
false;
2952 const double aspectRatio =
calculateAspectRatio( context, scaledWidth, hasDataDefinedAspectRatio );
2959 if (
static_cast< int >( scaledWidth ) < 1 || 10000.0 < scaledWidth )
2964 QPointF outputOffset;
2966 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
3005 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
3009 QTransform transform;
3011 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
3014 transform.rotate(
angle );
3019 QRectF symbolBounds = transform.mapRect( QRectF( -scaledWidth / 2.0,
3020 -scaledHeight / 2.0,
3028 return symbolBounds;
3052 if ( props.contains( QStringLiteral(
"imageFile" ) ) )
3053 path = props[QStringLiteral(
"imageFile" )].toString();
3054 if ( props.contains( QStringLiteral(
"size" ) ) )
3055 size = props[QStringLiteral(
"size" )].toDouble();
3056 if ( props.contains( QStringLiteral(
"angle" ) ) )
3057 angle = props[QStringLiteral(
"angle" )].toDouble();
3058 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
3062 m->setCommonProperties( props );
3068 if (
properties.contains( QStringLiteral(
"alpha" ) ) )
3073 if (
properties.contains( QStringLiteral(
"size_unit" ) ) )
3075 if (
properties.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
3077 if (
properties.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
3080 if (
properties.contains( QStringLiteral(
"offset" ) ) )
3082 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
3084 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
3087 if (
properties.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
3091 if (
properties.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
3102 const QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
3103 if ( it !=
properties.end() && it.value().userType() == QMetaType::Type::QString )
3121 if ( aPreservedAspectRatio && !par )
3125 else if ( !aPreservedAspectRatio && par )
3144 return QStringLiteral(
"RasterMarker" );
3165 if (
path.isEmpty() )
3169 double height = 0.0;
3171 bool hasDataDefinedSize =
false;
3172 const double scaledSize = calculateSize( context, hasDataDefinedSize );
3174 bool hasDataDefinedAspectRatio =
false;
3175 const double aspectRatio =
calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
3177 QPointF outputOffset;
3184 if (
size.isEmpty() )
3187 width = ( scaledSize *
static_cast< double >(
size.width() ) ) / 100.0;
3188 height = ( scaledSize *
static_cast< double >(
size.height() ) ) / 100.0;
3191 if (
static_cast< int >( width ) < 1 || 10000.0 < width ||
static_cast< int >( height ) < 1 || 10000.0 < height )
3194 calculateOffsetAndRotation( context, width, height, outputOffset,
angle );
3204 if ( !
size.isNull() &&
size.isValid() &&
size.width() > 0 )
3206 height = width * (
static_cast< double >(
size.height() ) /
static_cast< double >(
size.width() ) );
3211 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
3214 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
3218 p->translate( point + outputOffset );
3233 if ( !img.isNull() )
3236 if ( useSelectedColor )
3241 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
3247 bool cached =
false;
3251double QgsRasterMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
3253 double scaledSize =
mSize;
3257 if ( hasDataDefinedSize )
3265 if ( hasDataDefinedSize )
3272 if ( hasDataDefinedSize && ok )
3277 scaledSize = std::sqrt( scaledSize );
3290 if ( !hasDataDefinedAspectRatio )
3300 const double defaultHeight =
mSize * scaledAspectRatio;
3301 scaledAspectRatio = defaultHeight / scaledSize;
3304 double scaledHeight = scaledSize * scaledAspectRatio;
3311 if ( hasDataDefinedAspectRatio && ok )
3316 scaledHeight = sqrt( scaledHeight );
3323 scaledAspectRatio = scaledHeight / scaledSize;
3325 return scaledAspectRatio;
3328void QgsRasterMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &angle )
const
3333 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
3334 offset = QPointF( offsetX, offsetY );
3344 if ( hasDataDefinedRotation )
3365 map[QStringLiteral(
"imageFile" )] =
mPath;
3366 map[QStringLiteral(
"size" )] = QString::number(
mSize );
3369 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
3370 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
3371 map[QStringLiteral(
"alpha" )] = QString::number(
mOpacity );
3383 auto m = std::make_unique< QgsRasterMarkerSymbolLayer >();
3432 bool hasDataDefinedSize =
false;
3433 const double scaledSize = calculateSize( context, hasDataDefinedSize );
3435 bool hasDataDefinedAspectRatio =
false;
3436 const double aspectRatio =
calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
3440 if (
static_cast< int >( scaledSize ) < 1 || 10000.0 < scaledSize )
3445 QPointF outputOffset;
3447 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
3449 QTransform transform;
3452 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
3455 transform.rotate(
angle );
3457 QRectF symbolBounds = transform.mapRect( QRectF( -width / 2.0,
3462 return symbolBounds;
3474 mOrigSize = pointSize;
3494 if ( props.contains( QStringLiteral(
"font" ) ) )
3495 fontFamily = props[QStringLiteral(
"font" )].toString();
3496 if ( props.contains( QStringLiteral(
"chr" ) ) && props[QStringLiteral(
"chr" )].toString().length() > 0 )
3498 string = props[
"chr"].toString();
3499 const thread_local QRegularExpression charRegExp( QStringLiteral(
"%1([0-9]+)%1" ).arg(
FONTMARKER_CHR_FIX ) );
3500 QRegularExpressionMatch match = charRegExp.match(
string );
3501 while ( match.hasMatch() )
3503 QChar replacement = QChar( match.captured( 1 ).toUShort() );
3504 string =
string.mid( 0, match.capturedStart( 0 ) ) + replacement +
string.mid( match.capturedEnd( 0 ) );
3505 match = charRegExp.match(
string );
3509 if ( props.contains( QStringLiteral(
"size" ) ) )
3510 pointSize = props[QStringLiteral(
"size" )].toDouble();
3511 if ( props.contains( QStringLiteral(
"color" ) ) )
3513 if ( props.contains( QStringLiteral(
"angle" ) ) )
3514 angle = props[QStringLiteral(
"angle" )].toDouble();
3518 if ( props.contains( QStringLiteral(
"font_style" ) ) )
3519 m->
setFontStyle( props[QStringLiteral(
"font_style" )].toString() );
3520 if ( props.contains( QStringLiteral(
"outline_color" ) ) )
3522 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
3523 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
3524 if ( props.contains( QStringLiteral(
"offset" ) ) )
3526 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
3528 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
3530 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
3532 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
3534 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
3536 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
3538 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
3540 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
3542 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
3552 return QStringLiteral(
"FontMarker" );
3562 QColor brushColor =
mColor;
3563 QColor penColor = mStrokeColor;
3565 brushColor.setAlphaF(
mColor.alphaF() * context.
opacity() );
3566 penColor.setAlphaF( mStrokeColor.alphaF() * context.
opacity() );
3568 mBrush = QBrush( brushColor );
3569 mPen = QPen( penColor );
3570 mPen.setJoinStyle( mPenJoinStyle );
3574 if ( !mFontStyle.isEmpty() )
3582 if ( mNonZeroFontSize && sizePixels > MAX_FONT_CHARACTER_SIZE_IN_PIXELS )
3587 mFontSizeScale = sizePixels / MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
3588 sizePixels = MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
3591 mFontSizeScale = 1.0;
3595 mFont.setPixelSize( std::max( 2,
static_cast< int >( std::round( sizePixels ) ) ) );
3596 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3597 mChrWidth = mFontMetrics->horizontalAdvance( mString );
3598 mChrOffset = QPointF( mChrWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3605 if ( mUseCachedPath )
3607 QPointF chrOffset = mChrOffset;
3609 const QString charToRender = characterToRender( context, chrOffset, chrWidth );
3610 mCachedPath = QPainterPath();
3611 mCachedPath.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
3620QString QgsFontMarkerSymbolLayer::characterToRender(
QgsSymbolRenderContext &context, QPointF &charOffset,
double &charWidth )
3622 charOffset = mChrOffset;
3623 QString stringToRender = mString;
3628 if ( stringToRender != mString )
3630 charWidth = mFontMetrics->horizontalAdvance( stringToRender );
3631 charOffset = QPointF( charWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3634 return stringToRender;
3639 bool &hasDataDefinedRotation,
3641 double &angle )
const
3646 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
3647 offset = QPointF( offsetX, offsetY );
3663 if ( hasDataDefinedRotation )
3687 double scaledSize =
mSize;
3691 if ( hasDataDefinedSize )
3697 if ( hasDataDefinedSize && ok )
3702 scaledSize = std::sqrt( scaledSize );
3714 if ( !p || !mNonZeroFontSize )
3717 QTransform transform;
3720 QColor brushColor =
mColor;
3730 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
3732 mBrush.setColor( brushColor );
3734 QColor penColor = mStrokeColor;
3740 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
3764 p->setBrush( mBrush );
3767 mPen.setColor( penColor );
3768 mPen.setWidthF( penWidth );
3773 p->setPen( Qt::NoPen );
3791 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3794 QPointF chrOffset = mChrOffset;
3796 const QString charToRender = characterToRender( context, chrOffset, chrWidth );
3798 const double sizeToRender = calculateSize( context );
3800 bool hasDataDefinedRotation =
false;
3803 calculateOffsetAndRotation( context, sizeToRender, hasDataDefinedRotation,
offset,
angle );
3805 p->translate( point.x() +
offset.x(), point.y() +
offset.y() );
3808 transform.rotate(
angle );
3812 const double s = sizeToRender / mOrigSize;
3813 transform.scale( s, s );
3817 transform.scale( mFontSizeScale, mFontSizeScale );
3819 if ( mUseCachedPath )
3821 p->drawPath( transform.map( mCachedPath ) );
3826 path.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
3827 p->drawPath( transform.map( path ) );
3834 props[QStringLiteral(
"font" )] = mFontFamily;
3835 props[QStringLiteral(
"font_style" )] = mFontStyle;
3836 QString chr = mString;
3837 for (
int i = 0; i < 32; i++ )
3839 if ( i == 9 || i == 10 || i == 13 )
3843 chr.replace( QChar( i ), QStringLiteral(
"%1%2%1" ).arg(
FONTMARKER_CHR_FIX, QString::number( i ) ) );
3845 props[QStringLiteral(
"chr" )] = chr;
3846 props[QStringLiteral(
"size" )] = QString::number(
mSize );
3851 props[QStringLiteral(
"outline_width" )] = QString::number( mStrokeWidth );
3855 props[QStringLiteral(
"angle" )] = QString::number(
mAngle );
3888 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
3889 element.appendChild( graphicElem );
3891 const QString fontPath = QStringLiteral(
"ttf://%1" ).arg( mFontFamily );
3892 int markIndex = !mString.isEmpty() ? mString.at( 0 ).unicode() : 0;
3899 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
3902 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
3925 mStrokeWidthUnit = unit;
3930 QPointF chrOffset = mChrOffset;
3931 double chrWidth = mChrWidth;
3933 ( void )characterToRender( context, chrOffset, chrWidth );
3935 if ( !mFontMetrics )
3936 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3938 double scaledSize = calculateSize( context );
3941 chrWidth *= scaledSize / mOrigSize;
3943 chrWidth *= mFontSizeScale;
3945 bool hasDataDefinedRotation =
false;
3948 calculateOffsetAndRotation( context, scaledSize, hasDataDefinedRotation,
offset,
angle );
3951 QTransform transform;
3954 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
3957 transform.rotate(
angle );
3959 QRectF symbolBounds = transform.mapRect( QRectF( -chrWidth / 2.0,
3963 return symbolBounds;
3970 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
3971 if ( graphicElem.isNull() )
3974 QString name, format;
3982 if ( !name.startsWith( QLatin1String(
"ttf://" ) ) || format != QLatin1String(
"ttf" ) )
3992 const double d = angleFunc.toDouble( &ok );
4000 double scaleFactor = 1.0;
4001 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
4022 context.
pushMessage( QObject::tr(
"Font “%1” not available on system" ).arg( processedFamily ) );
4028 QMap<QString, QgsProperty>::iterator it =
mParameters.begin();
4040 QMap<QString, QgsProperty>::const_iterator it =
mParameters.constBegin();
4043 attrs.unite( it.value().referencedFields( context.
expressionContext(),
true ) );
4067 if (
properties.contains( QStringLiteral(
"imageFile" ) ) )
4069 if (
properties.contains( QStringLiteral(
"size" ) ) )
4071 if (
properties.contains( QStringLiteral(
"angle" ) ) )
4074 auto m = std::make_unique< QgsAnimatedMarkerSymbolLayer >(
path,
size,
angle );
4075 m->setFrameRate(
properties.value( QStringLiteral(
"frameRate" ), QStringLiteral(
"10" ) ).toDouble() );
4083 return QStringLiteral(
"AnimatedMarker" );
4089 res.insert( QStringLiteral(
"frameRate" ), mFrameRateFps );
4095 auto m = std::make_unique< QgsAnimatedMarkerSymbolLayer >(
mPath,
mSize,
mAngle );
4096 m->setFrameRate( mFrameRateFps );
4105 mPreparedPaths.clear();
4113 mStaticPath =
false;
4119 if ( !mStaticPath && !mPreparedPaths.contains(
path ) )
4122 mPreparedPaths.insert(
path );
4125 const long long mapFrameNumber = context.
currentFrame();
4127 const double markerAnimationDuration = totalFrameCount / mFrameRateFps;
4129 double animationTimeSeconds = 0;
4130 if ( mapFrameNumber >= 0 && context.
frameRate() > 0 )
4133 animationTimeSeconds = mapFrameNumber / context.
frameRate();
4138 animationTimeSeconds = QDateTime::currentMSecsSinceEpoch() / 1000.0;
4141 const double markerAnimationProgressSeconds = std::fmod( animationTimeSeconds, markerAnimationDuration );
4142 const int movieFrame =
static_cast< int >( std::floor( markerAnimationProgressSeconds * mFrameRateFps ) );
4144 bool cached =
false;
@ DynamicRotation
Rotation of symbol may be changed during rendering and symbol should not be cached.
@ IsSymbolLayerSubSymbol
Symbol is being rendered as a sub-symbol of a QgsSymbolLayer.
@ CanCalculateMaskGeometryPerFeature
If present, indicates that mask geometry can safely be calculated per feature for the symbol layer....
ScaleMethod
Scale methods.
@ ScaleDiameter
Calculate scale by the diameter.
@ ScaleArea
Calculate scale by the area.
QFlags< SymbolLayerFlag > SymbolLayerFlags
Symbol layer flags.
MarkerShape
Marker shapes.
@ EquilateralTriangle
Equilateral triangle.
@ SemiCircle
Semi circle (top half)
@ QuarterCircle
Quarter circle (top left quarter)
@ LeftHalfTriangle
Left half of triangle.
@ ArrowHead
Right facing arrow head (unfilled, lines only)
@ ParallelogramRight
Parallelogram that slants right.
@ AsteriskFill
A filled asterisk shape.
@ HalfArc
A line-only half arc.
@ QuarterSquare
Quarter square (top left quarter)
@ Cross2
Rotated cross (lines only), 'x' shape.
@ ArrowHeadFilled
Right facing filled arrow head.
@ Shield
A shape consisting of a triangle attached to a rectangle.
@ HalfSquare
Half square (left half)
@ CrossFill
Solid filled cross.
@ RoundedSquare
A square with rounded corners.
@ RightHalfTriangle
Right half of triangle.
@ ThirdCircle
One third circle (top left third)
@ ThirdArc
A line-only one third arc.
@ SquareWithCorners
A square with diagonal corners.
@ QuarterArc
A line-only one quarter arc.
@ DiamondStar
A 4-sided star.
@ Cross
Cross (lines only)
@ ParallelogramLeft
Parallelogram that slants left.
@ DiagonalHalfSquare
Diagonal half square (bottom left half)
RenderUnit
Rendering size units.
@ Percentage
Percentage of another measurement (e.g., canvas size, feature size)
@ Millimeters
Millimeters.
@ Unknown
Mixed or unknown units.
@ MetersInMapUnits
Meters value as Map units.
@ RenderingSubSymbol
Set whenever a sub-symbol of a parent symbol is currently being rendered. Can be used during symbol a...
@ RenderSymbolPreview
The render is for a symbol preview only and map based properties may not be available,...
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
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.
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.
QString valueAsString(int key, const QgsExpressionContext &context, const QString &defaultString=QString(), bool *ok=nullptr) const
Calculates the current value of the property with the specified key and interprets it as a string.
Animated marker symbol layer class.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsAnimatedMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
~QgsAnimatedMarkerSymbolLayer() override
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
QImage fetchImage(QgsRenderContext &context, const QString &path, QSize size, bool preserveAspectRatio, double opacity) const override
Fetches the image to render.
QgsAnimatedMarkerSymbolLayer(const QString &path=QString(), double size=DEFAULT_RASTERMARKER_SIZE, double angle=DEFAULT_RASTERMARKER_ANGLE)
Constructor for animated marker symbol layer using the specified source image path.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates an animated marker symbol layer from a string map of properties.
QString layerType() const override
Returns a string that represents this layer type.
static QgsImageCache * imageCache()
Returns the application's image cache, used for caching resampled versions of raster images.
static QgsSvgCache * svgCache()
Returns the application's SVG cache, used for caching SVG images and handling parameter replacement w...
static QgsFontManager * fontManager()
Returns the application font manager, which manages available fonts and font installation for the QGI...
static QColor colorFromString(const QString &string)
Decodes a string into a color value.
static QString colorToString(const QColor &color)
Encodes a color into a string value.
Exports QGIS layers to the DXF format.
void writeFilledCircle(const QString &layer, const QColor &color, const QgsPoint &pt, double radius)
Write filled circle (as hatch)
void writeCircle(const QString &layer, const QColor &color, const QgsPoint &pt, double radius, const QString &lineStyleName, double width)
Write circle (as polyline)
static double mapUnitScaleFactor(double scale, Qgis::RenderUnit symbolUnits, Qgis::DistanceUnit mapUnits, double mapUnitsPerPixel=1.0)
Returns scale factor for conversion to map units.
void writeLine(const QgsPoint &pt1, const QgsPoint &pt2, const QString &layer, const QString &lineStyleName, const QColor &color, double width=-1)
Write line (as a polyline)
void writePolygon(const QgsRingSequence &polygon, const QString &layer, const QString &hatchPattern, const QColor &color)
Draw dxf filled polygon (HATCH)
Qgis::DistanceUnit mapUnits() const
Retrieve map units.
double symbologyScale() const
Returns the reference scale for output.
void clipValueToMapUnitScale(double &value, const QgsMapUnitScale &scale, double pixelToMMFactor) const
Clips value to scale minimum/maximum.
void writePolyline(const QgsPointSequence &line, const QString &layer, const QString &lineStyleName, const QColor &color, double width=-1)
Draw dxf primitives (LWPOLYLINE)
A paint device for drawing into dxf files.
void setShift(QPointF shift)
void setLayer(const QString &layer)
void setOutputSize(const QRectF &r)
void setDrawingSize(QSizeF size)
The feature class encapsulates a single feature including its unique ID, geometry and a list of field...
bool hasGeometry() const
Returns true if the feature has an associated geometry.
A fill symbol type, for rendering Polygon and MultiPolygon geometries.
static QgsFillSymbol * createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
Filled marker symbol layer, consisting of a shape which is rendered using a QgsFillSymbol.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QColor color() const override
Returns the "representative" color of the symbol layer.
QgsFilledMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
~QgsFilledMarkerSymbolLayer() override
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void setColor(const QColor &c) override
Sets the "representative" color for the symbol layer.
QString layerType() const override
Returns a string that represents this layer type.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsFilledMarkerSymbolLayer.
QgsFilledMarkerSymbolLayer(Qgis::MarkerShape shape=Qgis::MarkerShape::Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructor for QgsFilledMarkerSymbolLayer.
QString processFontFamilyName(const QString &name) const
Processes a font family name, applying any matching fontFamilyReplacements() to the name.
void setStrokeWidthUnit(Qgis::RenderUnit unit)
Sets the stroke width unit.
~QgsFontMarkerSymbolLayer() override
void setStrokeColor(const QColor &color) override
Sets the stroke color for the symbol layer.
QgsFontMarkerSymbolLayer(const QString &fontFamily=DEFAULT_FONTMARKER_FONT, QString chr=DEFAULT_FONTMARKER_CHR, double pointSize=DEFAULT_FONTMARKER_SIZE, const QColor &color=DEFAULT_FONTMARKER_COLOR, double angle=DEFAULT_FONTMARKER_ANGLE)
Constructs a font marker symbol layer.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the stroke width map unit scale.
double strokeWidth() const
Returns the marker's stroke width.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
void setFontStyle(const QString &style)
Sets the font style for the font which will be used to render the point.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QString fontStyle() const
Returns the font style for the associated font which will be used to render the point.
QString fontFamily() const
Returns the font family name for the associated font which will be used to render the point.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Writes the symbol layer definition as a SLD XML element.
void setStrokeWidth(double width)
Set's the marker's stroke width.
static void resolveFonts(const QVariantMap &properties, const QgsReadWriteContext &context)
Resolves fonts from a properties map, raising warnings in the specified context if the required fonts...
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
void setPenJoinStyle(Qt::PenJoinStyle style)
Sets the stroke join style.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsFontMarkerSymbolLayer from an SLD XML element.
QgsFontMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
QString layerType() const override
Returns a string that represents this layer type.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsFontMarkerSymbolLayer from a property map (see properties())
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
static QString translateNamedStyle(const QString &namedStyle)
Returns the localized named style of a font, if such a translation is available.
static QFont createFont(const QString &family, int pointSize=-1, int weight=-1, bool italic=false)
Creates a font with the specified family.
static bool fontFamilyMatchOnSystem(const QString &family, QString *chosen=nullptr, bool *match=nullptr)
Check whether font family is on system.
static bool updateFontViaStyle(QFont &f, const QString &fontstyle, bool fallback=false)
Updates font with named style and retain all font properties.
static void setFontFamily(QFont &font, const QString &family)
Sets the family for a font object.
QSize originalSize(const QString &path, bool blocking=false) const
Returns the original size (in pixels) of the image at the specified path.
int totalFrameCount(const QString &path, bool blocking=false)
Returns the total frame count of the image at the specified path.
QImage pathAsImage(const QString &path, const QSize size, const bool keepAspectRatio, const double opacity, bool &fitsInCache, bool blocking=false, double targetDpi=96, int frameNumber=-1, bool *isMissing=nullptr)
Returns the specified path rendered as an image.
void prepareAnimation(const QString &path)
Prepares for optimized retrieval of frames for the animation at the given path.
static void overlayColor(QImage &image, const QColor &color)
Overlays a color onto an image.
Perform transforms between map coordinates and device coordinates.
double mapUnitsPerPixel() const
Returns the current map units per pixel.
double mapRotation() const
Returns the current map rotation in degrees (clockwise).
Struct for storing maximum and minimum scales for measurements in map units.
Abstract base class for marker symbol layers.
Qgis::RenderUnit mOffsetUnit
Offset units.
QPointF offset() const
Returns the marker's offset, which is the horizontal and vertical displacement which the rendered mar...
double mLineAngle
Line rotation angle (see setLineAngle() for details)
HorizontalAnchorPoint
Symbol horizontal anchor points.
void setOffsetUnit(Qgis::RenderUnit unit)
Sets the units for the symbol's offset.
void setAngle(double angle)
Sets the rotation angle for the marker.
Qgis::ScaleMethod scaleMethod() const
Returns the method to use for scaling the marker's size.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setVerticalAnchorPoint(VerticalAnchorPoint v)
Sets the vertical anchor point for positioning the symbol.
QPointF mOffset
Marker offset.
void setHorizontalAnchorPoint(HorizontalAnchorPoint h)
Sets the horizontal anchor point for positioning the symbol.
QgsMapUnitScale mapUnitScale() const override
void setOffset(QPointF offset)
Sets the marker's offset, which is the horizontal and vertical displacement which the rendered marker...
void setSizeMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol's size.
double size() const
Returns the symbol size.
QgsMapUnitScale mOffsetMapUnitScale
Offset map unit scale.
HorizontalAnchorPoint mHorizontalAnchorPoint
Horizontal anchor point.
static QPointF _rotatedOffset(QPointF offset, double angle)
Adjusts a marker offset to account for rotation.
Qgis::ScaleMethod mScaleMethod
Marker size scaling method.
QgsMapUnitScale mSizeMapUnitScale
Marker size map unit scale.
Qgis::RenderUnit mSizeUnit
Marker size unit.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void setSizeUnit(Qgis::RenderUnit unit)
Sets the units for the symbol's size.
VerticalAnchorPoint
Symbol vertical anchor points.
void markerOffset(QgsSymbolRenderContext &context, double &offsetX, double &offsetY) const
Calculates the required marker offset, including both the symbol offset and any displacement required...
VerticalAnchorPoint mVerticalAnchorPoint
Vertical anchor point.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol's offset.
double mAngle
Marker rotation angle, in degrees clockwise from north.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
double angle() const
Returns the rotation angle for the marker, in degrees clockwise from north.
void setMapUnitScale(const QgsMapUnitScale &scale) override
static void drawPicture(QPainter *painter, const QPointF &point, const QPicture &picture)
Draws a picture onto a painter, correctly applying workarounds to avoid issues with incorrect scaling...
Resolves relative paths into absolute paths and vice versa.
Point geometry type, with support for z-dimension and m-values.
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const final
Returns the calculated value of the property with the specified key from within the collection.
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
QgsProperty property(int key) const final
Returns a matching property from the collection, if one exists.
QString asExpression() const
Returns an expression string representing the state of the property, or an empty string if the proper...
static QVariantMap propertyMapToVariantMap(const QMap< QString, QgsProperty > &propertyMap)
Convert a map of QgsProperty to a map of QVariant This is useful to save a map of properties.
static QMap< QString, QgsProperty > variantMapToPropertyMap(const QVariantMap &variantMap)
Convert a map of QVariant to a map of QgsProperty This is useful to restore a map of properties.
static QgsProperty fromValue(const QVariant &value, bool isActive=true)
Returns a new StaticProperty created from the specified value.
Raster marker symbol layer class.
double mFixedAspectRatio
The marker fixed aspect ratio.
QColor color() const override
Returns the "representative" color of the symbol layer.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QgsMapUnitScale mapUnitScale() const override
void copyCommonProperties(QgsRasterMarkerSymbolLayer *other) const
Copies common properties to another layer.
void setOpacity(double opacity)
Set the marker opacity.
QString path() const
Returns the marker raster image path.
double calculateAspectRatio(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedAspectRatio) const
Calculates the marker aspect ratio between width and height.
QgsRasterMarkerSymbolLayer(const QString &path=QString(), double size=DEFAULT_SVGMARKER_SIZE, double angle=DEFAULT_SVGMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructs raster marker symbol layer with picture from given absolute path to a raster image file.
void setPath(const QString &path)
Set the marker raster image path.
virtual QImage fetchImage(QgsRenderContext &context, const QString &path, QSize size, bool preserveAspectRatio, double opacity) const
Fetches the image to render.
double defaultAspectRatio() const
Returns the default marker aspect ratio between width and height, 0 if not yet calculated.
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
void setFixedAspectRatio(double ratio)
Set the marker aspect ratio between width and height to be used in rendering, if the value set is low...
void setMapUnitScale(const QgsMapUnitScale &scale) override
void setCommonProperties(const QVariantMap &properties)
Sets common class properties from a properties map.
QgsRasterMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool preservedAspectRatio() const
Returns the preserved aspect ratio value, true if fixed aspect ratio has been lower or equal to 0.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
~QgsRasterMarkerSymbolLayer() override
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a raster marker symbol layer from a string map of properties.
double mOpacity
The marker default opacity.
double updateDefaultAspectRatio()
Calculates the default marker aspect ratio between width and height.
double mDefaultAspectRatio
The marker default aspect ratio.
bool setPreservedAspectRatio(bool par)
Set preserved the marker aspect ratio between width and height.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QString layerType() const override
Returns a string that represents this layer type.
double opacity() const
Returns the marker opacity.
The class is used as a container of context for various read/write operations on other objects.
void pushMessage(const QString &message, Qgis::MessageLevel level=Qgis::MessageLevel::Warning) const
Append a message to the context.
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
QgsExpressionContext & expressionContext()
Gets the expression context.
long long currentFrame() const
Returns the current frame number of the map (in frames per second), for maps which are part of an ani...
float devicePixelRatio() const
Returns the device pixel ratio.
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
double frameRate() const
Returns the frame rate of the map, for maps which are part of an animation.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QColor selectionColor() const
Returns the color to use when rendering selected features.
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
const QgsPathResolver & pathResolver() const
Returns the path resolver for conversion between relative and absolute paths during rendering operati...
Scoped object for saving and restoring a QPainter object's state.
Abstract base class for simple marker symbol layers.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
void calculateOffsetAndRotation(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedRotation, QPointF &offset, double &angle) const
Calculates the marker offset and rotation.
Qgis::MarkerShape mShape
Symbol shape.
QPainterPath mPath
Painter path representing shape. If mPolygon is empty then the shape is stored in mPath.
bool shapeToPolygon(Qgis::MarkerShape shape, QPolygonF &polygon) const
Creates a polygon representing the specified shape.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
static QList< Qgis::MarkerShape > availableShapes()
Returns a list of all available shape types.
~QgsSimpleMarkerSymbolLayerBase() override
static bool shapeIsFilled(Qgis::MarkerShape shape)
Returns true if a symbol shape has a fill.
QPolygonF mPolygon
Polygon of points in shape. If polygon is empty then shape is using mPath.
Qgis::MarkerShape shape() const
Returns the shape for the rendered marker symbol.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
QgsSimpleMarkerSymbolLayerBase(Qgis::MarkerShape shape=Qgis::MarkerShape::Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructor for QgsSimpleMarkerSymbolLayerBase.
static QString encodeShape(Qgis::MarkerShape shape)
Encodes a shape to its string representation.
double calculateSize(QgsSymbolRenderContext &context, bool &hasDataDefinedSize) const
Calculates the desired size of the marker, considering data defined size overrides.
static Qgis::MarkerShape decodeShape(const QString &name, bool *ok=nullptr)
Attempts to decode a string representation of a shape name to the corresponding shape.
bool prepareMarkerPath(Qgis::MarkerShape symbol)
Prepares the layer for drawing the specified shape (QPainterPath version)
bool prepareMarkerShape(Qgis::MarkerShape shape)
Prepares the layer for drawing the specified shape (QPolygonF version)
Simple marker symbol layer, consisting of a rendered shape with solid fill color and an stroke.
QPen mSelPen
QPen to use as stroke of selected symbols.
void setColor(const QColor &color) override
Sets the "representative" color for the symbol layer.
QColor mStrokeColor
Stroke color.
QImage mSelCache
Cached image of selected marker, if using cached version.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QImage mCache
Cached image of marker, if using cached version.
QBrush mSelBrush
QBrush to use as fill of selected symbols.
void setFillColor(const QColor &color) override
Sets the fill color for the symbol layer.
Qt::PenJoinStyle penJoinStyle() const
Returns the marker's stroke join style (e.g., miter, bevel, etc).
void drawMarker(QPainter *p, QgsSymbolRenderContext &context)
Draws the marker shape in the specified painter.
QPen mPen
QPen corresponding to marker's stroke style.
Qgis::RenderUnit mStrokeWidthUnit
Stroke width units.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsSimpleMarkerSymbolLayer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
void setMapUnitScale(const QgsMapUnitScale &scale) override
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
void setStrokeWidthUnit(Qgis::RenderUnit u)
Sets the unit for the width of the marker's stroke.
QColor color() const override
Returns the "representative" color of the symbol layer.
QgsMapUnitScale mapUnitScale() const override
Qt::PenStyle mStrokeStyle
Stroke style.
QgsSimpleMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsSimpleMarkerSymbolLayer from an SLD XML element.
~QgsSimpleMarkerSymbolLayer() override
Qt::PenCapStyle mPenCapStyle
Stroke pen cap style.
QString layerType() const override
Returns a string that represents this layer type.
double mStrokeWidth
Stroke width.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the map scale for the width of the marker's stroke.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
void setStrokeStyle(Qt::PenStyle strokeStyle)
Sets the marker's stroke style (e.g., solid, dashed, etc)
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QColor fillColor() const override
Returns the fill color for the symbol layer.
QColor strokeColor() const override
Returns the marker's stroke color.
QBrush mBrush
QBrush corresponding to marker's fill style.
void setStrokeWidth(double w)
Sets the width of the marker's stroke.
void setStrokeColor(const QColor &color) override
Sets the marker's stroke color.
Qt::PenStyle strokeStyle() const
Returns the marker's stroke style (e.g., solid, dashed, etc)
bool mUsingCache
true if using cached images of markers for drawing.
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
void setPenCapStyle(Qt::PenCapStyle style)
Sets the marker's stroke cap style (e.g., flat, round, etc).
bool writeDxf(QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift=QPointF(0.0, 0.0)) const override
write as DXF
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Writes the symbol layer definition as a SLD XML element.
static const int MAXIMUM_CACHE_WIDTH
Maximum width/height of cache image.
QString ogrFeatureStyle(double mmScaleFactor, double mapUnitScaleFactor) const override
bool prepareCache(QgsSymbolRenderContext &context)
Prepares cache image.
QgsMapUnitScale mStrokeWidthMapUnitScale
Stroke width map unit scale.
QgsSimpleMarkerSymbolLayer(Qgis::MarkerShape shape=Qgis::MarkerShape::Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD, const QColor &color=DEFAULT_SIMPLEMARKER_COLOR, const QColor &strokeColor=DEFAULT_SIMPLEMARKER_BORDERCOLOR, Qt::PenJoinStyle penJoinStyle=DEFAULT_SIMPLEMARKER_JOINSTYLE)
Constructor for QgsSimpleMarkerSymbolLayer.
double strokeWidth() const
Returns the width of the marker's stroke.
Qt::PenJoinStyle mPenJoinStyle
Stroke pen join style.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
QSizeF svgViewboxSize(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Calculates the viewbox size of a (possibly cached) SVG file.
QPicture svgAsPicture(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool forceVectorOutput=false, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Returns an SVG drawing as a QPicture.
void containsParams(const QString &path, bool &hasFillParam, QColor &defaultFillColor, bool &hasStrokeParam, QColor &defaultStrokeColor, bool &hasStrokeWidthParam, double &defaultStrokeWidth, bool blocking=false) const
Tests if an SVG file contains parameters for fill, stroke color, stroke width.
QImage svgAsImage(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, bool &fitsInCache, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >())
Returns an SVG drawing as a QImage.
QByteArray svgContent(const QString &path, double size, const QColor &fill, const QColor &stroke, double strokeWidth, double widthScaleFactor, double fixedAspectRatio=0, bool blocking=false, const QMap< QString, QString > ¶meters=QMap< QString, QString >(), bool *isMissingImage=nullptr)
Gets the SVG content corresponding to the given path.
QgsSvgMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
QColor fillColor() const override
Returns the fill color for the symbol layer.
QgsMapUnitScale mapUnitScale() const override
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates the symbol.
double mDefaultAspectRatio
The marker default aspect ratio.
QString layerType() const override
Returns a string that represents this layer type.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
QString path() const
Returns the marker SVG path.
Qgis::SymbolLayerFlags flags() const override
Returns flags which control the symbol layer's behavior.
bool preservedAspectRatio() const
Returns the preserved aspect ratio value, true if fixed aspect ratio has been lower or equal to 0.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
void setStrokeWidth(double w)
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
void prepareExpressions(const QgsSymbolRenderContext &context) override
Prepares all data defined property expressions for evaluation.
QMap< QString, QgsProperty > mParameters
bool setPreservedAspectRatio(bool par)
Set preserved the marker aspect ratio between width and height.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
double calculateAspectRatio(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedAspectRatio) const
Calculates the marker aspect ratio between width and height.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
static QgsSymbolLayer * createFromSld(QDomElement &element)
void setStrokeWidthUnit(Qgis::RenderUnit unit)
Sets the units for the stroke width.
void setStrokeColor(const QColor &c) override
Sets the stroke color for the symbol layer.
void setMapUnitScale(const QgsMapUnitScale &scale) override
double updateDefaultAspectRatio()
Calculates the default marker aspect ratio between width and height.
QColor strokeColor() const override
Returns the stroke color for the symbol layer.
void setFillColor(const QColor &color) override
Sets the fill color for the symbol layer.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
double strokeWidth() const
QgsSvgMarkerSymbolLayer(const QString &path, double size=DEFAULT_SVGMARKER_SIZE, double angle=DEFAULT_SVGMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructs SVG marker symbol layer with picture from given absolute path to a SVG file.
void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Writes the symbol layer definition as a SLD XML element.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
~QgsSvgMarkerSymbolLayer() override
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
static void resolvePaths(QVariantMap &properties, const QgsPathResolver &pathResolver, bool saving)
Turns relative paths in properties map to absolute when reading and vice versa when writing.
QMap< QString, QgsProperty > parameters() const
Returns the dynamic SVG parameters.
QgsMapUnitScale mStrokeWidthMapUnitScale
Qgis::RenderUnit mStrokeWidthUnit
void setParameters(const QMap< QString, QgsProperty > ¶meters)
Sets the dynamic SVG parameters.
double mFixedAspectRatio
The marker fixed aspect ratio.
bool writeDxf(QgsDxfExport &e, double mmMapUnitScaleFactor, const QString &layerName, QgsSymbolRenderContext &context, QPointF shift=QPointF(0.0, 0.0)) const override
write as DXF
void setFixedAspectRatio(double ratio)
Set the marker aspect ratio between width and height to be used in rendering, if the value set is low...
void setPath(const QString &path)
Set the marker SVG path.
static bool externalMarkerFromSld(QDomElement &element, QString &path, QString &format, int &markIndex, QColor &color, double &size)
static bool rotationFromSldElement(QDomElement &element, QString &rotationFunc)
static QString encodePenStyle(Qt::PenStyle style)
static Qt::PenJoinStyle decodePenJoinStyle(const QString &str)
static QString encodeMapUnitScale(const QgsMapUnitScale &mapUnitScale)
static QgsStringMap evaluatePropertiesMap(const QMap< QString, QgsProperty > &propertiesMap, const QgsExpressionContext &context)
Evaluates a map of properties using the given context and returns a variant map with evaluated expres...
static bool displacementFromSldElement(QDomElement &element, QPointF &offset)
static QString svgSymbolPathToName(const QString &path, const QgsPathResolver &pathResolver)
Determines an SVG symbol's name from its path.
static QPointF toPoint(const QVariant &value, bool *ok=nullptr)
Converts a value to a point.
static void multiplyImageOpacity(QImage *image, qreal opacity)
Multiplies opacity of image pixel values with a (global) transparency value.
static QgsMapUnitScale decodeMapUnitScale(const QString &str)
static double rescaleUom(double size, Qgis::RenderUnit unit, const QVariantMap &props)
Rescales the given size based on the uomScale found in the props, if any is found,...
static Qt::PenCapStyle decodePenCapStyle(const QString &str)
static bool externalGraphicFromSld(QDomElement &element, QString &path, QString &mime, QColor &color, double &size)
static void parametricSvgToSld(QDomDocument &doc, QDomElement &graphicElem, const QString &path, const QColor &fillColor, double size, const QColor &strokeColor, double strokeWidth)
Encodes a reference to a parametric SVG into SLD, as a succession of parametric SVG using URL paramet...
static Qgis::ScaleMethod decodeScaleMethod(const QString &str)
Decodes a symbol scale method from a string.
static QString encodePenCapStyle(Qt::PenCapStyle style)
static void externalMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &format, int *markIndex=nullptr, const QColor &color=QColor(), double size=-1)
static bool wellKnownMarkerFromSld(QDomElement &element, QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle, double &strokeWidth, double &size)
static void createDisplacementElement(QDomDocument &doc, QDomElement &element, QPointF offset)
static QString svgSymbolNameToPath(const QString &name, const QgsPathResolver &pathResolver)
Determines an SVG symbol's path from its name.
static QString encodeColor(const QColor &color)
static Qgis::RenderUnit decodeSldUom(const QString &str, double *scaleFactor=nullptr)
Decodes a SLD unit of measure string to a render unit.
static double estimateMaxSymbolBleed(QgsSymbol *symbol, const QgsRenderContext &context)
Returns the maximum estimated bleed for the symbol.
static void wellKnownMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &name, const QColor &color, const QColor &strokeColor, Qt::PenStyle strokeStyle, double strokeWidth=-1, double size=-1)
static QString encodeScaleMethod(Qgis::ScaleMethod scaleMethod)
Encodes a symbol scale method to a string.
static Qt::PenStyle decodePenStyle(const QString &str)
static void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
static QString encodePoint(QPointF point)
Encodes a QPointF to a string.
static QString encodePenJoinStyle(Qt::PenJoinStyle style)
static QPointF decodePoint(const QString &string)
Decodes a QSizeF from a string.
bool shouldRenderUsingSelectionColor(const QgsSymbolRenderContext &context) const
Returns true if the symbol layer should be rendered using the selection color from the render context...
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
bool installMasks(QgsRenderContext &context, bool recursive, const QRectF &rect=QRectF())
When rendering, install masks on context painter.
void removeMasks(QgsRenderContext &context, bool recursive)
When rendering, remove previously installed masks from context painter if recursive is true masks are...
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
@ StrokeStyle
Stroke style (eg solid, dashed)
@ Name
Name, eg shape name for simple markers.
@ Character
Character, eg for font marker symbol layers.
@ StrokeColor
Stroke color.
@ CapStyle
Line cap style.
@ JoinStyle
Line join style.
@ StrokeWidth
Stroke width.
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
virtual void startRender(QgsSymbolRenderContext &context)=0
Called before a set of rendering operations commences on the supplied render context.
virtual void prepareExpressions(const QgsSymbolRenderContext &context)
Prepares all data defined property expressions for evaluation.
virtual QColor color() const
Returns the "representative" color of the symbol layer.
virtual void setOutputUnit(Qgis::RenderUnit unit)
Sets the units to use for sizes and widths within the symbol layer.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
virtual Qgis::SymbolLayerFlags flags() const
Returns flags which control the symbol layer's behavior.
QgsPropertyCollection mDataDefinedProperties
virtual bool hasDataDefinedProperties() const
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
const QgsFeature * feature() const
Returns the current feature being rendered.
QgsFields fields() const
Fields of the layer.
Qgis::SymbolRenderHints renderHints() const
Returns the rendering hint flags for the symbol.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
bool forceVectorRendering() const
Returns true if symbol must be rendered using vector methods, and optimisations like pre-rendered ima...
qreal opacity() const
Returns the opacity for the symbol.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Abstract base class for all rendered symbols.
Qgis::SymbolType type() const
Returns the symbol's type.
static Q_INVOKABLE Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
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
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QMap< QString, QString > QgsStringMap
QVector< QgsPointSequence > QgsRingSequence
QVector< QgsPoint > QgsPointSequence
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
#define DEFAULT_FONTMARKER_JOINSTYLE
#define DEFAULT_RASTERMARKER_ANGLE
#define DEFAULT_RASTERMARKER_SIZE
#define DEFAULT_SVGMARKER_ANGLE
#define DEFAULT_SIMPLEMARKER_JOINSTYLE
#define DEFAULT_FONTMARKER_CHR
#define DEFAULT_SIMPLEMARKER_BORDERCOLOR
#define DEFAULT_SIMPLEMARKER_SIZE
#define DEFAULT_SIMPLEMARKER_NAME
#define DEFAULT_SIMPLEMARKER_ANGLE
#define DEFAULT_SVGMARKER_SIZE
#define DEFAULT_FONTMARKER_FONT
#define DEFAULT_FONTMARKER_BORDERCOLOR
#define DEFAULT_FONTMARKER_ANGLE
#define DEFAULT_FONTMARKER_COLOR
#define DEFAULT_FONTMARKER_SIZE
#define DEFAULT_SIMPLEMARKER_COLOR
#define DEFAULT_SCALE_METHOD
#define FONTMARKER_CHR_FIX