33#include <QSvgRenderer>
36#include <QDomDocument>
45static constexpr int MAX_FONT_CHARACTER_SIZE_IN_PIXELS = 500;
47static void _fixQPictureDPI( QPainter *p )
53 p->scale(
static_cast< double >(
qt_defaultDpiX() ) / p->device()->logicalDpiX(),
54 static_cast< double >(
qt_defaultDpiY() ) / p->device()->logicalDpiY() );
67 QList< Qgis::MarkerShape > shapes;
116 mSizeUnit = Qgis::RenderUnit::Millimeters;
182 QTransform transform;
185 if ( !hasDataDefinedSize )
195 const double half = scaledSize / 2.0;
196 transform.scale( half, half );
202 transform.rotate(
mAngle );
229 bool hasDataDefinedSize =
false;
230 const double scaledSize =
calculateSize( context, hasDataDefinedSize );
232 bool hasDataDefinedRotation =
false;
238 bool createdNewPath =
false;
256 createdNewPath =
true;
265 QTransform transform;
268 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
271 if ( hasDataDefinedSize || createdNewPath )
280 const double half = s / 2.0;
281 transform.scale( half, half );
286 transform.rotate(
angle );
295 polygon = transform.map(
mPolygon );
299 path = transform.map(
mPath );
301 draw( context, symbol, polygon, path );
306 bool hasDataDefinedSize =
false;
307 double scaledSize =
calculateSize( context, hasDataDefinedSize );
309 bool hasDataDefinedRotation =
false;
316 QTransform transform;
319 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
322 transform.rotate(
angle );
324 return transform.mapRect( QRectF( -scaledSize / 2.0,
334 const QString cleaned = name.toLower().trimmed();
336 if ( cleaned == QLatin1String(
"square" ) || cleaned == QLatin1String(
"rectangle" ) )
338 else if ( cleaned == QLatin1String(
"trapezoid" ) )
340 else if ( cleaned == QLatin1String(
"parallelogram_right" ) )
342 else if ( cleaned == QLatin1String(
"parallelogram_left" ) )
344 else if ( cleaned == QLatin1String(
"square_with_corners" ) )
346 else if ( cleaned == QLatin1String(
"rounded_square" ) )
348 else if ( cleaned == QLatin1String(
"diamond" ) )
350 else if ( cleaned == QLatin1String(
"shield" ) )
352 else if ( cleaned == QLatin1String(
"pentagon" ) )
354 else if ( cleaned == QLatin1String(
"hexagon" ) )
356 else if ( cleaned == QLatin1String(
"octagon" ) )
358 else if ( cleaned == QLatin1String(
"decagon" ) )
360 else if ( cleaned == QLatin1String(
"triangle" ) )
362 else if ( cleaned == QLatin1String(
"equilateral_triangle" ) )
364 else if ( cleaned == QLatin1String(
"star_diamond" ) )
366 else if ( cleaned == QLatin1String(
"star" ) || cleaned == QLatin1String(
"regular_star" ) )
368 else if ( cleaned == QLatin1String(
"heart" ) )
370 else if ( cleaned == QLatin1String(
"arrow" ) )
372 else if ( cleaned == QLatin1String(
"circle" ) )
374 else if ( cleaned == QLatin1String(
"cross" ) )
376 else if ( cleaned == QLatin1String(
"cross_fill" ) )
378 else if ( cleaned == QLatin1String(
"cross2" ) || cleaned == QLatin1String(
"x" ) )
380 else if ( cleaned == QLatin1String(
"line" ) )
382 else if ( cleaned == QLatin1String(
"arrowhead" ) )
384 else if ( cleaned == QLatin1String(
"filled_arrowhead" ) )
386 else if ( cleaned == QLatin1String(
"semi_circle" ) )
388 else if ( cleaned == QLatin1String(
"third_circle" ) )
390 else if ( cleaned == QLatin1String(
"quarter_circle" ) )
392 else if ( cleaned == QLatin1String(
"quarter_square" ) )
394 else if ( cleaned == QLatin1String(
"half_square" ) )
396 else if ( cleaned == QLatin1String(
"diagonal_half_square" ) )
398 else if ( cleaned == QLatin1String(
"right_half_triangle" ) )
400 else if ( cleaned == QLatin1String(
"left_half_triangle" ) )
402 else if ( cleaned == QLatin1String(
"asterisk_fill" ) )
404 else if ( cleaned == QLatin1String(
"half_arc" ) )
406 else if ( cleaned == QLatin1String(
"third_arc" ) )
408 else if ( cleaned == QLatin1String(
"quarter_arc" ) )
421 return QStringLiteral(
"square" );
423 return QStringLiteral(
"quarter_square" );
425 return QStringLiteral(
"half_square" );
427 return QStringLiteral(
"diagonal_half_square" );
429 return QStringLiteral(
"parallelogram_right" );
431 return QStringLiteral(
"parallelogram_left" );
433 return QStringLiteral(
"trapezoid" );
435 return QStringLiteral(
"shield" );
437 return QStringLiteral(
"diamond" );
439 return QStringLiteral(
"pentagon" );
441 return QStringLiteral(
"hexagon" );
443 return QStringLiteral(
"octagon" );
445 return QStringLiteral(
"decagon" );
447 return QStringLiteral(
"square_with_corners" );
449 return QStringLiteral(
"rounded_square" );
451 return QStringLiteral(
"triangle" );
453 return QStringLiteral(
"equilateral_triangle" );
455 return QStringLiteral(
"left_half_triangle" );
457 return QStringLiteral(
"right_half_triangle" );
459 return QStringLiteral(
"star_diamond" );
461 return QStringLiteral(
"star" );
463 return QStringLiteral(
"heart" );
465 return QStringLiteral(
"arrow" );
467 return QStringLiteral(
"filled_arrowhead" );
469 return QStringLiteral(
"cross_fill" );
471 return QStringLiteral(
"circle" );
473 return QStringLiteral(
"cross" );
475 return QStringLiteral(
"cross2" );
477 return QStringLiteral(
"line" );
479 return QStringLiteral(
"arrowhead" );
481 return QStringLiteral(
"semi_circle" );
483 return QStringLiteral(
"third_circle" );
485 return QStringLiteral(
"quarter_circle" );
487 return QStringLiteral(
"asterisk_fill" );
489 return QStringLiteral(
"half_arc" );
491 return QStringLiteral(
"third_arc" );
493 return QStringLiteral(
"quarter_arc" );
510 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 1, 1 ) ) );
515 static constexpr double VERTEX_OFFSET_FROM_ORIGIN = 0.6072;
517 polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
518 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
519 << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
520 << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
521 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
522 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
523 << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
524 << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
525 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
530 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 0 ) ) );
534 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 1 ) ) );
538 polygon << QPointF( -1, -1 ) << QPointF( 1, 1 ) << QPointF( -1, 1 ) << QPointF( -1, -1 );
542 polygon << QPointF( 0.5, -0.5 )
544 << QPointF( -1, 0.5 )
545 << QPointF( -0.5, -0.5 )
546 << QPointF( 0.5, -0.5 );
550 polygon << QPointF( 0.5, 0.5 )
551 << QPointF( 1, -0.5 )
552 << QPointF( -0.5, -0.5 )
553 << QPointF( -1, 0.5 )
554 << QPointF( 0.5, 0.5 );
558 polygon << QPointF( 1, 0.5 )
559 << QPointF( 0.5, -0.5 )
560 << QPointF( -1, -0.5 )
561 << QPointF( -0.5, 0.5 )
562 << QPointF( 1, 0.5 );
566 polygon << QPointF( -1, 0 ) << QPointF( 0, 1 )
567 << QPointF( 1, 0 ) << QPointF( 0, -1 ) << QPointF( -1, 0 );
571 polygon << QPointF( 1, 0.5 )
574 << QPointF( -1, 0.5 )
576 << QPointF( 1, 0.5 );
586 polygon << QPointF( -0.9511, -0.3090 )
587 << QPointF( -0.5878, 0.8090 )
588 << QPointF( 0.5878, 0.8090 )
589 << QPointF( 0.9511, -0.3090 )
591 << QPointF( -0.9511, -0.3090 );
602 polygon << QPointF( -0.8660, -0.5 )
603 << QPointF( -0.8660, 0.5 )
605 << QPointF( 0.8660, 0.5 )
606 << QPointF( 0.8660, -0.5 )
608 << QPointF( -0.8660, -0.5 );
613 static constexpr double VERTEX_OFFSET_FROM_ORIGIN = 1.0 / ( 1 + M_SQRT2 );
615 polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
616 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
617 << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
618 << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
619 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
620 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
621 << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
622 << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
623 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
630 polygon << QPointF( 0.587785252, 0.809016994 )
631 << QPointF( 0.951056516, 0.309016994 )
632 << QPointF( 0.951056516, -0.309016994 )
633 << QPointF( 0.587785252, -0.809016994 )
635 << QPointF( -0.587785252, -0.809016994 )
636 << QPointF( -0.951056516, -0.309016994 )
637 << QPointF( -0.951056516, 0.309016994 )
638 << QPointF( -0.587785252, 0.809016994 )
640 << QPointF( 0.587785252, 0.809016994 );
645 polygon << QPointF( -1, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
653 polygon << QPointF( -0.8660, 0.5 )
654 << QPointF( 0.8660, 0.5 )
656 << QPointF( -0.8660, 0.5 );
660 polygon << QPointF( 0, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( 0, 1 );
664 polygon << QPointF( -1, 1 ) << QPointF( 0, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
669 const double inner_r = std::cos(
DEG2RAD( 72.0 ) ) / std::cos(
DEG2RAD( 36.0 ) );
671 polygon << QPointF( inner_r * std::sin(
DEG2RAD( 315.0 ) ), - inner_r * std::cos(
DEG2RAD( 315.0 ) ) )
672 << QPointF( std::sin(
DEG2RAD( 270 ) ), - std::cos(
DEG2RAD( 270 ) ) )
673 << QPointF( inner_r * std::sin(
DEG2RAD( 225.0 ) ), - inner_r * std::cos(
DEG2RAD( 225.0 ) ) )
674 << QPointF( std::sin(
DEG2RAD( 180 ) ), - std::cos(
DEG2RAD( 180 ) ) )
675 << QPointF( inner_r * std::sin(
DEG2RAD( 135.0 ) ), - inner_r * std::cos(
DEG2RAD( 135.0 ) ) )
676 << QPointF( std::sin(
DEG2RAD( 90 ) ), - std::cos(
DEG2RAD( 90 ) ) )
677 << QPointF( inner_r * std::sin(
DEG2RAD( 45.0 ) ), - inner_r * std::cos(
DEG2RAD( 45.0 ) ) )
678 << QPointF( std::sin(
DEG2RAD( 0 ) ), - std::cos(
DEG2RAD( 0 ) ) );
684 const double inner_r = std::cos(
DEG2RAD( 72.0 ) ) / std::cos(
DEG2RAD( 36.0 ) );
686 polygon << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) )
687 << QPointF( std::sin(
DEG2RAD( 288.0 ) ), - std::cos(
DEG2RAD( 288 ) ) )
688 << QPointF( inner_r * std::sin(
DEG2RAD( 252.0 ) ), - inner_r * std::cos(
DEG2RAD( 252.0 ) ) )
689 << QPointF( std::sin(
DEG2RAD( 216.0 ) ), - std::cos(
DEG2RAD( 216.0 ) ) )
690 << QPointF( 0, inner_r )
691 << QPointF( std::sin(
DEG2RAD( 144.0 ) ), - std::cos(
DEG2RAD( 144.0 ) ) )
692 << QPointF( inner_r * std::sin(
DEG2RAD( 108.0 ) ), - inner_r * std::cos(
DEG2RAD( 108.0 ) ) )
693 << QPointF( std::sin(
DEG2RAD( 72.0 ) ), - std::cos(
DEG2RAD( 72.0 ) ) )
694 << QPointF( inner_r * std::sin(
DEG2RAD( 36.0 ) ), - inner_r * std::cos(
DEG2RAD( 36.0 ) ) )
696 << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) );
701 polygon << QPointF( 0, -1 )
702 << QPointF( 0.5, -0.5 )
703 << QPointF( 0.25, -0.5 )
704 << QPointF( 0.25, 1 )
705 << QPointF( -0.25, 1 )
706 << QPointF( -0.25, -0.5 )
707 << QPointF( -0.5, -0.5 )
712 polygon << QPointF( 0, 0 ) << QPointF( -1, 1 ) << QPointF( -1, -1 ) << QPointF( 0, 0 );
716 polygon << QPointF( -1, -0.2 )
717 << QPointF( -1, -0.2 )
718 << QPointF( -1, 0.2 )
719 << QPointF( -0.2, 0.2 )
720 << QPointF( -0.2, 1 )
722 << QPointF( 0.2, 0.2 )
724 << QPointF( 1, -0.2 )
725 << QPointF( 0.2, -0.2 )
726 << QPointF( 0.2, -1 )
727 << QPointF( -0.2, -1 )
728 << QPointF( -0.2, -0.2 )
729 << QPointF( -1, -0.2 );
734 static constexpr double THICKNESS = 0.3;
735 static constexpr double HALF_THICKNESS = THICKNESS / 2.0;
736 static constexpr double INTERSECTION_POINT = THICKNESS / M_SQRT2;
737 static constexpr double DIAGONAL1 = M_SQRT1_2 - INTERSECTION_POINT * 0.5;
738 static constexpr double DIAGONAL2 = M_SQRT1_2 + INTERSECTION_POINT * 0.5;
740 polygon << QPointF( -HALF_THICKNESS, -1 )
741 << QPointF( HALF_THICKNESS, -1 )
742 << QPointF( HALF_THICKNESS, -HALF_THICKNESS - INTERSECTION_POINT )
743 << QPointF( DIAGONAL1, -DIAGONAL2 )
744 << QPointF( DIAGONAL2, -DIAGONAL1 )
745 << QPointF( HALF_THICKNESS + INTERSECTION_POINT, -HALF_THICKNESS )
746 << QPointF( 1, -HALF_THICKNESS )
747 << QPointF( 1, HALF_THICKNESS )
748 << QPointF( HALF_THICKNESS + INTERSECTION_POINT, HALF_THICKNESS )
749 << QPointF( DIAGONAL2, DIAGONAL1 )
750 << QPointF( DIAGONAL1, DIAGONAL2 )
751 << QPointF( HALF_THICKNESS, HALF_THICKNESS + INTERSECTION_POINT )
752 << QPointF( HALF_THICKNESS, 1 )
753 << QPointF( -HALF_THICKNESS, 1 )
754 << QPointF( -HALF_THICKNESS, HALF_THICKNESS + INTERSECTION_POINT )
755 << QPointF( -DIAGONAL1, DIAGONAL2 )
756 << QPointF( -DIAGONAL2, DIAGONAL1 )
757 << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, HALF_THICKNESS )
758 << QPointF( -1, HALF_THICKNESS )
759 << QPointF( -1, -HALF_THICKNESS )
760 << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, -HALF_THICKNESS )
761 << QPointF( -DIAGONAL2, -DIAGONAL1 )
762 << QPointF( -DIAGONAL1, -DIAGONAL2 )
763 << QPointF( -HALF_THICKNESS, -HALF_THICKNESS - INTERSECTION_POINT )
764 << QPointF( -HALF_THICKNESS, -1 );
789 mPath = QPainterPath();
795 mPath.addEllipse( QRectF( -1, -1, 2, 2 ) );
799 mPath.moveTo( -1, -1 );
800 mPath.addRoundedRect( -1, -1, 2, 2, 0.25, 0.25 );
804 mPath.arcTo( -1, -1, 2, 2, 0, 180 );
805 mPath.lineTo( 0, 0 );
809 mPath.arcTo( -1, -1, 2, 2, 90, 120 );
810 mPath.lineTo( 0, 0 );
814 mPath.arcTo( -1, -1, 2, 2, 90, 90 );
815 mPath.lineTo( 0, 0 );
819 mPath.moveTo( 1, 0 );
820 mPath.arcTo( -1, -1, 2, 2, 0, 180 );
824 mPath.moveTo( 0, -1 );
825 mPath.arcTo( -1, -1, 2, 2, 90, 120 );
829 mPath.moveTo( 0, -1 );
830 mPath.arcTo( -1, -1, 2, 2, 90, 90 );
834 mPath.moveTo( -1, 0 );
835 mPath.lineTo( 1, 0 );
836 mPath.moveTo( 0, -1 );
837 mPath.lineTo( 0, 1 );
841 mPath.moveTo( -1, -1 );
842 mPath.lineTo( 1, 1 );
843 mPath.moveTo( 1, -1 );
844 mPath.lineTo( -1, 1 );
848 mPath.moveTo( 0, -1 );
849 mPath.lineTo( 0, 1 );
853 mPath.moveTo( -1, -1 );
854 mPath.lineTo( 0, 0 );
855 mPath.lineTo( -1, 1 );
859 mPath.moveTo( 0, 0.75 );
860 mPath.arcTo( 0, -1, 1, 1, -45, 210 );
861 mPath.arcTo( -1, -1, 1, 1, 15, 210 );
862 mPath.lineTo( 0, 0.75 );
896 double scaledSize =
mSize;
900 if ( hasDataDefinedSize )
907 if ( hasDataDefinedSize && ok )
912 scaledSize = std::sqrt( scaledSize );
927 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
928 offset = QPointF( offsetX, offsetY );
930 hasDataDefinedRotation =
false;
943 hasDataDefinedRotation =
true;
948 if ( hasDataDefinedRotation )
977 , mStrokeColor( strokeColor )
978 , mPenJoinStyle( penJoinStyle )
995 if ( props.contains( QStringLiteral(
"name" ) ) )
999 if ( props.contains( QStringLiteral(
"color" ) ) )
1001 if ( props.contains( QStringLiteral(
"color_border" ) ) )
1006 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
1010 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
1014 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
1018 if ( props.contains( QStringLiteral(
"size" ) ) )
1019 size = props[QStringLiteral(
"size" )].toDouble();
1020 if ( props.contains( QStringLiteral(
"angle" ) ) )
1021 angle = props[QStringLiteral(
"angle" )].toDouble();
1022 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1026 if ( props.contains( QStringLiteral(
"offset" ) ) )
1028 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1030 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1032 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1034 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1037 if ( props.contains( QStringLiteral(
"outline_style" ) ) )
1041 else if ( props.contains( QStringLiteral(
"line_style" ) ) )
1045 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
1047 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
1049 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
1051 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
1053 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
1057 if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
1061 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
1066 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1070 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1075 if ( props.contains( QStringLiteral(
"cap_style" ) ) )
1088 return QStringLiteral(
"SimpleMarker" );
1095 QColor brushColor =
mColor;
1098 brushColor.setAlphaF(
mColor.alphaF() * context.
opacity() );
1101 mBrush = QBrush( brushColor );
1102 mPen = QPen( penColor );
1112 selBrushColor.setAlphaF( context.
opacity() );
1113 selPenColor.setAlphaF( context.
opacity() );
1116 mSelPen = QPen( selPenColor );
1132 mCachedOpacity = context.
opacity();
1138 mSelPen.setColor( selBrushColor );
1171 scaledSize = ( std::abs( std::sin(
mAngle * M_PI / 180 ) ) + std::abs( std::cos(
mAngle * M_PI / 180 ) ) ) * scaledSize;
1174 const double pw =
static_cast< int >( std::round( ( (
qgsDoubleNear(
mPen.widthF(), 0.0 ) ? 1 :
mPen.widthF() * 4 ) + 1 ) ) ) / 2 * 2;
1175 const int imageSize = (
static_cast< int >( scaledSize ) + pw ) / 2 * 2 + 1;
1176 const double center = imageSize / 2.0;
1182 mCache = QImage( QSize( imageSize * deviceRatio,
1183 imageSize * deviceRatio ), QImage::Format_ARGB32_Premultiplied );
1193 p.setRenderHint( QPainter::Antialiasing );
1194 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
1196 p.translate( QPointF( center, center ) );
1204 mSelCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
1208 p.setRenderHint( QPainter::Antialiasing );
1209 p.setBrush( needsBrush ?
mSelBrush : Qt::NoBrush );
1211 p.translate( QPointF( center, center ) );
1222 p.setRenderHint( QPainter::Antialiasing );
1223 p.fillRect( 0, 0, imageSize, imageSize, selColor );
1224 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
1226 p.translate( QPointF( center, center ) );
1245 QColor brushColor =
mColor;
1246 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
1247 mBrush.setColor( brushColor );
1250 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
1251 mPen.setColor( penColor );
1260 c.setAlphaF(
c.alphaF() * context.
opacity() );
1270 c.setAlphaF(
c.alphaF() * context.
opacity() );
1322 p->setBrush( Qt::NoBrush );
1326 if ( !polygon.isEmpty() )
1327 p->drawPolygon( polygon );
1329 p->drawPath( path );
1346 const double s = img.width() / img.devicePixelRatioF();
1348 bool hasDataDefinedSize =
false;
1349 const double scaledSize =
calculateSize( context, hasDataDefinedSize );
1351 bool hasDataDefinedRotation =
false;
1356 p->drawImage( QRectF( point.x() - s / 2.0 +
offset.x(),
1357 point.y() - s / 2.0 +
offset.y(),
1372 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1375 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1381 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
1414 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
1415 element.appendChild( graphicElem );
1431 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
1434 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
1451 Q_UNUSED( mmScaleFactor )
1452 Q_UNUSED( mapUnitScaleFactor )
1454 QString ogrType =
"3";
1455 if ( mName ==
"square" )
1459 else if ( mName ==
"triangle" )
1463 else if ( mName ==
"star" )
1467 else if ( mName ==
"circle" )
1471 else if ( mName ==
"cross" )
1475 else if ( mName ==
"x" || mName ==
"cross2" )
1479 else if ( mName ==
"line" )
1485 ogrString.append(
"SYMBOL(" );
1486 ogrString.append(
"id:" );
1487 ogrString.append(
'\"' );
1488 ogrString.append(
"ogr-sym-" );
1489 ogrString.append( ogrType );
1490 ogrString.append(
'\"' );
1491 ogrString.append(
",c:" );
1492 ogrString.append(
mColor.name() );
1493 ogrString.append(
",o:" );
1495 ogrString.append( QString(
",s:%1mm" ).arg(
mSize ) );
1496 ogrString.append(
')' );
1501 ogrString.append(
"PEN(" );
1502 ogrString.append(
"c:" );
1503 ogrString.append(
mColor.name() );
1504 ogrString.append(
",w:" );
1505 ogrString.append( QString::number(
mSize ) );
1506 ogrString.append(
"mm" );
1507 ogrString.append(
")" );
1515 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1516 if ( graphicElem.isNull() )
1519 QString name = QStringLiteral(
"square" );
1532 const double d = angleFunc.toDouble( &ok );
1542 double scaleFactor = 1.0;
1543 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
1570 p->drawPath(
mPath );
1583 if ( hasDataDefinedSize )
1600 if (
mSizeUnit == Qgis::RenderUnit::Millimeters )
1602 size *= mmMapUnitScaleFactor;
1605 if (
mSizeUnit == Qgis::RenderUnit::MapUnits )
1609 const double halfSize =
size / 2.0;
1620 if (
mSizeUnit == Qgis::RenderUnit::MapUnits )
1626 QColor pc =
mPen.color();
1627 QColor bc =
mBrush.color();
1647 QPointF off( offsetX, offsetY );
1676 t.translate( shift.x() + off.x(), shift.y() - off.y() );
1684 t.scale( halfSize, -halfSize );
1686 polygon = t.map( polygon );
1689 p.reserve( polygon.size() );
1690 for (
int i = 0; i < polygon.size(); i++ )
1695 if (
mBrush.style() != Qt::NoBrush )
1697 if (
mPen.style() != Qt::NoPen )
1702 shift += QPointF( off.x(), -off.y() );
1703 if (
mBrush.style() != Qt::NoBrush )
1705 if (
mPen.style() != Qt::NoPen )
1710 const QPointF pt1 = t.map( QPointF( 0, -halfSize ) );
1711 const QPointF pt2 = t.map( QPointF( 0, halfSize ) );
1713 if (
mPen.style() != Qt::NoPen )
1718 if (
mPen.style() != Qt::NoPen )
1720 const QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
1721 const QPointF pt2 = t.map( QPointF( halfSize, 0 ) );
1722 const QPointF pt3 = t.map( QPointF( 0, -halfSize ) );
1723 const QPointF pt4 = t.map( QPointF( 0, halfSize ) );
1731 if (
mPen.style() != Qt::NoPen )
1733 const QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
1734 const QPointF pt2 = t.map( QPointF( halfSize, halfSize ) );
1735 const QPointF pt3 = t.map( QPointF( halfSize, -halfSize ) );
1736 const QPointF pt4 = t.map( QPointF( -halfSize, halfSize ) );
1744 if (
mPen.style() != Qt::NoPen )
1746 const QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
1747 const QPointF pt2 = t.map( QPointF( 0, 0 ) );
1748 const QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
1776 return Qgis::RenderUnit::Unknown;
1796 return mSizeUnit == Qgis::RenderUnit::MapUnits ||
mSizeUnit == Qgis::RenderUnit::MetersInMapUnits
1834 symbolBounds.adjust( -penWidth / 2.0, -penWidth / 2.0,
1835 penWidth / 2.0, penWidth / 2.0 );
1837 return symbolBounds;
1886 if ( props.contains( QStringLiteral(
"name" ) ) )
1887 name = props[QStringLiteral(
"name" )].toString();
1888 if ( props.contains( QStringLiteral(
"size" ) ) )
1889 size = props[QStringLiteral(
"size" )].toDouble();
1890 if ( props.contains( QStringLiteral(
"angle" ) ) )
1891 angle = props[QStringLiteral(
"angle" )].toDouble();
1892 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1896 if ( props.contains( QStringLiteral(
"offset" ) ) )
1898 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1900 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1902 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1904 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1906 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1910 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1924 return QStringLiteral(
"FilledMarker" );
1949 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1952 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2008 attr.unite( mFill->usedAttributes( context ) );
2016 if ( mFill && mFill->hasDataDefinedProperties() )
2025 mFill->setColor(
c );
2030 return mFill ? mFill->color() :
mColor;
2035 return mSizeUnit == Qgis::RenderUnit::MapUnits ||
mSizeUnit == Qgis::RenderUnit::MetersInMapUnits
2037 || ( mFill && mFill->usesMapUnits() );
2044 mFill->setOutputUnit( unit );
2058 const double prevOpacity = mFill->opacity();
2059 mFill->setOpacity( mFill->opacity() * context.
opacity() );
2063 p->setBrush( Qt::red );
2067 p->setBrush( Qt::NoBrush );
2069 p->setPen( Qt::black );
2074 if ( !polygon.isEmpty() )
2080 const QPolygonF poly = path.toFillPolygon();
2086 mFill->setOpacity( prevOpacity );
2101 mColor = QColor( 35, 35, 35 );
2115 if ( props.contains( QStringLiteral(
"name" ) ) )
2116 name = props[QStringLiteral(
"name" )].toString();
2117 if ( props.contains( QStringLiteral(
"size" ) ) )
2118 size = props[QStringLiteral(
"size" )].toDouble();
2119 if ( props.contains( QStringLiteral(
"angle" ) ) )
2120 angle = props[QStringLiteral(
"angle" )].toDouble();
2121 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
2126 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
2128 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
2130 if ( props.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
2132 if ( props.contains( QStringLiteral(
"offset" ) ) )
2134 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
2136 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2138 if ( props.contains( QStringLiteral(
"fill" ) ) )
2143 else if ( props.contains( QStringLiteral(
"color" ) ) )
2147 if ( props.contains( QStringLiteral(
"outline" ) ) )
2152 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
2156 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
2161 if ( props.contains( QStringLiteral(
"outline-width" ) ) )
2164 m->
setStrokeWidth( props[QStringLiteral(
"outline-width" )].toDouble() );
2166 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
2168 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
2170 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
2172 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
2175 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
2179 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
2183 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2186 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
2190 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
2199 if ( props.contains( QStringLiteral(
"parameters" ) ) )
2201 const QVariantMap
parameters = props[QStringLiteral(
"parameters" )].toMap();
2210 const QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
2229 QColor defaultFillColor, defaultStrokeColor;
2231 bool hasFillOpacityParam =
false, hasStrokeParam =
false, hasStrokeWidthParam =
false, hasStrokeOpacityParam =
false;
2232 bool hasDefaultFillColor =
false, hasDefaultFillOpacity =
false, hasDefaultStrokeColor =
false, hasDefaultStrokeWidth =
false, hasDefaultStrokeOpacity =
false;
2234 hasFillOpacityParam, hasDefaultFillOpacity, fillOpacity,
2235 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2236 hasStrokeWidthParam, hasDefaultStrokeWidth,
strokeWidth,
2237 hasStrokeOpacityParam, hasDefaultStrokeOpacity, strokeOpacity );
2239 const double newFillOpacity = hasFillOpacityParam ?
fillColor().alphaF() : 1.0;
2240 const double newStrokeOpacity = hasStrokeOpacityParam ?
strokeColor().alphaF() : 1.0;
2242 if ( hasDefaultFillColor )
2244 defaultFillColor.setAlphaF( newFillOpacity );
2247 if ( hasDefaultFillOpacity )
2250 c.setAlphaF( fillOpacity );
2253 if ( hasDefaultStrokeColor )
2255 defaultStrokeColor.setAlphaF( newStrokeOpacity );
2258 if ( hasDefaultStrokeWidth )
2262 if ( hasDefaultStrokeOpacity )
2265 c.setAlphaF( strokeOpacity );
2279 const double widthScaleFactor = 3.465;
2282 mDefaultAspectRatio = svgViewbox.isValid() ? svgViewbox.height() / svgViewbox.width() : 0.0;
2290 if ( aPreservedAspectRatio && !par )
2294 else if ( !aPreservedAspectRatio && par )
2309 return QStringLiteral(
"SvgMarker" );
2329 bool hasDataDefinedSize =
false;
2330 const double scaledWidth = calculateSize( context, hasDataDefinedSize );
2335 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
2342 bool hasDataDefinedAspectRatio =
false;
2343 const double aspectRatio =
calculateAspectRatio( context, scaledWidth, hasDataDefinedAspectRatio );
2386 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
2390 QPointF outputOffset;
2392 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
2394 p->translate( point + outputOffset );
2400 bool fitsInCache =
true;
2401 bool usePict =
true;
2408 if ( fitsInCache && img.width() > 1 )
2420 QImage transparentImage = img.copy();
2422 if ( devicePixelRatio == 1 )
2424 p->drawImage( -transparentImage.width() / 2.0, -transparentImage.height() / 2.0, transparentImage );
2428 p->drawImage( QRectF( -transparentImage.width() / 2.0 / devicePixelRatio, -transparentImage.height() / 2.0 / devicePixelRatio,
2429 transparentImage.width() / devicePixelRatio, transparentImage.height() / devicePixelRatio
2430 ), transparentImage );
2435 if ( devicePixelRatio == 1 )
2437 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
2441 p->drawImage( QRectF( -img.width() / 2.0 / devicePixelRatio, -img.height() / 2.0 / devicePixelRatio,
2442 img.width() / devicePixelRatio, img.height() / devicePixelRatio ), img );
2448 if ( usePict || !fitsInCache )
2450 p->setOpacity( context.
opacity() );
2454 if ( pct.width() > 1 )
2457 _fixQPictureDPI( p );
2458 p->drawPicture( 0, 0, pct );
2466double QgsSvgMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
2468 double scaledSize =
mSize;
2472 if ( hasDataDefinedSize )
2480 if ( hasDataDefinedSize )
2487 if ( hasDataDefinedSize && ok )
2492 scaledSize = std::sqrt( scaledSize );
2505 if ( !hasDataDefinedAspectRatio )
2515 const double defaultHeight =
mSize * scaledAspectRatio;
2516 scaledAspectRatio = defaultHeight / scaledSize;
2519 double scaledHeight = scaledSize * scaledAspectRatio;
2526 if ( hasDataDefinedAspectRatio && ok )
2531 scaledHeight = sqrt( scaledHeight );
2538 scaledAspectRatio = scaledHeight / scaledSize;
2540 return scaledAspectRatio;
2543void QgsSvgMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &
angle )
const
2548 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
2549 offset = QPointF( offsetX, offsetY );
2559 if ( hasDataDefinedRotation )
2585 map[QStringLiteral(
"name" )] =
mPath;
2586 map[QStringLiteral(
"size" )] = QString::number(
mSize );
2589 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
2590 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2597 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
2610 return mSizeUnit == Qgis::RenderUnit::MapUnits ||
mSizeUnit == Qgis::RenderUnit::MetersInMapUnits
2649 return Qgis::RenderUnit::Unknown;
2672 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2673 element.appendChild( graphicElem );
2683 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2686 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
2704 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
2705 if ( graphicElem.isNull() )
2708 QString
path, mimeType;
2716 double scaleFactor = 1.0;
2717 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
2721 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2729 const double d = angleFunc.toDouble( &ok );
2738 QString realPath {
path };
2739 QUrl svgUrl {
path };
2742 QUrlQuery queryString;
2744 if ( svgUrl.hasQuery() && svgUrl.hasFragment() )
2746 const QString queryPart {
path.mid(
path.indexOf(
'?' ) + 1 ) };
2747 queryString.setQuery( queryPart );
2751 if ( svgUrl.scheme().isEmpty() || svgUrl.isLocalFile() )
2753 svgUrl.setQuery( QString() );
2754 realPath = svgUrl.path();
2759 QMap<QString, QgsProperty> params;
2763 if ( queryString.hasQueryItem( QStringLiteral(
"fill" ) ) )
2765 const QColor
fillColor { queryString.queryItemValue( QStringLiteral(
"fill" ) ) };
2769 if ( queryString.hasQueryItem( QStringLiteral(
"fill-opacity" ) ) )
2771 const double alpha { queryString.queryItemValue( QStringLiteral(
"fill-opacity" ) ).toDouble( &ok ) };
2778 if ( queryString.hasQueryItem( QStringLiteral(
"outline" ) ) )
2780 const QColor
strokeColor { queryString.queryItemValue( QStringLiteral(
"outline" ) ) };
2784 if ( queryString.hasQueryItem( QStringLiteral(
"outline-opacity" ) ) )
2786 const double alpha { queryString.queryItemValue( QStringLiteral(
"outline-opacity" ) ).toDouble( &ok ) };
2793 if ( queryString.hasQueryItem( QStringLiteral(
"outline-width" ) ) )
2795 const int width { queryString.queryItemValue( QStringLiteral(
"outline-width" ) ).toInt( &ok )};
2802 if ( ! params.isEmpty() )
2821 if ( hasDataDefinedSize )
2827 if ( hasDataDefinedSize && ok )
2839 if (
mSizeUnit == Qgis::RenderUnit::Millimeters )
2841 size *= mmMapUnitScaleFactor;
2855 const double offsetX =
offset.x();
2856 const double offsetY =
offset.y();
2858 QPointF outputOffset( offsetX, offsetY );
2908 QSvgRenderer r( svgContent );
2915 QSizeF outSize( r.defaultSize() );
2916 outSize.scale(
size,
size, Qt::KeepAspectRatio );
2922 p.translate( r.defaultSize().width() / 2.0, r.defaultSize().height() / 2.0 );
2924 p.translate( -r.defaultSize().width() / 2.0, -r.defaultSize().height() / 2.0 );
2926 pd.
setShift( shift + QPointF( outputOffset.x(), -outputOffset.y() ) );
2927 pd.
setOutputSize( QRectF( -outSize.width() / 2.0, -outSize.height() / 2.0, outSize.width(), outSize.height() ) );
2936 bool hasDataDefinedSize =
false;
2937 double scaledWidth = calculateSize( context, hasDataDefinedSize );
2939 bool hasDataDefinedAspectRatio =
false;
2940 const double aspectRatio =
calculateAspectRatio( context, scaledWidth, hasDataDefinedAspectRatio );
2947 if (
static_cast< int >( scaledWidth ) < 1 || 10000.0 < scaledWidth )
2952 QPointF outputOffset;
2954 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
2993 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
2997 QTransform transform;
2999 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
3002 transform.rotate(
angle );
3007 QRectF symbolBounds = transform.mapRect( QRectF( -scaledWidth / 2.0,
3008 -scaledHeight / 2.0,
3016 return symbolBounds;
3040 if ( props.contains( QStringLiteral(
"imageFile" ) ) )
3041 path = props[QStringLiteral(
"imageFile" )].toString();
3042 if ( props.contains( QStringLiteral(
"size" ) ) )
3043 size = props[QStringLiteral(
"size" )].toDouble();
3044 if ( props.contains( QStringLiteral(
"angle" ) ) )
3045 angle = props[QStringLiteral(
"angle" )].toDouble();
3046 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
3049 std::unique_ptr< QgsRasterMarkerSymbolLayer > m = std::make_unique< QgsRasterMarkerSymbolLayer >(
path,
size,
angle,
scaleMethod );
3050 m->setCommonProperties( props );
3056 if (
properties.contains( QStringLiteral(
"alpha" ) ) )
3061 if (
properties.contains( QStringLiteral(
"size_unit" ) ) )
3063 if (
properties.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
3065 if (
properties.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
3068 if (
properties.contains( QStringLiteral(
"offset" ) ) )
3070 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
3072 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
3075 if (
properties.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
3079 if (
properties.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
3090 const QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
3091 if ( it !=
properties.end() && it.value().type() == QVariant::String )
3109 if ( aPreservedAspectRatio && !par )
3113 else if ( !aPreservedAspectRatio && par )
3132 return QStringLiteral(
"RasterMarker" );
3148 if (
path.isEmpty() )
3152 double height = 0.0;
3154 bool hasDataDefinedSize =
false;
3155 const double scaledSize = calculateSize( context, hasDataDefinedSize );
3157 bool hasDataDefinedAspectRatio =
false;
3158 const double aspectRatio =
calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
3160 QPointF outputOffset;
3164 if (
mSizeUnit == Qgis::RenderUnit::Percentage )
3167 if (
size.isEmpty() )
3170 width = ( scaledSize *
static_cast< double >(
size.width() ) ) / 100.0;
3171 height = ( scaledSize *
static_cast< double >(
size.height() ) ) / 100.0;
3174 if (
static_cast< int >( width ) < 1 || 10000.0 < width ||
static_cast< int >( height ) < 1 || 10000.0 < height )
3177 calculateOffsetAndRotation( context, width, height, outputOffset,
angle );
3187 if ( !
size.isNull() &&
size.isValid() &&
size.width() > 0 )
3189 height = width * (
static_cast< double >(
size.height() ) /
static_cast< double >(
size.width() ) );
3194 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
3197 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
3201 p->translate( point + outputOffset );
3216 if ( !img.isNull() )
3223 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
3229 bool cached =
false;
3233double QgsRasterMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
3235 double scaledSize =
mSize;
3239 if ( hasDataDefinedSize )
3247 if ( hasDataDefinedSize )
3254 if ( hasDataDefinedSize && ok )
3259 scaledSize = std::sqrt( scaledSize );
3272 if ( !hasDataDefinedAspectRatio )
3282 const double defaultHeight =
mSize * scaledAspectRatio;
3283 scaledAspectRatio = defaultHeight / scaledSize;
3286 double scaledHeight = scaledSize * scaledAspectRatio;
3293 if ( hasDataDefinedAspectRatio && ok )
3298 scaledHeight = sqrt( scaledHeight );
3305 scaledAspectRatio = scaledHeight / scaledSize;
3307 return scaledAspectRatio;
3310void QgsRasterMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &
angle )
const
3315 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
3316 offset = QPointF( offsetX, offsetY );
3326 if ( hasDataDefinedRotation )
3347 map[QStringLiteral(
"imageFile" )] =
mPath;
3348 map[QStringLiteral(
"size" )] = QString::number(
mSize );
3351 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
3352 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
3353 map[QStringLiteral(
"alpha" )] = QString::number(
mOpacity );
3365 std::unique_ptr< QgsRasterMarkerSymbolLayer > m = std::make_unique< QgsRasterMarkerSymbolLayer >(
mPath,
mSize,
mAngle );
3388 return mSizeUnit == Qgis::RenderUnit::MapUnits ||
mSizeUnit == Qgis::RenderUnit::MetersInMapUnits
3409 bool hasDataDefinedSize =
false;
3410 const double scaledSize = calculateSize( context, hasDataDefinedSize );
3412 bool hasDataDefinedAspectRatio =
false;
3413 const double aspectRatio =
calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
3417 if (
static_cast< int >( scaledSize ) < 1 || 10000.0 < scaledSize )
3422 QPointF outputOffset;
3424 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
3426 QTransform transform;
3429 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
3432 transform.rotate(
angle );
3434 QRectF symbolBounds = transform.mapRect( QRectF( -width / 2.0,
3439 return symbolBounds;
3451 mOrigSize = pointSize;
3452 mSizeUnit = Qgis::RenderUnit::Millimeters;
3457 mStrokeWidthUnit = Qgis::RenderUnit::Millimeters;
3471 if ( props.contains( QStringLiteral(
"font" ) ) )
3472 fontFamily = props[QStringLiteral(
"font" )].toString();
3473 if ( props.contains( QStringLiteral(
"chr" ) ) && props[QStringLiteral(
"chr" )].toString().length() > 0 )
3474 string = props[QStringLiteral(
"chr" )].toString();
3475 if ( props.contains( QStringLiteral(
"size" ) ) )
3476 pointSize = props[QStringLiteral(
"size" )].toDouble();
3477 if ( props.contains( QStringLiteral(
"color" ) ) )
3479 if ( props.contains( QStringLiteral(
"angle" ) ) )
3480 angle = props[QStringLiteral(
"angle" )].toDouble();
3484 if ( props.contains( QStringLiteral(
"font_style" ) ) )
3485 m->
setFontStyle( props[QStringLiteral(
"font_style" )].toString() );
3486 if ( props.contains( QStringLiteral(
"outline_color" ) ) )
3488 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
3489 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
3490 if ( props.contains( QStringLiteral(
"offset" ) ) )
3492 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
3494 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
3496 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
3498 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
3500 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
3502 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
3504 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
3506 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
3508 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
3518 return QStringLiteral(
"FontMarker" );
3523 QColor brushColor =
mColor;
3524 QColor penColor = mStrokeColor;
3526 brushColor.setAlphaF(
mColor.alphaF() * context.
opacity() );
3527 penColor.setAlphaF( mStrokeColor.alphaF() * context.
opacity() );
3529 mBrush = QBrush( brushColor );
3530 mPen = QPen( penColor );
3531 mPen.setJoinStyle( mPenJoinStyle );
3535 if ( !mFontStyle.isEmpty() )
3543 if ( mNonZeroFontSize && sizePixels > MAX_FONT_CHARACTER_SIZE_IN_PIXELS )
3548 mFontSizeScale = sizePixels / MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
3549 sizePixels = MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
3552 mFontSizeScale = 1.0;
3556 mFont.setPixelSize( std::max( 2,
static_cast< int >( std::round( sizePixels ) ) ) );
3557 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3558 mChrWidth = mFontMetrics->horizontalAdvance( mString );
3559 mChrOffset = QPointF( mChrWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3566 if ( mUseCachedPath )
3568 QPointF chrOffset = mChrOffset;
3570 const QString charToRender = characterToRender( context, chrOffset, chrWidth );
3571 mCachedPath = QPainterPath();
3572 mCachedPath.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
3581QString QgsFontMarkerSymbolLayer::characterToRender(
QgsSymbolRenderContext &context, QPointF &charOffset,
double &charWidth )
3583 charOffset = mChrOffset;
3584 QString stringToRender = mString;
3589 if ( stringToRender != mString )
3591 charWidth = mFontMetrics->horizontalAdvance( stringToRender );
3592 charOffset = QPointF( charWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3595 return stringToRender;
3600 bool &hasDataDefinedRotation,
3602 double &
angle )
const
3607 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
3608 offset = QPointF( offsetX, offsetY );
3624 if ( hasDataDefinedRotation )
3648 double scaledSize =
mSize;
3652 if ( hasDataDefinedSize )
3658 if ( hasDataDefinedSize && ok )
3663 scaledSize = std::sqrt( scaledSize );
3675 if ( !p || !mNonZeroFontSize )
3678 QTransform transform;
3681 QColor brushColor =
mColor;
3690 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
3692 mBrush.setColor( brushColor );
3694 QColor penColor = mStrokeColor;
3700 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
3724 p->setBrush( mBrush );
3727 mPen.setColor( penColor );
3728 mPen.setWidthF( penWidth );
3733 p->setPen( Qt::NoPen );
3741 mFont.setFamily( processedFamily );
3751 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3754 QPointF chrOffset = mChrOffset;
3756 const QString charToRender = characterToRender( context, chrOffset, chrWidth );
3758 const double sizeToRender = calculateSize( context );
3760 bool hasDataDefinedRotation =
false;
3763 calculateOffsetAndRotation( context, sizeToRender, hasDataDefinedRotation,
offset,
angle );
3765 p->translate( point.x() +
offset.x(), point.y() +
offset.y() );
3768 transform.rotate(
angle );
3772 const double s = sizeToRender / mOrigSize;
3773 transform.scale( s, s );
3777 transform.scale( mFontSizeScale, mFontSizeScale );
3779 if ( mUseCachedPath )
3781 p->drawPath( transform.map( mCachedPath ) );
3786 path.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
3787 p->drawPath( transform.map( path ) );
3794 props[QStringLiteral(
"font" )] = mFontFamily;
3795 props[QStringLiteral(
"font_style" )] = mFontStyle;
3796 props[QStringLiteral(
"chr" )] = mString;
3797 props[QStringLiteral(
"size" )] = QString::number(
mSize );
3802 props[QStringLiteral(
"outline_width" )] = QString::number( mStrokeWidth );
3806 props[QStringLiteral(
"angle" )] = QString::number(
mAngle );
3839 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
3840 element.appendChild( graphicElem );
3842 const QString fontPath = QStringLiteral(
"ttf://%1" ).arg( mFontFamily );
3843 int markIndex = !mString.isEmpty() ? mString.at( 0 ).unicode() : 0;
3850 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
3853 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
3868 return mSizeUnit == Qgis::RenderUnit::MapUnits ||
mSizeUnit == Qgis::RenderUnit::MetersInMapUnits
3869 || mStrokeWidthUnit == Qgis::RenderUnit::MapUnits || mStrokeWidthUnit == Qgis::RenderUnit::MetersInMapUnits
3876 mStrokeWidthUnit = unit;
3881 QPointF chrOffset = mChrOffset;
3882 double chrWidth = mChrWidth;
3884 ( void )characterToRender( context, chrOffset, chrWidth );
3886 if ( !mFontMetrics )
3887 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3889 double scaledSize = calculateSize( context );
3892 chrWidth *= scaledSize / mOrigSize;
3894 chrWidth *= mFontSizeScale;
3896 bool hasDataDefinedRotation =
false;
3899 calculateOffsetAndRotation( context, scaledSize, hasDataDefinedRotation,
offset,
angle );
3902 QTransform transform;
3905 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
3908 transform.rotate(
angle );
3910 QRectF symbolBounds = transform.mapRect( QRectF( -chrWidth / 2.0,
3914 return symbolBounds;
3921 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
3922 if ( graphicElem.isNull() )
3925 QString name, format;
3933 if ( !name.startsWith( QLatin1String(
"ttf://" ) ) || format != QLatin1String(
"ttf" ) )
3943 const double d = angleFunc.toDouble( &ok );
3951 double scaleFactor = 1.0;
3952 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
3973 context.
pushMessage( QObject::tr(
"Font “%1” not available on system" ).arg( processedFamily ) );
3979 QMap<QString, QgsProperty>::iterator it =
mParameters.begin();
3991 QMap<QString, QgsProperty>::const_iterator it =
mParameters.constBegin();
3994 attrs.unite( it.value().referencedFields( context.
expressionContext(),
true ) );
4018 if (
properties.contains( QStringLiteral(
"imageFile" ) ) )
4020 if (
properties.contains( QStringLiteral(
"size" ) ) )
4022 if (
properties.contains( QStringLiteral(
"angle" ) ) )
4025 std::unique_ptr< QgsAnimatedMarkerSymbolLayer > m = std::make_unique< QgsAnimatedMarkerSymbolLayer >(
path,
size,
angle );
4026 m->setFrameRate(
properties.value( QStringLiteral(
"frameRate" ), QStringLiteral(
"10" ) ).toDouble() );
4034 return QStringLiteral(
"AnimatedMarker" );
4040 res.insert( QStringLiteral(
"frameRate" ), mFrameRateFps );
4046 std::unique_ptr< QgsAnimatedMarkerSymbolLayer > m = std::make_unique< QgsAnimatedMarkerSymbolLayer >(
mPath,
mSize,
mAngle );
4047 m->setFrameRate( mFrameRateFps );
4056 mPreparedPaths.clear();
4064 mStaticPath =
false;
4070 if ( !mStaticPath && !mPreparedPaths.contains(
path ) )
4073 mPreparedPaths.insert(
path );
4076 const long long mapFrameNumber = context.
currentFrame();
4078 const double markerAnimationDuration = totalFrameCount / mFrameRateFps;
4080 double animationTimeSeconds = 0;
4081 if ( mapFrameNumber >= 0 && context.
frameRate() > 0 )
4084 animationTimeSeconds = mapFrameNumber / context.
frameRate();
4089 animationTimeSeconds = QDateTime::currentMSecsSinceEpoch() / 1000.0;
4092 const double markerAnimationProgressSeconds = std::fmod( animationTimeSeconds, markerAnimationDuration );
4093 const int movieFrame =
static_cast< int >( std::floor( markerAnimationProgressSeconds * mFrameRateFps ) );
4095 bool cached =
false;
@ DynamicRotation
Rotation of symbol may be changed during rendering and symbol should not be cached.
ScaleMethod
Scale methods.
@ ScaleDiameter
Calculate scale by the diameter.
@ ScaleArea
Calculate scale by the area.
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.
@ 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...
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())
static QString translateNamedStyle(const QString &namedStyle)
Returns the localized named style of a font, if such a translation is available.
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.
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.
QgsProperty property(int key) const override
Returns a matching property from the collection, if one exists.
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const override
Returns the calculated value of the property with the specified key from within the collection.
bool isActive(int key) const override
Returns true if the collection contains an active property with the specified key.
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.
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.
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.
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 QColor decodeColor(const QString &str)
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.
@ PropertyStrokeStyle
Stroke style (eg solid, dashed)
@ PropertyCapStyle
Line cap style.
@ PropertyAngle
Symbol angle.
@ PropertySize
Symbol size.
@ PropertyJoinStyle
Line join style.
@ PropertyOpacity
Opacity.
@ PropertyCharacter
Character, eg for font marker symbol layers.
@ PropertyOffset
Symbol offset.
@ PropertyStrokeWidth
Stroke width.
@ PropertyFillColor
Fill color.
@ PropertyFontStyle
Font style.
@ PropertyHeight
Symbol height.
@ PropertyFontFamily
Font family.
@ PropertyName
Name, eg shape name for simple markers.
@ PropertyStrokeColor
Stroke color.
@ PropertyWidth
Symbol width.
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.
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
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.
void copyPaintEffect(QgsSymbolLayer *destLayer) const
Copies paint effect of this layer to another symbol layer.
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.
bool selected() const
Returns true if symbols should be rendered using the selected symbol coloring and style.
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)
Returns true if the specified variant should be considered a NULL value.
double ANALYSIS_EXPORT angle(QgsPoint *p1, QgsPoint *p2, QgsPoint *p3, QgsPoint *p4)
Calculates the angle between two segments (in 2 dimension, z-values are ignored)
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