34#include <QSvgRenderer>
37#include <QDomDocument>
46static constexpr int MAX_FONT_CHARACTER_SIZE_IN_PIXELS = 500;
48static void _fixQPictureDPI( QPainter *p )
54 p->scale(
static_cast< double >(
qt_defaultDpiX() ) / p->device()->logicalDpiX(),
55 static_cast< double >(
qt_defaultDpiY() ) / p->device()->logicalDpiY() );
68 QList< Qgis::MarkerShape > shapes;
183 QTransform transform;
186 if ( !hasDataDefinedSize )
196 const double half = scaledSize / 2.0;
197 transform.scale( half, half );
203 transform.rotate(
mAngle );
230 bool hasDataDefinedSize =
false;
231 const double scaledSize =
calculateSize( context, hasDataDefinedSize );
233 bool hasDataDefinedRotation =
false;
239 bool createdNewPath =
false;
257 createdNewPath =
true;
266 QTransform transform;
269 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
272 if ( hasDataDefinedSize || createdNewPath )
281 const double half = s / 2.0;
282 transform.scale( half, half );
287 transform.rotate(
angle );
296 polygon = transform.map(
mPolygon );
300 path = transform.map(
mPath );
302 draw( context, symbol, polygon, path );
307 bool hasDataDefinedSize =
false;
308 double scaledSize =
calculateSize( context, hasDataDefinedSize );
310 bool hasDataDefinedRotation =
false;
317 QTransform transform;
320 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
323 transform.rotate(
angle );
325 return transform.mapRect( QRectF( -scaledSize / 2.0,
335 const QString cleaned = name.toLower().trimmed();
337 if ( cleaned == QLatin1String(
"square" ) || cleaned == QLatin1String(
"rectangle" ) )
339 else if ( cleaned == QLatin1String(
"trapezoid" ) )
341 else if ( cleaned == QLatin1String(
"parallelogram_right" ) )
343 else if ( cleaned == QLatin1String(
"parallelogram_left" ) )
345 else if ( cleaned == QLatin1String(
"square_with_corners" ) )
347 else if ( cleaned == QLatin1String(
"rounded_square" ) )
349 else if ( cleaned == QLatin1String(
"diamond" ) )
351 else if ( cleaned == QLatin1String(
"shield" ) )
353 else if ( cleaned == QLatin1String(
"pentagon" ) )
355 else if ( cleaned == QLatin1String(
"hexagon" ) )
357 else if ( cleaned == QLatin1String(
"octagon" ) )
359 else if ( cleaned == QLatin1String(
"decagon" ) )
361 else if ( cleaned == QLatin1String(
"triangle" ) )
363 else if ( cleaned == QLatin1String(
"equilateral_triangle" ) )
365 else if ( cleaned == QLatin1String(
"star_diamond" ) )
367 else if ( cleaned == QLatin1String(
"star" ) || cleaned == QLatin1String(
"regular_star" ) )
369 else if ( cleaned == QLatin1String(
"heart" ) )
371 else if ( cleaned == QLatin1String(
"arrow" ) )
373 else if ( cleaned == QLatin1String(
"circle" ) )
375 else if ( cleaned == QLatin1String(
"cross" ) )
377 else if ( cleaned == QLatin1String(
"cross_fill" ) )
379 else if ( cleaned == QLatin1String(
"cross2" ) || cleaned == QLatin1String(
"x" ) )
381 else if ( cleaned == QLatin1String(
"line" ) )
383 else if ( cleaned == QLatin1String(
"arrowhead" ) )
385 else if ( cleaned == QLatin1String(
"filled_arrowhead" ) )
387 else if ( cleaned == QLatin1String(
"semi_circle" ) )
389 else if ( cleaned == QLatin1String(
"third_circle" ) )
391 else if ( cleaned == QLatin1String(
"quarter_circle" ) )
393 else if ( cleaned == QLatin1String(
"quarter_square" ) )
395 else if ( cleaned == QLatin1String(
"half_square" ) )
397 else if ( cleaned == QLatin1String(
"diagonal_half_square" ) )
399 else if ( cleaned == QLatin1String(
"right_half_triangle" ) )
401 else if ( cleaned == QLatin1String(
"left_half_triangle" ) )
403 else if ( cleaned == QLatin1String(
"asterisk_fill" ) )
405 else if ( cleaned == QLatin1String(
"half_arc" ) )
407 else if ( cleaned == QLatin1String(
"third_arc" ) )
409 else if ( cleaned == QLatin1String(
"quarter_arc" ) )
422 return QStringLiteral(
"square" );
424 return QStringLiteral(
"quarter_square" );
426 return QStringLiteral(
"half_square" );
428 return QStringLiteral(
"diagonal_half_square" );
430 return QStringLiteral(
"parallelogram_right" );
432 return QStringLiteral(
"parallelogram_left" );
434 return QStringLiteral(
"trapezoid" );
436 return QStringLiteral(
"shield" );
438 return QStringLiteral(
"diamond" );
440 return QStringLiteral(
"pentagon" );
442 return QStringLiteral(
"hexagon" );
444 return QStringLiteral(
"octagon" );
446 return QStringLiteral(
"decagon" );
448 return QStringLiteral(
"square_with_corners" );
450 return QStringLiteral(
"rounded_square" );
452 return QStringLiteral(
"triangle" );
454 return QStringLiteral(
"equilateral_triangle" );
456 return QStringLiteral(
"left_half_triangle" );
458 return QStringLiteral(
"right_half_triangle" );
460 return QStringLiteral(
"star_diamond" );
462 return QStringLiteral(
"star" );
464 return QStringLiteral(
"heart" );
466 return QStringLiteral(
"arrow" );
468 return QStringLiteral(
"filled_arrowhead" );
470 return QStringLiteral(
"cross_fill" );
472 return QStringLiteral(
"circle" );
474 return QStringLiteral(
"cross" );
476 return QStringLiteral(
"cross2" );
478 return QStringLiteral(
"line" );
480 return QStringLiteral(
"arrowhead" );
482 return QStringLiteral(
"semi_circle" );
484 return QStringLiteral(
"third_circle" );
486 return QStringLiteral(
"quarter_circle" );
488 return QStringLiteral(
"asterisk_fill" );
490 return QStringLiteral(
"half_arc" );
492 return QStringLiteral(
"third_arc" );
494 return QStringLiteral(
"quarter_arc" );
511 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 1, 1 ) ) );
516 static constexpr double VERTEX_OFFSET_FROM_ORIGIN = 0.6072;
518 polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
519 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
520 << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
521 << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
522 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
523 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
524 << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
525 << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
526 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
531 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 0 ) ) );
535 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 1 ) ) );
539 polygon << QPointF( -1, -1 ) << QPointF( 1, 1 ) << QPointF( -1, 1 ) << QPointF( -1, -1 );
543 polygon << QPointF( 0.5, -0.5 )
545 << QPointF( -1, 0.5 )
546 << QPointF( -0.5, -0.5 )
547 << QPointF( 0.5, -0.5 );
551 polygon << QPointF( 0.5, 0.5 )
552 << QPointF( 1, -0.5 )
553 << QPointF( -0.5, -0.5 )
554 << QPointF( -1, 0.5 )
555 << QPointF( 0.5, 0.5 );
559 polygon << QPointF( 1, 0.5 )
560 << QPointF( 0.5, -0.5 )
561 << QPointF( -1, -0.5 )
562 << QPointF( -0.5, 0.5 )
563 << QPointF( 1, 0.5 );
567 polygon << QPointF( -1, 0 ) << QPointF( 0, 1 )
568 << QPointF( 1, 0 ) << QPointF( 0, -1 ) << QPointF( -1, 0 );
572 polygon << QPointF( 1, 0.5 )
575 << QPointF( -1, 0.5 )
577 << QPointF( 1, 0.5 );
587 polygon << QPointF( -0.9511, -0.3090 )
588 << QPointF( -0.5878, 0.8090 )
589 << QPointF( 0.5878, 0.8090 )
590 << QPointF( 0.9511, -0.3090 )
592 << QPointF( -0.9511, -0.3090 );
603 polygon << QPointF( -0.8660, -0.5 )
604 << QPointF( -0.8660, 0.5 )
606 << QPointF( 0.8660, 0.5 )
607 << QPointF( 0.8660, -0.5 )
609 << QPointF( -0.8660, -0.5 );
614 static constexpr double VERTEX_OFFSET_FROM_ORIGIN = 1.0 / ( 1 + M_SQRT2 );
616 polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
617 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
618 << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
619 << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
620 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
621 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
622 << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
623 << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
624 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
631 polygon << QPointF( 0.587785252, 0.809016994 )
632 << QPointF( 0.951056516, 0.309016994 )
633 << QPointF( 0.951056516, -0.309016994 )
634 << QPointF( 0.587785252, -0.809016994 )
636 << QPointF( -0.587785252, -0.809016994 )
637 << QPointF( -0.951056516, -0.309016994 )
638 << QPointF( -0.951056516, 0.309016994 )
639 << QPointF( -0.587785252, 0.809016994 )
641 << QPointF( 0.587785252, 0.809016994 );
646 polygon << QPointF( -1, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
654 polygon << QPointF( -0.8660, 0.5 )
655 << QPointF( 0.8660, 0.5 )
657 << QPointF( -0.8660, 0.5 );
661 polygon << QPointF( 0, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( 0, 1 );
665 polygon << QPointF( -1, 1 ) << QPointF( 0, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
670 const double inner_r = std::cos(
DEG2RAD( 72.0 ) ) / std::cos(
DEG2RAD( 36.0 ) );
672 polygon << QPointF( inner_r * std::sin(
DEG2RAD( 315.0 ) ), - inner_r * std::cos(
DEG2RAD( 315.0 ) ) )
673 << QPointF( std::sin(
DEG2RAD( 270 ) ), - std::cos(
DEG2RAD( 270 ) ) )
674 << QPointF( inner_r * std::sin(
DEG2RAD( 225.0 ) ), - inner_r * std::cos(
DEG2RAD( 225.0 ) ) )
675 << QPointF( std::sin(
DEG2RAD( 180 ) ), - std::cos(
DEG2RAD( 180 ) ) )
676 << QPointF( inner_r * std::sin(
DEG2RAD( 135.0 ) ), - inner_r * std::cos(
DEG2RAD( 135.0 ) ) )
677 << QPointF( std::sin(
DEG2RAD( 90 ) ), - std::cos(
DEG2RAD( 90 ) ) )
678 << QPointF( inner_r * std::sin(
DEG2RAD( 45.0 ) ), - inner_r * std::cos(
DEG2RAD( 45.0 ) ) )
679 << QPointF( std::sin(
DEG2RAD( 0 ) ), - std::cos(
DEG2RAD( 0 ) ) );
685 const double inner_r = std::cos(
DEG2RAD( 72.0 ) ) / std::cos(
DEG2RAD( 36.0 ) );
687 polygon << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) )
688 << QPointF( std::sin(
DEG2RAD( 288.0 ) ), - std::cos(
DEG2RAD( 288 ) ) )
689 << QPointF( inner_r * std::sin(
DEG2RAD( 252.0 ) ), - inner_r * std::cos(
DEG2RAD( 252.0 ) ) )
690 << QPointF( std::sin(
DEG2RAD( 216.0 ) ), - std::cos(
DEG2RAD( 216.0 ) ) )
691 << QPointF( 0, inner_r )
692 << QPointF( std::sin(
DEG2RAD( 144.0 ) ), - std::cos(
DEG2RAD( 144.0 ) ) )
693 << QPointF( inner_r * std::sin(
DEG2RAD( 108.0 ) ), - inner_r * std::cos(
DEG2RAD( 108.0 ) ) )
694 << QPointF( std::sin(
DEG2RAD( 72.0 ) ), - std::cos(
DEG2RAD( 72.0 ) ) )
695 << QPointF( inner_r * std::sin(
DEG2RAD( 36.0 ) ), - inner_r * std::cos(
DEG2RAD( 36.0 ) ) )
697 << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) );
702 polygon << QPointF( 0, -1 )
703 << QPointF( 0.5, -0.5 )
704 << QPointF( 0.25, -0.5 )
705 << QPointF( 0.25, 1 )
706 << QPointF( -0.25, 1 )
707 << QPointF( -0.25, -0.5 )
708 << QPointF( -0.5, -0.5 )
713 polygon << QPointF( 0, 0 ) << QPointF( -1, 1 ) << QPointF( -1, -1 ) << QPointF( 0, 0 );
717 polygon << QPointF( -1, -0.2 )
718 << QPointF( -1, -0.2 )
719 << QPointF( -1, 0.2 )
720 << QPointF( -0.2, 0.2 )
721 << QPointF( -0.2, 1 )
723 << QPointF( 0.2, 0.2 )
725 << QPointF( 1, -0.2 )
726 << QPointF( 0.2, -0.2 )
727 << QPointF( 0.2, -1 )
728 << QPointF( -0.2, -1 )
729 << QPointF( -0.2, -0.2 )
730 << QPointF( -1, -0.2 );
735 static constexpr double THICKNESS = 0.3;
736 static constexpr double HALF_THICKNESS = THICKNESS / 2.0;
737 static constexpr double INTERSECTION_POINT = THICKNESS / M_SQRT2;
738 static constexpr double DIAGONAL1 = M_SQRT1_2 - INTERSECTION_POINT * 0.5;
739 static constexpr double DIAGONAL2 = M_SQRT1_2 + INTERSECTION_POINT * 0.5;
741 polygon << 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 )
754 << QPointF( -HALF_THICKNESS, 1 )
755 << QPointF( -HALF_THICKNESS, HALF_THICKNESS + INTERSECTION_POINT )
756 << QPointF( -DIAGONAL1, DIAGONAL2 )
757 << QPointF( -DIAGONAL2, DIAGONAL1 )
758 << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, HALF_THICKNESS )
759 << QPointF( -1, HALF_THICKNESS )
760 << QPointF( -1, -HALF_THICKNESS )
761 << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, -HALF_THICKNESS )
762 << QPointF( -DIAGONAL2, -DIAGONAL1 )
763 << QPointF( -DIAGONAL1, -DIAGONAL2 )
764 << QPointF( -HALF_THICKNESS, -HALF_THICKNESS - INTERSECTION_POINT )
765 << QPointF( -HALF_THICKNESS, -1 );
790 mPath = QPainterPath();
796 mPath.addEllipse( QRectF( -1, -1, 2, 2 ) );
800 mPath.moveTo( -1, -1 );
801 mPath.addRoundedRect( -1, -1, 2, 2, 0.25, 0.25 );
805 mPath.arcTo( -1, -1, 2, 2, 0, 180 );
806 mPath.lineTo( 0, 0 );
810 mPath.arcTo( -1, -1, 2, 2, 90, 120 );
811 mPath.lineTo( 0, 0 );
815 mPath.arcTo( -1, -1, 2, 2, 90, 90 );
816 mPath.lineTo( 0, 0 );
820 mPath.moveTo( 1, 0 );
821 mPath.arcTo( -1, -1, 2, 2, 0, 180 );
825 mPath.moveTo( 0, -1 );
826 mPath.arcTo( -1, -1, 2, 2, 90, 120 );
830 mPath.moveTo( 0, -1 );
831 mPath.arcTo( -1, -1, 2, 2, 90, 90 );
835 mPath.moveTo( -1, 0 );
836 mPath.lineTo( 1, 0 );
837 mPath.moveTo( 0, -1 );
838 mPath.lineTo( 0, 1 );
842 mPath.moveTo( -1, -1 );
843 mPath.lineTo( 1, 1 );
844 mPath.moveTo( 1, -1 );
845 mPath.lineTo( -1, 1 );
849 mPath.moveTo( 0, -1 );
850 mPath.lineTo( 0, 1 );
854 mPath.moveTo( -1, -1 );
855 mPath.lineTo( 0, 0 );
856 mPath.lineTo( -1, 1 );
860 mPath.moveTo( 0, 0.75 );
861 mPath.arcTo( 0, -1, 1, 1, -45, 210 );
862 mPath.arcTo( -1, -1, 1, 1, 15, 210 );
863 mPath.lineTo( 0, 0.75 );
897 double scaledSize =
mSize;
901 if ( hasDataDefinedSize )
908 if ( hasDataDefinedSize && ok )
913 scaledSize = std::sqrt( scaledSize );
928 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
929 offset = QPointF( offsetX, offsetY );
931 hasDataDefinedRotation =
false;
944 hasDataDefinedRotation =
true;
949 if ( hasDataDefinedRotation )
978 , mStrokeColor( strokeColor )
979 , mPenJoinStyle( penJoinStyle )
996 if ( props.contains( QStringLiteral(
"name" ) ) )
1000 if ( props.contains( QStringLiteral(
"color" ) ) )
1002 if ( props.contains( QStringLiteral(
"color_border" ) ) )
1007 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
1011 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
1015 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
1019 if ( props.contains( QStringLiteral(
"size" ) ) )
1020 size = props[QStringLiteral(
"size" )].toDouble();
1021 if ( props.contains( QStringLiteral(
"angle" ) ) )
1022 angle = props[QStringLiteral(
"angle" )].toDouble();
1023 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1027 if ( props.contains( QStringLiteral(
"offset" ) ) )
1029 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1031 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1033 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1035 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1038 if ( props.contains( QStringLiteral(
"outline_style" ) ) )
1042 else if ( props.contains( QStringLiteral(
"line_style" ) ) )
1046 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
1048 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
1050 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
1052 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
1054 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
1058 if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
1062 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
1067 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1071 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1076 if ( props.contains( QStringLiteral(
"cap_style" ) ) )
1089 return QStringLiteral(
"SimpleMarker" );
1101 QColor brushColor =
mColor;
1104 brushColor.setAlphaF(
mColor.alphaF() * context.
opacity() );
1107 mBrush = QBrush( brushColor );
1108 mPen = QPen( penColor );
1118 selBrushColor.setAlphaF( context.
opacity() );
1119 selPenColor.setAlphaF( context.
opacity() );
1122 mSelPen = QPen( selPenColor );
1138 mCachedOpacity = context.
opacity();
1144 mSelPen.setColor( selBrushColor );
1177 scaledSize = ( std::abs( std::sin(
mAngle * M_PI / 180 ) ) + std::abs( std::cos(
mAngle * M_PI / 180 ) ) ) * scaledSize;
1180 const double pw =
static_cast< int >( std::round( ( (
qgsDoubleNear(
mPen.widthF(), 0.0 ) ? 1 :
mPen.widthF() * 4 ) + 1 ) ) ) / 2 * 2;
1181 const int imageSize = (
static_cast< int >( scaledSize ) + pw ) / 2 * 2 + 1;
1182 const double center = imageSize / 2.0;
1188 mCache = QImage( QSize( imageSize * deviceRatio,
1189 imageSize * deviceRatio ), QImage::Format_ARGB32_Premultiplied );
1199 p.setRenderHint( QPainter::Antialiasing );
1200 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
1202 p.translate( QPointF( center, center ) );
1210 mSelCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
1214 p.setRenderHint( QPainter::Antialiasing );
1215 p.setBrush( needsBrush ?
mSelBrush : Qt::NoBrush );
1217 p.translate( QPointF( center, center ) );
1228 p.setRenderHint( QPainter::Antialiasing );
1229 p.fillRect( 0, 0, imageSize, imageSize, selColor );
1230 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
1232 p.translate( QPointF( center, center ) );
1251 QColor brushColor =
mColor;
1252 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
1253 mBrush.setColor( brushColor );
1256 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
1257 mPen.setColor( penColor );
1266 c.setAlphaF(
c.alphaF() * context.
opacity() );
1276 c.setAlphaF(
c.alphaF() * context.
opacity() );
1329 p->setBrush( Qt::NoBrush );
1333 if ( !polygon.isEmpty() )
1334 p->drawPolygon( polygon );
1336 p->drawPath( path );
1354 const double s = img.width() / img.devicePixelRatioF();
1356 bool hasDataDefinedSize =
false;
1357 const double scaledSize =
calculateSize( context, hasDataDefinedSize );
1359 bool hasDataDefinedRotation =
false;
1364 p->drawImage( QRectF( point.x() - s / 2.0 +
offset.x(),
1365 point.y() - s / 2.0 +
offset.y(),
1380 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1383 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1389 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
1422 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
1423 element.appendChild( graphicElem );
1439 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
1442 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
1459 Q_UNUSED( mmScaleFactor )
1460 Q_UNUSED( mapUnitScaleFactor )
1462 QString ogrType =
"3";
1463 if ( mName ==
"square" )
1467 else if ( mName ==
"triangle" )
1471 else if ( mName ==
"star" )
1475 else if ( mName ==
"circle" )
1479 else if ( mName ==
"cross" )
1483 else if ( mName ==
"x" || mName ==
"cross2" )
1487 else if ( mName ==
"line" )
1493 ogrString.append(
"SYMBOL(" );
1494 ogrString.append(
"id:" );
1495 ogrString.append(
'\"' );
1496 ogrString.append(
"ogr-sym-" );
1497 ogrString.append( ogrType );
1498 ogrString.append(
'\"' );
1499 ogrString.append(
",c:" );
1500 ogrString.append(
mColor.name() );
1501 ogrString.append(
",o:" );
1503 ogrString.append( QString(
",s:%1mm" ).arg(
mSize ) );
1504 ogrString.append(
')' );
1509 ogrString.append(
"PEN(" );
1510 ogrString.append(
"c:" );
1511 ogrString.append(
mColor.name() );
1512 ogrString.append(
",w:" );
1513 ogrString.append( QString::number(
mSize ) );
1514 ogrString.append(
"mm" );
1515 ogrString.append(
")" );
1523 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1524 if ( graphicElem.isNull() )
1527 QString name = QStringLiteral(
"square" );
1540 const double d = angleFunc.toDouble( &ok );
1550 double scaleFactor = 1.0;
1551 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
1578 p->drawPath(
mPath );
1591 if ( hasDataDefinedSize )
1610 size *= mmMapUnitScaleFactor;
1617 const double halfSize =
size / 2.0;
1634 QColor pc =
mPen.color();
1635 QColor bc =
mBrush.color();
1655 QPointF off( offsetX, offsetY );
1684 t.translate( shift.x() + off.x(), shift.y() - off.y() );
1692 t.scale( halfSize, -halfSize );
1694 polygon = t.map( polygon );
1697 p.reserve( polygon.size() );
1698 for (
int i = 0; i < polygon.size(); i++ )
1703 if (
mBrush.style() != Qt::NoBrush )
1705 if (
mPen.style() != Qt::NoPen )
1710 shift += QPointF( off.x(), -off.y() );
1711 if (
mBrush.style() != Qt::NoBrush )
1713 if (
mPen.style() != Qt::NoPen )
1718 const QPointF pt1 = t.map( QPointF( 0, -halfSize ) );
1719 const QPointF pt2 = t.map( QPointF( 0, halfSize ) );
1721 if (
mPen.style() != Qt::NoPen )
1726 if (
mPen.style() != Qt::NoPen )
1728 const QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
1729 const QPointF pt2 = t.map( QPointF( halfSize, 0 ) );
1730 const QPointF pt3 = t.map( QPointF( 0, -halfSize ) );
1731 const QPointF pt4 = t.map( QPointF( 0, halfSize ) );
1739 if (
mPen.style() != Qt::NoPen )
1741 const QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
1742 const QPointF pt2 = t.map( QPointF( halfSize, halfSize ) );
1743 const QPointF pt3 = t.map( QPointF( halfSize, -halfSize ) );
1744 const QPointF pt4 = t.map( QPointF( -halfSize, halfSize ) );
1752 if (
mPen.style() != Qt::NoPen )
1754 const QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
1755 const QPointF pt2 = t.map( QPointF( 0, 0 ) );
1756 const QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
1842 symbolBounds.adjust( -penWidth / 2.0, -penWidth / 2.0,
1843 penWidth / 2.0, penWidth / 2.0 );
1845 return symbolBounds;
1894 if ( props.contains( QStringLiteral(
"name" ) ) )
1895 name = props[QStringLiteral(
"name" )].toString();
1896 if ( props.contains( QStringLiteral(
"size" ) ) )
1897 size = props[QStringLiteral(
"size" )].toDouble();
1898 if ( props.contains( QStringLiteral(
"angle" ) ) )
1899 angle = props[QStringLiteral(
"angle" )].toDouble();
1900 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1904 if ( props.contains( QStringLiteral(
"offset" ) ) )
1906 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1908 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1910 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1912 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1914 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1918 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1932 return QStringLiteral(
"FilledMarker" );
1958 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1961 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2017 attr.unite( mFill->usedAttributes( context ) );
2025 if ( mFill && mFill->hasDataDefinedProperties() )
2034 mFill->setColor(
c );
2039 return mFill ? mFill->color() :
mColor;
2046 || ( mFill && mFill->usesMapUnits() );
2053 mFill->setOutputUnit( unit );
2067 const double prevOpacity = mFill->opacity();
2068 mFill->setOpacity( mFill->opacity() * context.
opacity() );
2072 p->setBrush( Qt::red );
2076 p->setBrush( Qt::NoBrush );
2078 p->setPen( Qt::black );
2084 if ( !polygon.isEmpty() )
2086 mFill->renderPolygon( polygon,
nullptr, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2090 const QPolygonF poly = path.toFillPolygon();
2091 mFill->renderPolygon( poly,
nullptr, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2096 mFill->setOpacity( prevOpacity );
2111 mColor = QColor( 35, 35, 35 );
2125 if ( props.contains( QStringLiteral(
"name" ) ) )
2126 name = props[QStringLiteral(
"name" )].toString();
2127 if ( props.contains( QStringLiteral(
"size" ) ) )
2128 size = props[QStringLiteral(
"size" )].toDouble();
2129 if ( props.contains( QStringLiteral(
"angle" ) ) )
2130 angle = props[QStringLiteral(
"angle" )].toDouble();
2131 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
2136 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
2138 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
2140 if ( props.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
2142 if ( props.contains( QStringLiteral(
"offset" ) ) )
2144 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
2146 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2148 if ( props.contains( QStringLiteral(
"fill" ) ) )
2153 else if ( props.contains( QStringLiteral(
"color" ) ) )
2157 if ( props.contains( QStringLiteral(
"outline" ) ) )
2162 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
2166 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
2171 if ( props.contains( QStringLiteral(
"outline-width" ) ) )
2174 m->
setStrokeWidth( props[QStringLiteral(
"outline-width" )].toDouble() );
2176 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
2178 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
2180 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
2182 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
2185 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
2189 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
2193 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2196 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
2200 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
2209 if ( props.contains( QStringLiteral(
"parameters" ) ) )
2211 const QVariantMap
parameters = props[QStringLiteral(
"parameters" )].toMap();
2220 const QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
2239 QColor defaultFillColor, defaultStrokeColor;
2241 bool hasFillOpacityParam =
false, hasStrokeParam =
false, hasStrokeWidthParam =
false, hasStrokeOpacityParam =
false;
2242 bool hasDefaultFillColor =
false, hasDefaultFillOpacity =
false, hasDefaultStrokeColor =
false, hasDefaultStrokeWidth =
false, hasDefaultStrokeOpacity =
false;
2244 hasFillOpacityParam, hasDefaultFillOpacity, fillOpacity,
2245 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2246 hasStrokeWidthParam, hasDefaultStrokeWidth,
strokeWidth,
2247 hasStrokeOpacityParam, hasDefaultStrokeOpacity, strokeOpacity );
2249 const double newFillOpacity = hasFillOpacityParam ?
fillColor().alphaF() : 1.0;
2250 const double newStrokeOpacity = hasStrokeOpacityParam ?
strokeColor().alphaF() : 1.0;
2252 if ( hasDefaultFillColor )
2254 defaultFillColor.setAlphaF( newFillOpacity );
2257 if ( hasDefaultFillOpacity )
2260 c.setAlphaF( fillOpacity );
2263 if ( hasDefaultStrokeColor )
2265 defaultStrokeColor.setAlphaF( newStrokeOpacity );
2268 if ( hasDefaultStrokeWidth )
2272 if ( hasDefaultStrokeOpacity )
2275 c.setAlphaF( strokeOpacity );
2289 const double widthScaleFactor = 3.465;
2292 mDefaultAspectRatio = svgViewbox.isValid() ? svgViewbox.height() / svgViewbox.width() : 0.0;
2300 if ( aPreservedAspectRatio && !par )
2304 else if ( !aPreservedAspectRatio && par )
2319 return QStringLiteral(
"SvgMarker" );
2344 bool hasDataDefinedSize =
false;
2345 const double scaledWidth = calculateSize( context, hasDataDefinedSize );
2350 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
2357 bool hasDataDefinedAspectRatio =
false;
2358 const double aspectRatio =
calculateAspectRatio( context, scaledWidth, hasDataDefinedAspectRatio );
2402 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
2406 QPointF outputOffset;
2408 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
2410 p->translate( point + outputOffset );
2416 bool fitsInCache =
true;
2417 bool usePict =
true;
2424 if ( fitsInCache && img.width() > 1 )
2428 if ( useSelectedColor )
2436 QImage transparentImage = img.copy();
2438 if ( devicePixelRatio == 1 )
2440 p->drawImage( -transparentImage.width() / 2.0, -transparentImage.height() / 2.0, transparentImage );
2444 p->drawImage( QRectF( -transparentImage.width() / 2.0 / devicePixelRatio, -transparentImage.height() / 2.0 / devicePixelRatio,
2445 transparentImage.width() / devicePixelRatio, transparentImage.height() / devicePixelRatio
2446 ), transparentImage );
2451 if ( devicePixelRatio == 1 )
2453 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
2457 p->drawImage( QRectF( -img.width() / 2.0 / devicePixelRatio, -img.height() / 2.0 / devicePixelRatio,
2458 img.width() / devicePixelRatio, img.height() / devicePixelRatio ), img );
2464 if ( usePict || !fitsInCache )
2466 p->setOpacity( context.
opacity() );
2470 if ( pct.width() > 1 )
2473 _fixQPictureDPI( p );
2474 p->drawPicture( 0, 0, pct );
2482double QgsSvgMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
2484 double scaledSize =
mSize;
2488 if ( hasDataDefinedSize )
2496 if ( hasDataDefinedSize )
2503 if ( hasDataDefinedSize && ok )
2508 scaledSize = std::sqrt( scaledSize );
2521 if ( !hasDataDefinedAspectRatio )
2531 const double defaultHeight =
mSize * scaledAspectRatio;
2532 scaledAspectRatio = defaultHeight / scaledSize;
2535 double scaledHeight = scaledSize * scaledAspectRatio;
2542 if ( hasDataDefinedAspectRatio && ok )
2547 scaledHeight = sqrt( scaledHeight );
2554 scaledAspectRatio = scaledHeight / scaledSize;
2556 return scaledAspectRatio;
2559void QgsSvgMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &angle )
const
2564 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
2565 offset = QPointF( offsetX, offsetY );
2575 if ( hasDataDefinedRotation )
2601 map[QStringLiteral(
"name" )] =
mPath;
2602 map[QStringLiteral(
"size" )] = QString::number(
mSize );
2605 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
2606 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2613 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
2688 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2689 element.appendChild( graphicElem );
2699 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2702 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
2720 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
2721 if ( graphicElem.isNull() )
2724 QString
path, mimeType;
2732 double scaleFactor = 1.0;
2733 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
2737 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2745 const double d = angleFunc.toDouble( &ok );
2754 QString realPath {
path };
2755 QUrl svgUrl {
path };
2758 QUrlQuery queryString;
2760 if ( svgUrl.hasQuery() && svgUrl.hasFragment() )
2762 const QString queryPart {
path.mid(
path.indexOf(
'?' ) + 1 ) };
2763 queryString.setQuery( queryPart );
2767 if ( svgUrl.scheme().isEmpty() || svgUrl.isLocalFile() )
2769 svgUrl.setQuery( QString() );
2770 realPath = svgUrl.path();
2775 QMap<QString, QgsProperty> params;
2779 if ( queryString.hasQueryItem( QStringLiteral(
"fill" ) ) )
2781 const QColor
fillColor { queryString.queryItemValue( QStringLiteral(
"fill" ) ) };
2785 if ( queryString.hasQueryItem( QStringLiteral(
"fill-opacity" ) ) )
2787 const double alpha { queryString.queryItemValue( QStringLiteral(
"fill-opacity" ) ).toDouble( &ok ) };
2794 if ( queryString.hasQueryItem( QStringLiteral(
"outline" ) ) )
2796 const QColor
strokeColor { queryString.queryItemValue( QStringLiteral(
"outline" ) ) };
2800 if ( queryString.hasQueryItem( QStringLiteral(
"outline-opacity" ) ) )
2802 const double alpha { queryString.queryItemValue( QStringLiteral(
"outline-opacity" ) ).toDouble( &ok ) };
2809 if ( queryString.hasQueryItem( QStringLiteral(
"outline-width" ) ) )
2811 const int width { queryString.queryItemValue( QStringLiteral(
"outline-width" ) ).toInt( &ok )};
2818 if ( ! params.isEmpty() )
2837 if ( hasDataDefinedSize )
2843 if ( hasDataDefinedSize && ok )
2857 size *= mmMapUnitScaleFactor;
2871 const double offsetX =
offset.x();
2872 const double offsetY =
offset.y();
2874 QPointF outputOffset( offsetX, offsetY );
2924 QSvgRenderer r( svgContent );
2931 QSizeF outSize( r.defaultSize() );
2932 outSize.scale(
size,
size, Qt::KeepAspectRatio );
2938 p.translate( r.defaultSize().width() / 2.0, r.defaultSize().height() / 2.0 );
2940 p.translate( -r.defaultSize().width() / 2.0, -r.defaultSize().height() / 2.0 );
2942 pd.
setShift( shift + QPointF( outputOffset.x(), -outputOffset.y() ) );
2943 pd.
setOutputSize( QRectF( -outSize.width() / 2.0, -outSize.height() / 2.0, outSize.width(), outSize.height() ) );
2952 bool hasDataDefinedSize =
false;
2953 double scaledWidth = calculateSize( context, hasDataDefinedSize );
2955 bool hasDataDefinedAspectRatio =
false;
2956 const double aspectRatio =
calculateAspectRatio( context, scaledWidth, hasDataDefinedAspectRatio );
2963 if (
static_cast< int >( scaledWidth ) < 1 || 10000.0 < scaledWidth )
2968 QPointF outputOffset;
2970 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
3009 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
3013 QTransform transform;
3015 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
3018 transform.rotate(
angle );
3023 QRectF symbolBounds = transform.mapRect( QRectF( -scaledWidth / 2.0,
3024 -scaledHeight / 2.0,
3032 return symbolBounds;
3056 if ( props.contains( QStringLiteral(
"imageFile" ) ) )
3057 path = props[QStringLiteral(
"imageFile" )].toString();
3058 if ( props.contains( QStringLiteral(
"size" ) ) )
3059 size = props[QStringLiteral(
"size" )].toDouble();
3060 if ( props.contains( QStringLiteral(
"angle" ) ) )
3061 angle = props[QStringLiteral(
"angle" )].toDouble();
3062 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
3065 std::unique_ptr< QgsRasterMarkerSymbolLayer > m = std::make_unique< QgsRasterMarkerSymbolLayer >(
path,
size,
angle,
scaleMethod );
3066 m->setCommonProperties( props );
3072 if (
properties.contains( QStringLiteral(
"alpha" ) ) )
3077 if (
properties.contains( QStringLiteral(
"size_unit" ) ) )
3079 if (
properties.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
3081 if (
properties.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
3084 if (
properties.contains( QStringLiteral(
"offset" ) ) )
3086 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
3088 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
3091 if (
properties.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
3095 if (
properties.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
3106 const QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
3107 if ( it !=
properties.end() && it.value().userType() == QMetaType::Type::QString )
3125 if ( aPreservedAspectRatio && !par )
3129 else if ( !aPreservedAspectRatio && par )
3148 return QStringLiteral(
"RasterMarker" );
3169 if (
path.isEmpty() )
3173 double height = 0.0;
3175 bool hasDataDefinedSize =
false;
3176 const double scaledSize = calculateSize( context, hasDataDefinedSize );
3178 bool hasDataDefinedAspectRatio =
false;
3179 const double aspectRatio =
calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
3181 QPointF outputOffset;
3188 if (
size.isEmpty() )
3191 width = ( scaledSize *
static_cast< double >(
size.width() ) ) / 100.0;
3192 height = ( scaledSize *
static_cast< double >(
size.height() ) ) / 100.0;
3195 if (
static_cast< int >( width ) < 1 || 10000.0 < width ||
static_cast< int >( height ) < 1 || 10000.0 < height )
3198 calculateOffsetAndRotation( context, width, height, outputOffset,
angle );
3208 if ( !
size.isNull() &&
size.isValid() &&
size.width() > 0 )
3210 height = width * (
static_cast< double >(
size.height() ) /
static_cast< double >(
size.width() ) );
3215 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
3218 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
3222 p->translate( point + outputOffset );
3237 if ( !img.isNull() )
3240 if ( useSelectedColor )
3245 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
3251 bool cached =
false;
3255double QgsRasterMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
3257 double scaledSize =
mSize;
3261 if ( hasDataDefinedSize )
3269 if ( hasDataDefinedSize )
3276 if ( hasDataDefinedSize && ok )
3281 scaledSize = std::sqrt( scaledSize );
3294 if ( !hasDataDefinedAspectRatio )
3304 const double defaultHeight =
mSize * scaledAspectRatio;
3305 scaledAspectRatio = defaultHeight / scaledSize;
3308 double scaledHeight = scaledSize * scaledAspectRatio;
3315 if ( hasDataDefinedAspectRatio && ok )
3320 scaledHeight = sqrt( scaledHeight );
3327 scaledAspectRatio = scaledHeight / scaledSize;
3329 return scaledAspectRatio;
3332void QgsRasterMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &angle )
const
3337 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
3338 offset = QPointF( offsetX, offsetY );
3348 if ( hasDataDefinedRotation )
3369 map[QStringLiteral(
"imageFile" )] =
mPath;
3370 map[QStringLiteral(
"size" )] = QString::number(
mSize );
3373 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
3374 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
3375 map[QStringLiteral(
"alpha" )] = QString::number(
mOpacity );
3387 std::unique_ptr< QgsRasterMarkerSymbolLayer > m = std::make_unique< QgsRasterMarkerSymbolLayer >(
mPath,
mSize,
mAngle );
3431 bool hasDataDefinedSize =
false;
3432 const double scaledSize = calculateSize( context, hasDataDefinedSize );
3434 bool hasDataDefinedAspectRatio =
false;
3435 const double aspectRatio =
calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
3439 if (
static_cast< int >( scaledSize ) < 1 || 10000.0 < scaledSize )
3444 QPointF outputOffset;
3446 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
3448 QTransform transform;
3451 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
3454 transform.rotate(
angle );
3456 QRectF symbolBounds = transform.mapRect( QRectF( -width / 2.0,
3461 return symbolBounds;
3473 mOrigSize = pointSize;
3493 if ( props.contains( QStringLiteral(
"font" ) ) )
3494 fontFamily = props[QStringLiteral(
"font" )].toString();
3495 if ( props.contains( QStringLiteral(
"chr" ) ) && props[QStringLiteral(
"chr" )].toString().length() > 0 )
3497 string = props[
"chr"].toString();
3498 const thread_local QRegularExpression charRegExp( QStringLiteral(
"%1([0-9]+)%1" ).arg(
FONTMARKER_CHR_FIX ) );
3499 QRegularExpressionMatch match = charRegExp.match(
string );
3500 while ( match.hasMatch() )
3502 QChar replacement = QChar( match.captured( 1 ).toUShort() );
3503 string =
string.mid( 0, match.capturedStart( 0 ) ) + replacement +
string.mid( match.capturedEnd( 0 ) );
3504 match = charRegExp.match(
string );
3508 if ( props.contains( QStringLiteral(
"size" ) ) )
3509 pointSize = props[QStringLiteral(
"size" )].toDouble();
3510 if ( props.contains( QStringLiteral(
"color" ) ) )
3512 if ( props.contains( QStringLiteral(
"angle" ) ) )
3513 angle = props[QStringLiteral(
"angle" )].toDouble();
3517 if ( props.contains( QStringLiteral(
"font_style" ) ) )
3518 m->
setFontStyle( props[QStringLiteral(
"font_style" )].toString() );
3519 if ( props.contains( QStringLiteral(
"outline_color" ) ) )
3521 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
3522 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
3523 if ( props.contains( QStringLiteral(
"offset" ) ) )
3525 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
3527 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
3529 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
3531 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
3533 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
3535 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
3537 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
3539 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
3541 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
3551 return QStringLiteral(
"FontMarker" );
3561 QColor brushColor =
mColor;
3562 QColor penColor = mStrokeColor;
3564 brushColor.setAlphaF(
mColor.alphaF() * context.
opacity() );
3565 penColor.setAlphaF( mStrokeColor.alphaF() * context.
opacity() );
3567 mBrush = QBrush( brushColor );
3568 mPen = QPen( penColor );
3569 mPen.setJoinStyle( mPenJoinStyle );
3573 if ( !mFontStyle.isEmpty() )
3581 if ( mNonZeroFontSize && sizePixels > MAX_FONT_CHARACTER_SIZE_IN_PIXELS )
3586 mFontSizeScale = sizePixels / MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
3587 sizePixels = MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
3590 mFontSizeScale = 1.0;
3594 mFont.setPixelSize( std::max( 2,
static_cast< int >( std::round( sizePixels ) ) ) );
3595 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3596 mChrWidth = mFontMetrics->horizontalAdvance( mString );
3597 mChrOffset = QPointF( mChrWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3604 if ( mUseCachedPath )
3606 QPointF chrOffset = mChrOffset;
3608 const QString charToRender = characterToRender( context, chrOffset, chrWidth );
3609 mCachedPath = QPainterPath();
3610 mCachedPath.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
3619QString QgsFontMarkerSymbolLayer::characterToRender(
QgsSymbolRenderContext &context, QPointF &charOffset,
double &charWidth )
3621 charOffset = mChrOffset;
3622 QString stringToRender = mString;
3627 if ( stringToRender != mString )
3629 charWidth = mFontMetrics->horizontalAdvance( stringToRender );
3630 charOffset = QPointF( charWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3633 return stringToRender;
3638 bool &hasDataDefinedRotation,
3640 double &angle )
const
3645 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
3646 offset = QPointF( offsetX, offsetY );
3662 if ( hasDataDefinedRotation )
3686 double scaledSize =
mSize;
3690 if ( hasDataDefinedSize )
3696 if ( hasDataDefinedSize && ok )
3701 scaledSize = std::sqrt( scaledSize );
3713 if ( !p || !mNonZeroFontSize )
3716 QTransform transform;
3719 QColor brushColor =
mColor;
3729 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
3731 mBrush.setColor( brushColor );
3733 QColor penColor = mStrokeColor;
3739 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
3763 p->setBrush( mBrush );
3766 mPen.setColor( penColor );
3767 mPen.setWidthF( penWidth );
3772 p->setPen( Qt::NoPen );
3790 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3793 QPointF chrOffset = mChrOffset;
3795 const QString charToRender = characterToRender( context, chrOffset, chrWidth );
3797 const double sizeToRender = calculateSize( context );
3799 bool hasDataDefinedRotation =
false;
3802 calculateOffsetAndRotation( context, sizeToRender, hasDataDefinedRotation,
offset,
angle );
3804 p->translate( point.x() +
offset.x(), point.y() +
offset.y() );
3807 transform.rotate(
angle );
3811 const double s = sizeToRender / mOrigSize;
3812 transform.scale( s, s );
3816 transform.scale( mFontSizeScale, mFontSizeScale );
3818 if ( mUseCachedPath )
3820 p->drawPath( transform.map( mCachedPath ) );
3825 path.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
3826 p->drawPath( transform.map( path ) );
3833 props[QStringLiteral(
"font" )] = mFontFamily;
3834 props[QStringLiteral(
"font_style" )] = mFontStyle;
3835 QString chr = mString;
3836 for (
int i = 0; i < 32; i++ )
3838 if ( i == 9 || i == 10 || i == 13 )
3842 chr.replace( QChar( i ), QStringLiteral(
"%1%2%1" ).arg(
FONTMARKER_CHR_FIX, QString::number( i ) ) );
3844 props[QStringLiteral(
"chr" )] = chr;
3845 props[QStringLiteral(
"size" )] = QString::number(
mSize );
3850 props[QStringLiteral(
"outline_width" )] = QString::number( mStrokeWidth );
3854 props[QStringLiteral(
"angle" )] = QString::number(
mAngle );
3887 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
3888 element.appendChild( graphicElem );
3890 const QString fontPath = QStringLiteral(
"ttf://%1" ).arg( mFontFamily );
3891 int markIndex = !mString.isEmpty() ? mString.at( 0 ).unicode() : 0;
3898 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
3901 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
3924 mStrokeWidthUnit = unit;
3929 QPointF chrOffset = mChrOffset;
3930 double chrWidth = mChrWidth;
3932 ( void )characterToRender( context, chrOffset, chrWidth );
3934 if ( !mFontMetrics )
3935 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3937 double scaledSize = calculateSize( context );
3940 chrWidth *= scaledSize / mOrigSize;
3942 chrWidth *= mFontSizeScale;
3944 bool hasDataDefinedRotation =
false;
3947 calculateOffsetAndRotation( context, scaledSize, hasDataDefinedRotation,
offset,
angle );
3950 QTransform transform;
3953 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
3956 transform.rotate(
angle );
3958 QRectF symbolBounds = transform.mapRect( QRectF( -chrWidth / 2.0,
3962 return symbolBounds;
3969 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
3970 if ( graphicElem.isNull() )
3973 QString name, format;
3981 if ( !name.startsWith( QLatin1String(
"ttf://" ) ) || format != QLatin1String(
"ttf" ) )
3991 const double d = angleFunc.toDouble( &ok );
3999 double scaleFactor = 1.0;
4000 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
4021 context.
pushMessage( QObject::tr(
"Font “%1” not available on system" ).arg( processedFamily ) );
4027 QMap<QString, QgsProperty>::iterator it =
mParameters.begin();
4039 QMap<QString, QgsProperty>::const_iterator it =
mParameters.constBegin();
4042 attrs.unite( it.value().referencedFields( context.
expressionContext(),
true ) );
4066 if (
properties.contains( QStringLiteral(
"imageFile" ) ) )
4068 if (
properties.contains( QStringLiteral(
"size" ) ) )
4070 if (
properties.contains( QStringLiteral(
"angle" ) ) )
4073 std::unique_ptr< QgsAnimatedMarkerSymbolLayer > m = std::make_unique< QgsAnimatedMarkerSymbolLayer >(
path,
size,
angle );
4074 m->setFrameRate(
properties.value( QStringLiteral(
"frameRate" ), QStringLiteral(
"10" ) ).toDouble() );
4082 return QStringLiteral(
"AnimatedMarker" );
4088 res.insert( QStringLiteral(
"frameRate" ), mFrameRateFps );
4094 std::unique_ptr< QgsAnimatedMarkerSymbolLayer > m = std::make_unique< QgsAnimatedMarkerSymbolLayer >(
mPath,
mSize,
mAngle );
4095 m->setFrameRate( mFrameRateFps );
4104 mPreparedPaths.clear();
4112 mStaticPath =
false;
4118 if ( !mStaticPath && !mPreparedPaths.contains(
path ) )
4121 mPreparedPaths.insert(
path );
4124 const long long mapFrameNumber = context.
currentFrame();
4126 const double markerAnimationDuration = totalFrameCount / mFrameRateFps;
4128 double animationTimeSeconds = 0;
4129 if ( mapFrameNumber >= 0 && context.
frameRate() > 0 )
4132 animationTimeSeconds = mapFrameNumber / context.
frameRate();
4137 animationTimeSeconds = QDateTime::currentMSecsSinceEpoch() / 1000.0;
4140 const double markerAnimationProgressSeconds = std::fmod( animationTimeSeconds, markerAnimationDuration );
4141 const int movieFrame =
static_cast< int >( std::floor( markerAnimationProgressSeconds * mFrameRateFps ) );
4143 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 (since QGIS 3.38)
@ 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 (since QGIS 3.28)
@ AsteriskFill
A filled asterisk shape (since QGIS 3.18)
@ Octagon
Octagon (since QGIS 3.18)
@ HalfArc
A line-only half arc (since QGIS 3.20)
@ QuarterSquare
Quarter square (top left quarter)
@ Cross2
Rotated cross (lines only), 'x' shape.
@ Trapezoid
Trapezoid (since QGIS 3.28)
@ ArrowHeadFilled
Right facing filled arrow head.
@ Shield
A shape consisting of a triangle attached to a rectangle (since QGIS 3.28)
@ HalfSquare
Half square (left half)
@ CrossFill
Solid filled cross.
@ Decagon
Decagon (since QGIS 3.28)
@ RoundedSquare
A square with rounded corners (since QGIS 3.28)
@ RightHalfTriangle
Right half of triangle.
@ ThirdCircle
One third circle (top left third)
@ ThirdArc
A line-only one third arc (since QGIS 3.20)
@ SquareWithCorners
A square with diagonal corners (since QGIS 3.18)
@ QuarterArc
A line-only one quarter arc (since QGIS 3.20)
@ DiamondStar
A 4-sided star (since QGIS 3.28)
@ Cross
Cross (lines only)
@ ParallelogramLeft
Parallelogram that slants left (since QGIS 3.28)
@ Heart
Heart (since QGIS 3.28)
@ 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.
~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
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.
bool forceVectorOutput() const
Returns true if rendering operations should use vector operations instead of any faster raster shortc...
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.
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 void setColor(const QColor &color)
Sets the "representative" color for the symbol layer.
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.
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)
Q_GUI_EXPORT int qt_defaultDpiX()
Q_GUI_EXPORT int qt_defaultDpiY()
#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