35#include <QMimeDatabase>
38#include <QSvgRenderer>
41#include <QDomDocument>
47static constexpr int MAX_FONT_CHARACTER_SIZE_IN_PIXELS = 500;
58 QList< Qgis::MarkerShape > shapes;
173 QTransform transform;
176 if ( !hasDataDefinedSize )
186 const double half = scaledSize / 2.0;
187 transform.scale( half, half );
193 transform.rotate(
mAngle );
220 bool hasDataDefinedSize =
false;
221 const double scaledSize =
calculateSize( context, hasDataDefinedSize );
223 bool hasDataDefinedRotation =
false;
229 bool createdNewPath =
false;
247 createdNewPath =
true;
256 QTransform transform;
259 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
262 if ( hasDataDefinedSize || createdNewPath )
271 const double half = s / 2.0;
272 transform.scale( half, half );
277 transform.rotate(
angle );
286 polygon = transform.map(
mPolygon );
290 path = transform.map(
mPath );
292 draw( context, symbol, polygon, path );
297 bool hasDataDefinedSize =
false;
298 double scaledSize =
calculateSize( context, hasDataDefinedSize );
300 bool hasDataDefinedRotation =
false;
307 QTransform transform;
310 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
313 transform.rotate(
angle );
315 return transform.mapRect( QRectF( -scaledSize / 2.0,
325 const QString cleaned = name.toLower().trimmed();
327 if ( cleaned == QLatin1String(
"square" ) || cleaned == QLatin1String(
"rectangle" ) )
329 else if ( cleaned == QLatin1String(
"trapezoid" ) )
331 else if ( cleaned == QLatin1String(
"parallelogram_right" ) )
333 else if ( cleaned == QLatin1String(
"parallelogram_left" ) )
335 else if ( cleaned == QLatin1String(
"square_with_corners" ) )
337 else if ( cleaned == QLatin1String(
"rounded_square" ) )
339 else if ( cleaned == QLatin1String(
"diamond" ) )
341 else if ( cleaned == QLatin1String(
"shield" ) )
343 else if ( cleaned == QLatin1String(
"pentagon" ) )
345 else if ( cleaned == QLatin1String(
"hexagon" ) )
347 else if ( cleaned == QLatin1String(
"octagon" ) )
349 else if ( cleaned == QLatin1String(
"decagon" ) )
351 else if ( cleaned == QLatin1String(
"triangle" ) )
353 else if ( cleaned == QLatin1String(
"equilateral_triangle" ) )
355 else if ( cleaned == QLatin1String(
"star_diamond" ) )
357 else if ( cleaned == QLatin1String(
"star" ) || cleaned == QLatin1String(
"regular_star" ) )
359 else if ( cleaned == QLatin1String(
"heart" ) )
361 else if ( cleaned == QLatin1String(
"arrow" ) )
363 else if ( cleaned == QLatin1String(
"circle" ) )
365 else if ( cleaned == QLatin1String(
"cross" ) )
367 else if ( cleaned == QLatin1String(
"cross_fill" ) )
369 else if ( cleaned == QLatin1String(
"cross2" ) || cleaned == QLatin1String(
"x" ) )
371 else if ( cleaned == QLatin1String(
"line" ) )
373 else if ( cleaned == QLatin1String(
"arrowhead" ) )
375 else if ( cleaned == QLatin1String(
"filled_arrowhead" ) )
377 else if ( cleaned == QLatin1String(
"semi_circle" ) )
379 else if ( cleaned == QLatin1String(
"third_circle" ) )
381 else if ( cleaned == QLatin1String(
"quarter_circle" ) )
383 else if ( cleaned == QLatin1String(
"quarter_square" ) )
385 else if ( cleaned == QLatin1String(
"half_square" ) )
387 else if ( cleaned == QLatin1String(
"diagonal_half_square" ) )
389 else if ( cleaned == QLatin1String(
"right_half_triangle" ) )
391 else if ( cleaned == QLatin1String(
"left_half_triangle" ) )
393 else if ( cleaned == QLatin1String(
"asterisk_fill" ) )
395 else if ( cleaned == QLatin1String(
"half_arc" ) )
397 else if ( cleaned == QLatin1String(
"third_arc" ) )
399 else if ( cleaned == QLatin1String(
"quarter_arc" ) )
412 return QStringLiteral(
"square" );
414 return QStringLiteral(
"quarter_square" );
416 return QStringLiteral(
"half_square" );
418 return QStringLiteral(
"diagonal_half_square" );
420 return QStringLiteral(
"parallelogram_right" );
422 return QStringLiteral(
"parallelogram_left" );
424 return QStringLiteral(
"trapezoid" );
426 return QStringLiteral(
"shield" );
428 return QStringLiteral(
"diamond" );
430 return QStringLiteral(
"pentagon" );
432 return QStringLiteral(
"hexagon" );
434 return QStringLiteral(
"octagon" );
436 return QStringLiteral(
"decagon" );
438 return QStringLiteral(
"square_with_corners" );
440 return QStringLiteral(
"rounded_square" );
442 return QStringLiteral(
"triangle" );
444 return QStringLiteral(
"equilateral_triangle" );
446 return QStringLiteral(
"left_half_triangle" );
448 return QStringLiteral(
"right_half_triangle" );
450 return QStringLiteral(
"star_diamond" );
452 return QStringLiteral(
"star" );
454 return QStringLiteral(
"heart" );
456 return QStringLiteral(
"arrow" );
458 return QStringLiteral(
"filled_arrowhead" );
460 return QStringLiteral(
"cross_fill" );
462 return QStringLiteral(
"circle" );
464 return QStringLiteral(
"cross" );
466 return QStringLiteral(
"cross2" );
468 return QStringLiteral(
"line" );
470 return QStringLiteral(
"arrowhead" );
472 return QStringLiteral(
"semi_circle" );
474 return QStringLiteral(
"third_circle" );
476 return QStringLiteral(
"quarter_circle" );
478 return QStringLiteral(
"asterisk_fill" );
480 return QStringLiteral(
"half_arc" );
482 return QStringLiteral(
"third_arc" );
484 return QStringLiteral(
"quarter_arc" );
501 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 1, 1 ) ) );
506 static constexpr double VERTEX_OFFSET_FROM_ORIGIN = 0.6072;
508 polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
509 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
510 << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
511 << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
512 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
513 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
514 << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
515 << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
516 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
521 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 0 ) ) );
525 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 1 ) ) );
529 polygon << QPointF( -1, -1 ) << QPointF( 1, 1 ) << QPointF( -1, 1 ) << QPointF( -1, -1 );
533 polygon << QPointF( 0.5, -0.5 )
535 << QPointF( -1, 0.5 )
536 << QPointF( -0.5, -0.5 )
537 << QPointF( 0.5, -0.5 );
541 polygon << QPointF( 0.5, 0.5 )
542 << QPointF( 1, -0.5 )
543 << QPointF( -0.5, -0.5 )
544 << QPointF( -1, 0.5 )
545 << QPointF( 0.5, 0.5 );
549 polygon << QPointF( 1, 0.5 )
550 << QPointF( 0.5, -0.5 )
551 << QPointF( -1, -0.5 )
552 << QPointF( -0.5, 0.5 )
553 << QPointF( 1, 0.5 );
557 polygon << QPointF( -1, 0 ) << QPointF( 0, 1 )
558 << QPointF( 1, 0 ) << QPointF( 0, -1 ) << QPointF( -1, 0 );
562 polygon << QPointF( 1, 0.5 )
565 << QPointF( -1, 0.5 )
567 << QPointF( 1, 0.5 );
577 polygon << QPointF( -0.9511, -0.3090 )
578 << QPointF( -0.5878, 0.8090 )
579 << QPointF( 0.5878, 0.8090 )
580 << QPointF( 0.9511, -0.3090 )
582 << QPointF( -0.9511, -0.3090 );
593 polygon << QPointF( -0.8660, -0.5 )
594 << QPointF( -0.8660, 0.5 )
596 << QPointF( 0.8660, 0.5 )
597 << QPointF( 0.8660, -0.5 )
599 << QPointF( -0.8660, -0.5 );
604 static constexpr double VERTEX_OFFSET_FROM_ORIGIN = 1.0 / ( 1 + M_SQRT2 );
606 polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
607 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
608 << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
609 << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
610 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
611 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
612 << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
613 << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
614 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
621 polygon << QPointF( 0.587785252, 0.809016994 )
622 << QPointF( 0.951056516, 0.309016994 )
623 << QPointF( 0.951056516, -0.309016994 )
624 << QPointF( 0.587785252, -0.809016994 )
626 << QPointF( -0.587785252, -0.809016994 )
627 << QPointF( -0.951056516, -0.309016994 )
628 << QPointF( -0.951056516, 0.309016994 )
629 << QPointF( -0.587785252, 0.809016994 )
631 << QPointF( 0.587785252, 0.809016994 );
636 polygon << QPointF( -1, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
644 polygon << QPointF( -0.8660, 0.5 )
645 << QPointF( 0.8660, 0.5 )
647 << QPointF( -0.8660, 0.5 );
651 polygon << QPointF( 0, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( 0, 1 );
655 polygon << QPointF( -1, 1 ) << QPointF( 0, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
660 const double inner_r = std::cos(
DEG2RAD( 72.0 ) ) / std::cos(
DEG2RAD( 36.0 ) );
662 polygon << QPointF( inner_r * std::sin(
DEG2RAD( 315.0 ) ), - inner_r * std::cos(
DEG2RAD( 315.0 ) ) )
663 << QPointF( std::sin(
DEG2RAD( 270 ) ), - std::cos(
DEG2RAD( 270 ) ) )
664 << QPointF( inner_r * std::sin(
DEG2RAD( 225.0 ) ), - inner_r * std::cos(
DEG2RAD( 225.0 ) ) )
665 << QPointF( std::sin(
DEG2RAD( 180 ) ), - std::cos(
DEG2RAD( 180 ) ) )
666 << QPointF( inner_r * std::sin(
DEG2RAD( 135.0 ) ), - inner_r * std::cos(
DEG2RAD( 135.0 ) ) )
667 << QPointF( std::sin(
DEG2RAD( 90 ) ), - std::cos(
DEG2RAD( 90 ) ) )
668 << QPointF( inner_r * std::sin(
DEG2RAD( 45.0 ) ), - inner_r * std::cos(
DEG2RAD( 45.0 ) ) )
669 << QPointF( std::sin(
DEG2RAD( 0 ) ), - std::cos(
DEG2RAD( 0 ) ) )
670 << QPointF( inner_r * std::sin(
DEG2RAD( 315.0 ) ), - inner_r * std::cos(
DEG2RAD( 315.0 ) ) );
676 const double inner_r = std::cos(
DEG2RAD( 72.0 ) ) / std::cos(
DEG2RAD( 36.0 ) );
678 polygon << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) )
679 << QPointF( std::sin(
DEG2RAD( 288.0 ) ), - std::cos(
DEG2RAD( 288 ) ) )
680 << QPointF( inner_r * std::sin(
DEG2RAD( 252.0 ) ), - inner_r * std::cos(
DEG2RAD( 252.0 ) ) )
681 << QPointF( std::sin(
DEG2RAD( 216.0 ) ), - std::cos(
DEG2RAD( 216.0 ) ) )
682 << QPointF( 0, inner_r )
683 << QPointF( std::sin(
DEG2RAD( 144.0 ) ), - std::cos(
DEG2RAD( 144.0 ) ) )
684 << QPointF( inner_r * std::sin(
DEG2RAD( 108.0 ) ), - inner_r * std::cos(
DEG2RAD( 108.0 ) ) )
685 << QPointF( std::sin(
DEG2RAD( 72.0 ) ), - std::cos(
DEG2RAD( 72.0 ) ) )
686 << QPointF( inner_r * std::sin(
DEG2RAD( 36.0 ) ), - inner_r * std::cos(
DEG2RAD( 36.0 ) ) )
688 << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) );
693 polygon << QPointF( 0, -1 )
694 << QPointF( 0.5, -0.5 )
695 << QPointF( 0.25, -0.5 )
696 << QPointF( 0.25, 1 )
697 << QPointF( -0.25, 1 )
698 << QPointF( -0.25, -0.5 )
699 << QPointF( -0.5, -0.5 )
704 polygon << QPointF( 0, 0 ) << QPointF( -1, 1 ) << QPointF( -1, -1 ) << QPointF( 0, 0 );
708 polygon << QPointF( -1, -0.2 )
709 << QPointF( -1, -0.2 )
710 << QPointF( -1, 0.2 )
711 << QPointF( -0.2, 0.2 )
712 << QPointF( -0.2, 1 )
714 << QPointF( 0.2, 0.2 )
716 << QPointF( 1, -0.2 )
717 << QPointF( 0.2, -0.2 )
718 << QPointF( 0.2, -1 )
719 << QPointF( -0.2, -1 )
720 << QPointF( -0.2, -0.2 )
721 << QPointF( -1, -0.2 );
726 static constexpr double THICKNESS = 0.3;
727 static constexpr double HALF_THICKNESS = THICKNESS / 2.0;
728 static constexpr double INTERSECTION_POINT = THICKNESS / M_SQRT2;
729 static constexpr double DIAGONAL1 = M_SQRT1_2 - INTERSECTION_POINT * 0.5;
730 static constexpr double DIAGONAL2 = M_SQRT1_2 + INTERSECTION_POINT * 0.5;
732 polygon << QPointF( -HALF_THICKNESS, -1 )
733 << QPointF( HALF_THICKNESS, -1 )
734 << QPointF( HALF_THICKNESS, -HALF_THICKNESS - INTERSECTION_POINT )
735 << QPointF( DIAGONAL1, -DIAGONAL2 )
736 << QPointF( DIAGONAL2, -DIAGONAL1 )
737 << QPointF( HALF_THICKNESS + INTERSECTION_POINT, -HALF_THICKNESS )
738 << QPointF( 1, -HALF_THICKNESS )
739 << QPointF( 1, HALF_THICKNESS )
740 << QPointF( HALF_THICKNESS + INTERSECTION_POINT, HALF_THICKNESS )
741 << QPointF( DIAGONAL2, DIAGONAL1 )
742 << QPointF( DIAGONAL1, DIAGONAL2 )
743 << QPointF( HALF_THICKNESS, HALF_THICKNESS + INTERSECTION_POINT )
744 << QPointF( HALF_THICKNESS, 1 )
745 << QPointF( -HALF_THICKNESS, 1 )
746 << QPointF( -HALF_THICKNESS, HALF_THICKNESS + INTERSECTION_POINT )
747 << QPointF( -DIAGONAL1, DIAGONAL2 )
748 << QPointF( -DIAGONAL2, DIAGONAL1 )
749 << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, HALF_THICKNESS )
750 << QPointF( -1, HALF_THICKNESS )
751 << QPointF( -1, -HALF_THICKNESS )
752 << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, -HALF_THICKNESS )
753 << QPointF( -DIAGONAL2, -DIAGONAL1 )
754 << QPointF( -DIAGONAL1, -DIAGONAL2 )
755 << QPointF( -HALF_THICKNESS, -HALF_THICKNESS - INTERSECTION_POINT )
756 << QPointF( -HALF_THICKNESS, -1 );
781 mPath = QPainterPath();
787 mPath.addEllipse( QRectF( -1, -1, 2, 2 ) );
791 mPath.moveTo( -1, -1 );
792 mPath.addRoundedRect( -1, -1, 2, 2, 0.25, 0.25 );
796 mPath.arcTo( -1, -1, 2, 2, 0, 180 );
797 mPath.lineTo( 0, 0 );
801 mPath.arcTo( -1, -1, 2, 2, 90, 120 );
802 mPath.lineTo( 0, 0 );
806 mPath.arcTo( -1, -1, 2, 2, 90, 90 );
807 mPath.lineTo( 0, 0 );
811 mPath.moveTo( 1, 0 );
812 mPath.arcTo( -1, -1, 2, 2, 0, 180 );
816 mPath.moveTo( 0, -1 );
817 mPath.arcTo( -1, -1, 2, 2, 90, 120 );
821 mPath.moveTo( 0, -1 );
822 mPath.arcTo( -1, -1, 2, 2, 90, 90 );
826 mPath.moveTo( -1, 0 );
827 mPath.lineTo( 1, 0 );
828 mPath.moveTo( 0, -1 );
829 mPath.lineTo( 0, 1 );
833 mPath.moveTo( -1, -1 );
834 mPath.lineTo( 1, 1 );
835 mPath.moveTo( 1, -1 );
836 mPath.lineTo( -1, 1 );
840 mPath.moveTo( 0, -1 );
841 mPath.lineTo( 0, 1 );
845 mPath.moveTo( -1, -1 );
846 mPath.lineTo( 0, 0 );
847 mPath.lineTo( -1, 1 );
851 mPath.moveTo( 0, 0.75 );
852 mPath.arcTo( 0, -1, 1, 1, -45, 210 );
853 mPath.arcTo( -1, -1, 1, 1, 15, 210 );
854 mPath.lineTo( 0, 0.75 );
888 double scaledSize =
mSize;
892 if ( hasDataDefinedSize )
899 if ( hasDataDefinedSize && ok )
904 scaledSize = std::sqrt( scaledSize );
919 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
920 offset = QPointF( offsetX, offsetY );
922 hasDataDefinedRotation =
false;
935 hasDataDefinedRotation =
true;
940 if ( hasDataDefinedRotation )
969 , mStrokeColor( strokeColor )
970 , mPenJoinStyle( penJoinStyle )
987 if ( props.contains( QStringLiteral(
"name" ) ) )
991 if ( props.contains( QStringLiteral(
"color" ) ) )
993 if ( props.contains( QStringLiteral(
"color_border" ) ) )
998 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
1002 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
1006 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
1010 if ( props.contains( QStringLiteral(
"size" ) ) )
1011 size = props[QStringLiteral(
"size" )].toDouble();
1012 if ( props.contains( QStringLiteral(
"angle" ) ) )
1013 angle = props[QStringLiteral(
"angle" )].toDouble();
1014 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1018 if ( props.contains( QStringLiteral(
"offset" ) ) )
1020 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1022 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1024 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1026 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1029 if ( props.contains( QStringLiteral(
"outline_style" ) ) )
1033 else if ( props.contains( QStringLiteral(
"line_style" ) ) )
1037 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
1039 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
1041 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
1043 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
1045 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
1049 if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
1053 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
1058 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1062 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1067 if ( props.contains( QStringLiteral(
"cap_style" ) ) )
1080 return QStringLiteral(
"SimpleMarker" );
1092 QColor brushColor =
mColor;
1095 brushColor.setAlphaF(
mColor.alphaF() * context.
opacity() );
1098 mBrush = QBrush( brushColor );
1099 mPen = QPen( penColor );
1109 selBrushColor.setAlphaF( context.
opacity() );
1110 selPenColor.setAlphaF( context.
opacity() );
1113 mSelPen = QPen( selPenColor );
1129 mCachedOpacity = context.
opacity();
1135 mSelPen.setColor( selBrushColor );
1168 scaledSize = ( std::abs( std::sin(
mAngle * M_PI / 180 ) ) + std::abs( std::cos(
mAngle * M_PI / 180 ) ) ) * scaledSize;
1171 const double pw =
static_cast< int >( std::round( ( (
qgsDoubleNear(
mPen.widthF(), 0.0 ) ? 1 :
mPen.widthF() * 4 ) + 1 ) ) ) / 2 * 2;
1172 const int imageSize = (
static_cast< int >( scaledSize ) + pw ) / 2 * 2 + 1;
1173 const double center = imageSize / 2.0;
1179 mCache = QImage( QSize( imageSize * deviceRatio,
1180 imageSize * deviceRatio ), QImage::Format_ARGB32_Premultiplied );
1190 p.setRenderHint( QPainter::Antialiasing );
1191 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
1193 p.translate( QPointF( center, center ) );
1201 mSelCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
1205 p.setRenderHint( QPainter::Antialiasing );
1206 p.setBrush( needsBrush ?
mSelBrush : Qt::NoBrush );
1208 p.translate( QPointF( center, center ) );
1219 p.setRenderHint( QPainter::Antialiasing );
1220 p.fillRect( 0, 0, imageSize, imageSize, selColor );
1221 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
1223 p.translate( QPointF( center, center ) );
1242 QColor brushColor =
mColor;
1243 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
1244 mBrush.setColor( brushColor );
1247 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
1248 mPen.setColor( penColor );
1257 c.setAlphaF(
c.alphaF() * context.
opacity() );
1267 c.setAlphaF(
c.alphaF() * context.
opacity() );
1320 p->setBrush( Qt::NoBrush );
1324 if ( !polygon.isEmpty() )
1325 p->drawPolygon( polygon );
1327 p->drawPath( path );
1345 const double s = img.width() / img.devicePixelRatioF();
1347 bool hasDataDefinedSize =
false;
1348 const double scaledSize =
calculateSize( context, hasDataDefinedSize );
1350 bool hasDataDefinedRotation =
false;
1355 p->drawImage( QRectF( point.x() - s / 2.0 +
offset.x(),
1356 point.y() - s / 2.0 +
offset.y(),
1371 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1374 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1380 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
1385 map[QStringLiteral(
"horizontal_anchor_point" )] = QString::number(
static_cast< int >(
mHorizontalAnchorPoint ) );
1386 map[QStringLiteral(
"vertical_anchor_point" )] = QString::number(
static_cast< int >(
mVerticalAnchorPoint ) );
1414 toSld( doc, element, context );
1432 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
1433 element.appendChild( graphicElem );
1450 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
1453 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
1471 Q_UNUSED( mmScaleFactor )
1472 Q_UNUSED( mapUnitScaleFactor )
1474 QString ogrType =
"3";
1475 if ( mName ==
"square" )
1479 else if ( mName ==
"triangle" )
1483 else if ( mName ==
"star" )
1487 else if ( mName ==
"circle" )
1491 else if ( mName ==
"cross" )
1495 else if ( mName ==
"x" || mName ==
"cross2" )
1499 else if ( mName ==
"line" )
1505 ogrString.append(
"SYMBOL(" );
1506 ogrString.append(
"id:" );
1507 ogrString.append(
'\"' );
1508 ogrString.append(
"ogr-sym-" );
1509 ogrString.append( ogrType );
1510 ogrString.append(
'\"' );
1511 ogrString.append(
",c:" );
1512 ogrString.append(
mColor.name() );
1513 ogrString.append(
",o:" );
1515 ogrString.append( QString(
",s:%1mm" ).arg(
mSize ) );
1516 ogrString.append(
')' );
1521 ogrString.append(
"PEN(" );
1522 ogrString.append(
"c:" );
1523 ogrString.append(
mColor.name() );
1524 ogrString.append(
",w:" );
1525 ogrString.append( QString::number(
mSize ) );
1526 ogrString.append(
"mm" );
1527 ogrString.append(
")" );
1535 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1536 if ( graphicElem.isNull() )
1539 QString name = QStringLiteral(
"square" );
1552 const double d = angleFunc.toDouble( &ok );
1562 double scaleFactor = 1.0;
1563 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
1590 p->drawPath(
mPath );
1603 if ( hasDataDefinedSize )
1622 size *= mmMapUnitScaleFactor;
1629 const double halfSize =
size / 2.0;
1646 QColor pc =
mPen.color();
1647 QColor bc =
mBrush.color();
1667 QPointF off( offsetX, offsetY );
1696 t.translate( shift.x() + off.x(), shift.y() - off.y() );
1704 t.scale( halfSize, -halfSize );
1706 polygon = t.map( polygon );
1709 p.reserve( polygon.size() );
1710 for (
int i = 0; i < polygon.size(); i++ )
1715 if (
mBrush.style() != Qt::NoBrush )
1717 if (
mPen.style() != Qt::NoPen )
1722 shift += QPointF( off.x(), -off.y() );
1723 if (
mBrush.style() != Qt::NoBrush )
1725 if (
mPen.style() != Qt::NoPen )
1730 const QPointF pt1 = t.map( QPointF( 0, -halfSize ) );
1731 const QPointF pt2 = t.map( QPointF( 0, halfSize ) );
1733 if (
mPen.style() != Qt::NoPen )
1738 if (
mPen.style() != Qt::NoPen )
1740 const QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
1741 const QPointF pt2 = t.map( QPointF( halfSize, 0 ) );
1742 const QPointF pt3 = t.map( QPointF( 0, -halfSize ) );
1743 const QPointF pt4 = t.map( QPointF( 0, halfSize ) );
1751 if (
mPen.style() != Qt::NoPen )
1753 const QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
1754 const QPointF pt2 = t.map( QPointF( halfSize, halfSize ) );
1755 const QPointF pt3 = t.map( QPointF( halfSize, -halfSize ) );
1756 const QPointF pt4 = t.map( QPointF( -halfSize, halfSize ) );
1764 if (
mPen.style() != Qt::NoPen )
1766 const QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
1767 const QPointF pt2 = t.map( QPointF( 0, 0 ) );
1768 const QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
1854 symbolBounds.adjust( -penWidth / 2.0, -penWidth / 2.0,
1855 penWidth / 2.0, penWidth / 2.0 );
1857 return symbolBounds;
1906 if ( props.contains( QStringLiteral(
"name" ) ) )
1907 name = props[QStringLiteral(
"name" )].toString();
1908 if ( props.contains( QStringLiteral(
"size" ) ) )
1909 size = props[QStringLiteral(
"size" )].toDouble();
1910 if ( props.contains( QStringLiteral(
"angle" ) ) )
1911 angle = props[QStringLiteral(
"angle" )].toDouble();
1912 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1916 if ( props.contains( QStringLiteral(
"offset" ) ) )
1918 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1920 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1922 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1924 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1926 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1930 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1944 return QStringLiteral(
"FilledMarker" );
1984 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1987 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1992 map[QStringLiteral(
"horizontal_anchor_point" )] = QString::number(
static_cast< int >(
mHorizontalAnchorPoint ) );
1993 map[QStringLiteral(
"vertical_anchor_point" )] = QString::number(
static_cast< int >(
mVerticalAnchorPoint ) );
2043 attr.unite( mFill->usedAttributes( context ) );
2051 if ( mFill && mFill->hasDataDefinedProperties() )
2060 mFill->setColor(
c );
2065 return mFill ? mFill->color() :
mColor;
2072 || ( mFill && mFill->usesMapUnits() );
2079 mFill->setOutputUnit( unit );
2093 const double prevOpacity = mFill->opacity();
2094 mFill->setOpacity( mFill->opacity() * context.
opacity() );
2098 p->setBrush( Qt::red );
2102 p->setBrush( Qt::NoBrush );
2104 p->setPen( Qt::black );
2110 if ( !polygon.isEmpty() )
2112 mFill->renderPolygon( polygon,
nullptr, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2116 const QPolygonF poly = path.toFillPolygon();
2117 mFill->renderPolygon( poly,
nullptr, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2122 mFill->setOpacity( prevOpacity );
2137 mColor = QColor( 35, 35, 35 );
2144 , mPath( other.mPath )
2145 , mDefaultAspectRatio( other.mDefaultAspectRatio )
2146 , mFixedAspectRatio( other.mFixedAspectRatio )
2147 , mHasFillParam( other.mHasFillParam )
2148 , mStrokeColor( other.mStrokeColor )
2149 , mStrokeWidth( other.mStrokeWidth )
2150 , mParameters( other.mParameters )
2151 , mStrokeWidthUnit( other.mStrokeWidthUnit )
2152 , mStrokeWidthMapUnitScale( other.mStrokeWidthMapUnitScale )
2165 if ( props.contains( QStringLiteral(
"name" ) ) )
2166 name = props[QStringLiteral(
"name" )].toString();
2167 if ( props.contains( QStringLiteral(
"size" ) ) )
2168 size = props[QStringLiteral(
"size" )].toDouble();
2169 if ( props.contains( QStringLiteral(
"angle" ) ) )
2170 angle = props[QStringLiteral(
"angle" )].toDouble();
2171 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
2176 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
2178 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
2180 if ( props.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
2182 if ( props.contains( QStringLiteral(
"offset" ) ) )
2184 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
2186 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2188 if ( props.contains( QStringLiteral(
"fill" ) ) )
2193 else if ( props.contains( QStringLiteral(
"color" ) ) )
2197 if ( props.contains( QStringLiteral(
"outline" ) ) )
2202 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
2206 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
2211 if ( props.contains( QStringLiteral(
"outline-width" ) ) )
2214 m->
setStrokeWidth( props[QStringLiteral(
"outline-width" )].toDouble() );
2216 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
2218 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
2220 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
2222 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
2225 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
2229 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
2233 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2236 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
2240 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
2249 if ( props.contains( QStringLiteral(
"parameters" ) ) )
2251 const QVariantMap
parameters = props[QStringLiteral(
"parameters" )].toMap();
2260 const QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
2279 QColor defaultFillColor, defaultStrokeColor;
2281 bool hasFillOpacityParam =
false, hasStrokeParam =
false, hasStrokeWidthParam =
false, hasStrokeOpacityParam =
false;
2282 bool hasDefaultFillColor =
false, hasDefaultFillOpacity =
false, hasDefaultStrokeColor =
false, hasDefaultStrokeWidth =
false, hasDefaultStrokeOpacity =
false;
2284 hasFillOpacityParam, hasDefaultFillOpacity, fillOpacity,
2285 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2286 hasStrokeWidthParam, hasDefaultStrokeWidth,
strokeWidth,
2287 hasStrokeOpacityParam, hasDefaultStrokeOpacity, strokeOpacity );
2289 const double newFillOpacity = hasFillOpacityParam ?
fillColor().alphaF() : 1.0;
2290 const double newStrokeOpacity = hasStrokeOpacityParam ?
strokeColor().alphaF() : 1.0;
2292 if ( hasDefaultFillColor )
2294 defaultFillColor.setAlphaF( newFillOpacity );
2297 if ( hasDefaultFillOpacity )
2300 c.setAlphaF( fillOpacity );
2303 if ( hasDefaultStrokeColor )
2305 defaultStrokeColor.setAlphaF( newStrokeOpacity );
2308 if ( hasDefaultStrokeWidth )
2312 if ( hasDefaultStrokeOpacity )
2315 c.setAlphaF( strokeOpacity );
2329 const double widthScaleFactor = 3.465;
2332 mDefaultAspectRatio = svgViewbox.isValid() ? svgViewbox.height() / svgViewbox.width() : 0.0;
2340 if ( aPreservedAspectRatio && !par )
2344 else if ( !aPreservedAspectRatio && par )
2359 return QStringLiteral(
"SvgMarker" );
2384 bool hasDataDefinedSize =
false;
2385 const double scaledWidth = calculateSize( context, hasDataDefinedSize );
2390 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
2397 bool hasDataDefinedAspectRatio =
false;
2398 const double aspectRatio =
calculateAspectRatio( context, scaledWidth, hasDataDefinedAspectRatio );
2442 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
2446 QPointF outputOffset;
2448 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
2450 p->translate( point + outputOffset );
2456 bool fitsInCache =
true;
2457 bool usePict =
true;
2459 if ( ( !context.
forceVectorRendering() && !rotated ) || ( useSelectedColor && rasterizeSelected ) )
2464 if ( fitsInCache && img.width() > 1 )
2468 if ( useSelectedColor )
2476 QImage transparentImage = img.copy();
2478 if ( devicePixelRatio == 1 )
2480 p->drawImage( -transparentImage.width() / 2.0, -transparentImage.height() / 2.0, transparentImage );
2484 p->drawImage( QRectF( -transparentImage.width() / 2.0 / devicePixelRatio, -transparentImage.height() / 2.0 / devicePixelRatio,
2485 transparentImage.width() / devicePixelRatio, transparentImage.height() / devicePixelRatio
2486 ), transparentImage );
2491 if ( devicePixelRatio == 1 )
2493 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
2497 p->drawImage( QRectF( -img.width() / 2.0 / devicePixelRatio, -img.height() / 2.0 / devicePixelRatio,
2498 img.width() / devicePixelRatio, img.height() / devicePixelRatio ), img );
2504 if ( usePict || !fitsInCache )
2506 p->setOpacity( context.
opacity() );
2510 if ( pct.width() > 1 )
2520double QgsSvgMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
2522 double scaledSize =
mSize;
2526 if ( hasDataDefinedSize )
2534 if ( hasDataDefinedSize )
2541 if ( hasDataDefinedSize && ok )
2546 scaledSize = std::sqrt( scaledSize );
2559 if ( !hasDataDefinedAspectRatio )
2569 const double defaultHeight =
mSize * scaledAspectRatio;
2570 scaledAspectRatio = defaultHeight / scaledSize;
2573 double scaledHeight = scaledSize * scaledAspectRatio;
2580 if ( hasDataDefinedAspectRatio && ok )
2585 scaledHeight = sqrt( scaledHeight );
2592 scaledAspectRatio = scaledHeight / scaledSize;
2594 return scaledAspectRatio;
2597void QgsSvgMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &angle )
const
2602 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
2603 offset = QPointF( offsetX, offsetY );
2613 if ( hasDataDefinedRotation )
2639 map[QStringLiteral(
"name" )] =
mPath;
2640 map[QStringLiteral(
"size" )] = QString::number(
mSize );
2643 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
2644 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2651 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
2654 map[QStringLiteral(
"horizontal_anchor_point" )] = QString::number(
static_cast< int >(
mHorizontalAnchorPoint ) );
2655 map[QStringLiteral(
"vertical_anchor_point" )] = QString::number(
static_cast< int >(
mVerticalAnchorPoint ) );
2678 toSld( doc, element, context );
2727 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2728 element.appendChild( graphicElem );
2739 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2742 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
2761 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
2762 if ( graphicElem.isNull() )
2765 QString
path, mimeType;
2773 double scaleFactor = 1.0;
2774 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
2778 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2786 const double d = angleFunc.toDouble( &ok );
2795 QString realPath {
path };
2796 QUrl svgUrl {
path };
2799 QUrlQuery queryString;
2801 if ( svgUrl.hasQuery() && svgUrl.hasFragment() )
2803 const QString queryPart {
path.mid(
path.indexOf(
'?' ) + 1 ) };
2804 queryString.setQuery( queryPart );
2808 if ( svgUrl.scheme().isEmpty() || svgUrl.isLocalFile() )
2810 svgUrl.setQuery( QString() );
2811 realPath = svgUrl.path();
2816 QMap<QString, QgsProperty> params;
2820 if ( queryString.hasQueryItem( QStringLiteral(
"fill" ) ) )
2822 const QColor
fillColor { queryString.queryItemValue( QStringLiteral(
"fill" ) ) };
2826 if ( queryString.hasQueryItem( QStringLiteral(
"fill-opacity" ) ) )
2828 const double alpha { queryString.queryItemValue( QStringLiteral(
"fill-opacity" ) ).toDouble( &ok ) };
2835 if ( queryString.hasQueryItem( QStringLiteral(
"outline" ) ) )
2837 const QColor
strokeColor { queryString.queryItemValue( QStringLiteral(
"outline" ) ) };
2841 if ( queryString.hasQueryItem( QStringLiteral(
"outline-opacity" ) ) )
2843 const double alpha { queryString.queryItemValue( QStringLiteral(
"outline-opacity" ) ).toDouble( &ok ) };
2850 if ( queryString.hasQueryItem( QStringLiteral(
"outline-width" ) ) )
2852 const int width { queryString.queryItemValue( QStringLiteral(
"outline-width" ) ).toInt( &ok )};
2859 if ( ! params.isEmpty() )
2878 if ( hasDataDefinedSize )
2884 if ( hasDataDefinedSize && ok )
2898 size *= mmMapUnitScaleFactor;
2912 const double offsetX =
offset.x();
2913 const double offsetY =
offset.y();
2915 QPointF outputOffset( offsetX, offsetY );
2965 QSvgRenderer r( svgContent );
2972 QSizeF outSize( r.defaultSize() );
2973 outSize.scale(
size,
size, Qt::KeepAspectRatio );
2979 p.translate( r.defaultSize().width() / 2.0, r.defaultSize().height() / 2.0 );
2981 p.translate( -r.defaultSize().width() / 2.0, -r.defaultSize().height() / 2.0 );
2983 pd.
setShift( shift + QPointF( outputOffset.x(), -outputOffset.y() ) );
2984 pd.
setOutputSize( QRectF( -outSize.width() / 2.0, -outSize.height() / 2.0, outSize.width(), outSize.height() ) );
2993 bool hasDataDefinedSize =
false;
2994 double scaledWidth = calculateSize( context, hasDataDefinedSize );
2996 bool hasDataDefinedAspectRatio =
false;
2997 const double aspectRatio =
calculateAspectRatio( context, scaledWidth, hasDataDefinedAspectRatio );
3004 if (
static_cast< int >( scaledWidth ) < 1 || 10000.0 < scaledWidth )
3009 QPointF outputOffset;
3011 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
3050 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
3054 QTransform transform;
3056 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
3059 transform.rotate(
angle );
3064 QRectF symbolBounds = transform.mapRect( QRectF( -scaledWidth / 2.0,
3065 -scaledHeight / 2.0,
3073 return symbolBounds;
3097 if ( props.contains( QStringLiteral(
"imageFile" ) ) )
3098 path = props[QStringLiteral(
"imageFile" )].toString();
3099 if ( props.contains( QStringLiteral(
"size" ) ) )
3100 size = props[QStringLiteral(
"size" )].toDouble();
3101 if ( props.contains( QStringLiteral(
"angle" ) ) )
3102 angle = props[QStringLiteral(
"angle" )].toDouble();
3103 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
3107 m->setCommonProperties( props );
3113 const QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
3114 if ( graphicElem.isNull() )
3117 const QDomElement externalGraphicElem = graphicElem.firstChildElement( QStringLiteral(
"ExternalGraphic" ) );
3118 if ( externalGraphicElem.isNull() )
3121 const QDomElement onlineResourceElem = externalGraphicElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
3122 const QDomElement inlineContentElem = externalGraphicElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
3125 if ( !onlineResourceElem.isNull() )
3127 url = onlineResourceElem.attribute( QStringLiteral(
"href" ) );
3130 else if ( !inlineContentElem.isNull() && inlineContentElem.attribute( QStringLiteral(
"encoding" ) ) == QLatin1String(
"base64" ) )
3132 url = QStringLiteral(
"base64:" ) + inlineContentElem.text();
3146 if (
properties.contains( QStringLiteral(
"alpha" ) ) )
3151 if (
properties.contains( QStringLiteral(
"size_unit" ) ) )
3153 if (
properties.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
3155 if (
properties.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
3158 if (
properties.contains( QStringLiteral(
"offset" ) ) )
3160 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
3162 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
3165 if (
properties.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
3169 if (
properties.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
3180 const QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
3181 if ( it !=
properties.end() && it.value().userType() == QMetaType::Type::QString )
3199 if ( aPreservedAspectRatio && !par )
3203 else if ( !aPreservedAspectRatio && par )
3222 return QStringLiteral(
"RasterMarker" );
3243 if (
path.isEmpty() )
3247 double height = 0.0;
3249 bool hasDataDefinedSize =
false;
3250 const double scaledSize = calculateSize( context, hasDataDefinedSize );
3252 bool hasDataDefinedAspectRatio =
false;
3253 const double aspectRatio =
calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
3255 QPointF outputOffset;
3262 if (
size.isEmpty() )
3265 width = ( scaledSize *
static_cast< double >(
size.width() ) ) / 100.0;
3266 height = ( scaledSize *
static_cast< double >(
size.height() ) ) / 100.0;
3269 if (
static_cast< int >( width ) < 1 || 10000.0 < width ||
static_cast< int >( height ) < 1 || 10000.0 < height )
3272 calculateOffsetAndRotation( context, width, height, outputOffset,
angle );
3282 if ( !
size.isNull() &&
size.isValid() &&
size.width() > 0 )
3284 height = width * (
static_cast< double >(
size.height() ) /
static_cast< double >(
size.width() ) );
3289 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
3292 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
3296 p->translate( point + outputOffset );
3311 if ( !img.isNull() )
3314 if ( useSelectedColor )
3319 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
3325 bool cached =
false;
3329double QgsRasterMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
3331 double scaledSize =
mSize;
3335 if ( hasDataDefinedSize )
3343 if ( hasDataDefinedSize )
3350 if ( hasDataDefinedSize && ok )
3355 scaledSize = std::sqrt( scaledSize );
3368 if ( !hasDataDefinedAspectRatio )
3378 const double defaultHeight =
mSize * scaledAspectRatio;
3379 scaledAspectRatio = defaultHeight / scaledSize;
3382 double scaledHeight = scaledSize * scaledAspectRatio;
3389 if ( hasDataDefinedAspectRatio && ok )
3394 scaledHeight = sqrt( scaledHeight );
3401 scaledAspectRatio = scaledHeight / scaledSize;
3403 return scaledAspectRatio;
3406void QgsRasterMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &angle )
const
3411 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
3412 offset = QPointF( offsetX, offsetY );
3422 if ( hasDataDefinedRotation )
3443 map[QStringLiteral(
"imageFile" )] =
mPath;
3444 map[QStringLiteral(
"size" )] = QString::number(
mSize );
3447 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
3448 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
3449 map[QStringLiteral(
"alpha" )] = QString::number(
mOpacity );
3454 map[QStringLiteral(
"horizontal_anchor_point" )] = QString::number(
static_cast< int >(
mHorizontalAnchorPoint ) );
3455 map[QStringLiteral(
"vertical_anchor_point" )] = QString::number(
static_cast< int >(
mVerticalAnchorPoint ) );
3461 auto m = std::make_unique< QgsRasterMarkerSymbolLayer >();
3510 bool hasDataDefinedSize =
false;
3511 const double scaledSize = calculateSize( context, hasDataDefinedSize );
3513 bool hasDataDefinedAspectRatio =
false;
3514 const double aspectRatio =
calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
3518 if (
static_cast< int >( scaledSize ) < 1 || 10000.0 < scaledSize )
3523 QPointF outputOffset;
3525 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
3527 QTransform transform;
3530 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
3533 transform.rotate(
angle );
3535 QRectF symbolBounds = transform.mapRect( QRectF( -width / 2.0,
3540 return symbolBounds;
3555 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
3556 element.appendChild( graphicElem );
3559 QDomElement extGraphElem = doc.createElement( QStringLiteral(
"se:ExternalGraphic" ) );
3560 graphicElem.appendChild( extGraphElem );
3562 QMimeDatabase mimeDB;
3566 if (
mPath.startsWith( QStringLiteral(
"base64:" ) ) )
3568 base64data =
mPath.mid( 7 );
3580 if ( !base64data.isEmpty() )
3583 QDomElement inlineContEleme = doc.createElement( QStringLiteral(
"se:InlineContent" ) );
3585 inlineContEleme.setAttribute( QStringLiteral(
"encoding" ), QStringLiteral(
"base64" ) );
3586 inlineContEleme.appendChild( doc.createTextNode( base64data ) );
3587 extGraphElem.appendChild( inlineContEleme );
3590 const QByteArray ba = QByteArray::fromBase64( base64data.toUtf8() );
3591 mimeType = mimeDB.mimeTypeForData( ba );
3596 QDomElement onlineResElem = doc.createElement( QStringLiteral(
"se:OnlineResource" ) );
3597 QString url =
mPath;
3599 onlineResElem.setAttribute( QStringLiteral(
"xlink:href" ), url );
3600 onlineResElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
3601 extGraphElem.appendChild( onlineResElem );
3604 if (
mPath.startsWith( QStringLiteral(
"http://" ) ) ||
mPath.startsWith( QStringLiteral(
"https://" ) ) )
3608 mimeType = mimeDB.mimeTypeForName(
"image/png" );
3612 mimeType = mimeDB.mimeTypeForUrl( url );
3616 QDomElement formatElem = doc.createElement( QStringLiteral(
"se:Format" ) );
3617 formatElem.appendChild( doc.createTextNode( mimeType.name() ) );
3618 extGraphElem.appendChild( formatElem );
3633 mOrigSize = pointSize;
3653 if ( props.contains( QStringLiteral(
"font" ) ) )
3654 fontFamily = props[QStringLiteral(
"font" )].toString();
3655 if ( props.contains( QStringLiteral(
"chr" ) ) && props[QStringLiteral(
"chr" )].toString().length() > 0 )
3657 string = props[
"chr"].toString();
3658 const thread_local QRegularExpression charRegExp( QStringLiteral(
"%1([0-9]+)%1" ).arg(
FONTMARKER_CHR_FIX ) );
3659 QRegularExpressionMatch match = charRegExp.match(
string );
3660 while ( match.hasMatch() )
3662 QChar replacement = QChar( match.captured( 1 ).toUShort() );
3663 string =
string.mid( 0, match.capturedStart( 0 ) ) + replacement +
string.mid( match.capturedEnd( 0 ) );
3664 match = charRegExp.match(
string );
3668 if ( props.contains( QStringLiteral(
"size" ) ) )
3669 pointSize = props[QStringLiteral(
"size" )].toDouble();
3670 if ( props.contains( QStringLiteral(
"color" ) ) )
3672 if ( props.contains( QStringLiteral(
"angle" ) ) )
3673 angle = props[QStringLiteral(
"angle" )].toDouble();
3677 if ( props.contains( QStringLiteral(
"font_style" ) ) )
3678 m->
setFontStyle( props[QStringLiteral(
"font_style" )].toString() );
3679 if ( props.contains( QStringLiteral(
"outline_color" ) ) )
3681 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
3682 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
3683 if ( props.contains( QStringLiteral(
"offset" ) ) )
3685 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
3687 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
3689 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
3691 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
3693 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
3695 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
3697 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
3699 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
3701 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
3711 return QStringLiteral(
"FontMarker" );
3721 QColor brushColor =
mColor;
3722 QColor penColor = mStrokeColor;
3724 brushColor.setAlphaF(
mColor.alphaF() * context.
opacity() );
3725 penColor.setAlphaF( mStrokeColor.alphaF() * context.
opacity() );
3727 mBrush = QBrush( brushColor );
3728 mPen = QPen( penColor );
3729 mPen.setJoinStyle( mPenJoinStyle );
3733 if ( !mFontStyle.isEmpty() )
3741 if ( mNonZeroFontSize && sizePixels > MAX_FONT_CHARACTER_SIZE_IN_PIXELS )
3746 mFontSizeScale = sizePixels / MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
3747 sizePixels = MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
3750 mFontSizeScale = 1.0;
3754 mFont.setPixelSize( std::max( 2,
static_cast< int >( std::round( sizePixels ) ) ) );
3755 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3756 mChrWidth = mFontMetrics->horizontalAdvance( mString );
3761 mChrOffset = QPointF( mChrWidth / 2.0, -sizePixels / 2.0 );
3768 mChrOffset = QPointF( mChrWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3778 if ( mUseCachedPath )
3780 QPointF chrOffset = mChrOffset;
3782 const QString charToRender = characterToRender( context, chrOffset, chrWidth );
3783 mCachedPath = QPainterPath();
3784 mCachedPath.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
3793QString QgsFontMarkerSymbolLayer::characterToRender(
QgsSymbolRenderContext &context, QPointF &charOffset,
double &charWidth )
3795 charOffset = mChrOffset;
3796 QString stringToRender = mString;
3801 if ( stringToRender != mString )
3803 charWidth = mFontMetrics->horizontalAdvance( stringToRender );
3809 charOffset = QPointF( charWidth / 2.0, -sizePixels / 2.0 );
3816 charOffset = QPointF( charWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3822 return stringToRender;
3827 bool &hasDataDefinedRotation,
3829 double &angle )
const
3834 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
3835 offset = QPointF( offsetX, offsetY );
3836 hasDataDefinedRotation =
false;
3850 hasDataDefinedRotation =
true;
3854 if ( hasDataDefinedRotation )
3878 double scaledSize =
mSize;
3882 if ( hasDataDefinedSize )
3888 if ( hasDataDefinedSize && ok )
3893 scaledSize = std::sqrt( scaledSize );
3905 if ( !p || !mNonZeroFontSize )
3908 QTransform transform;
3911 QColor brushColor =
mColor;
3921 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
3923 mBrush.setColor( brushColor );
3925 QColor penColor = mStrokeColor;
3931 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
3955 p->setBrush( mBrush );
3958 mPen.setColor( penColor );
3959 mPen.setWidthF( penWidth );
3964 p->setPen( Qt::NoPen );
3982 mFontMetrics.reset(
new QFontMetrics( mFont ) );
3985 QPointF chrOffset = mChrOffset;
3987 const QString charToRender = characterToRender( context, chrOffset, chrWidth );
3989 const double sizeToRender = calculateSize( context );
3991 bool hasDataDefinedRotation =
false;
3994 calculateOffsetAndRotation( context, sizeToRender, hasDataDefinedRotation,
offset,
angle );
3996 p->translate( point.x() +
offset.x(), point.y() +
offset.y() );
3999 transform.rotate(
angle );
4003 const double s = sizeToRender / mOrigSize;
4004 transform.scale( s, s );
4008 transform.scale( mFontSizeScale, mFontSizeScale );
4010 if ( mUseCachedPath )
4012 p->drawPath( transform.map( mCachedPath ) );
4017 path.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
4018 p->drawPath( transform.map( path ) );
4025 props[QStringLiteral(
"font" )] = mFontFamily;
4026 props[QStringLiteral(
"font_style" )] = mFontStyle;
4027 QString chr = mString;
4028 for (
int i = 0; i < 32; i++ )
4030 if ( i == 9 || i == 10 || i == 13 )
4034 chr.replace( QChar( i ), QStringLiteral(
"%1%2%1" ).arg(
FONTMARKER_CHR_FIX, QString::number( i ) ) );
4036 props[QStringLiteral(
"chr" )] = chr;
4037 props[QStringLiteral(
"size" )] = QString::number(
mSize );
4042 props[QStringLiteral(
"outline_width" )] = QString::number( mStrokeWidth );
4046 props[QStringLiteral(
"angle" )] = QString::number(
mAngle );
4050 props[QStringLiteral(
"horizontal_anchor_point" )] = QString::number(
static_cast< int >(
mHorizontalAnchorPoint ) );
4051 props[QStringLiteral(
"vertical_anchor_point" )] = QString::number(
static_cast< int >(
mVerticalAnchorPoint ) );
4080 toSld( doc, element, context );
4098 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
4099 element.appendChild( graphicElem );
4102 const QString fontPath = QStringLiteral(
"ttf://%1" ).arg( mFontFamily );
4103 int markIndex = !mString.isEmpty() ? mString.at( 0 ).unicode() : 0;
4110 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
4113 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
4137 mStrokeWidthUnit = unit;
4142 QPointF chrOffset = mChrOffset;
4143 double chrWidth = mChrWidth;
4145 ( void )characterToRender( context, chrOffset, chrWidth );
4147 if ( !mFontMetrics )
4148 mFontMetrics.reset(
new QFontMetrics( mFont ) );
4150 double scaledSize = calculateSize( context );
4153 chrWidth *= scaledSize / mOrigSize;
4155 chrWidth *= mFontSizeScale;
4157 bool hasDataDefinedRotation =
false;
4160 calculateOffsetAndRotation( context, scaledSize, hasDataDefinedRotation,
offset,
angle );
4163 QTransform transform;
4166 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
4169 transform.rotate(
angle );
4171 QRectF symbolBounds = transform.mapRect( QRectF( -chrWidth / 2.0,
4175 return symbolBounds;
4182 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
4183 if ( graphicElem.isNull() )
4186 QString name, format;
4194 if ( !name.startsWith( QLatin1String(
"ttf://" ) ) || format != QLatin1String(
"ttf" ) )
4204 const double d = angleFunc.toDouble( &ok );
4212 double scaleFactor = 1.0;
4213 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
4234 context.
pushMessage( QObject::tr(
"Font “%1” not available on system" ).arg( processedFamily ) );
4240 QMap<QString, QgsProperty>::iterator it =
mParameters.begin();
4252 QMap<QString, QgsProperty>::const_iterator it =
mParameters.constBegin();
4255 attrs.unite( it.value().referencedFields( context.
expressionContext(),
true ) );
4279 if (
properties.contains( QStringLiteral(
"imageFile" ) ) )
4281 if (
properties.contains( QStringLiteral(
"size" ) ) )
4283 if (
properties.contains( QStringLiteral(
"angle" ) ) )
4286 auto m = std::make_unique< QgsAnimatedMarkerSymbolLayer >(
path,
size,
angle );
4287 m->setFrameRate(
properties.value( QStringLiteral(
"frameRate" ), QStringLiteral(
"10" ) ).toDouble() );
4295 return QStringLiteral(
"AnimatedMarker" );
4301 res.insert( QStringLiteral(
"frameRate" ), mFrameRateFps );
4307 auto m = std::make_unique< QgsAnimatedMarkerSymbolLayer >(
mPath,
mSize,
mAngle );
4308 m->setFrameRate( mFrameRateFps );
4317 mPreparedPaths.clear();
4325 mStaticPath =
false;
4331 if ( !mStaticPath && !mPreparedPaths.contains(
path ) )
4334 mPreparedPaths.insert(
path );
4337 const long long mapFrameNumber = context.
currentFrame();
4339 const double markerAnimationDuration = totalFrameCount / mFrameRateFps;
4341 double animationTimeSeconds = 0;
4342 if ( mapFrameNumber >= 0 && context.
frameRate() > 0 )
4345 animationTimeSeconds = mapFrameNumber / context.
frameRate();
4350 animationTimeSeconds = QDateTime::currentMSecsSinceEpoch() / 1000.0;
4353 const double markerAnimationProgressSeconds = std::fmod( animationTimeSeconds, markerAnimationDuration );
4354 const int movieFrame =
static_cast< int >( std::floor( markerAnimationProgressSeconds * mFrameRateFps ) );
4356 bool cached =
false;
@ DynamicRotation
Rotation of symbol may be changed during rendering and symbol should not be cached.
@ IsSymbolLayerSubSymbol
Symbol is being rendered as a sub-symbol of a QgsSymbolLayer.
@ CanCalculateMaskGeometryPerFeature
If present, indicates that mask geometry can safely be calculated per feature for the symbol layer....
ScaleMethod
Scale methods.
@ ScaleDiameter
Calculate scale by the diameter.
@ ScaleArea
Calculate scale by the area.
QFlags< SymbolLayerFlag > SymbolLayerFlags
Symbol layer flags.
MarkerShape
Marker shapes.
@ EquilateralTriangle
Equilateral triangle.
@ SemiCircle
Semi circle (top half)
@ QuarterCircle
Quarter circle (top left quarter)
@ LeftHalfTriangle
Left half of triangle.
@ ArrowHead
Right facing arrow head (unfilled, lines only)
@ ParallelogramRight
Parallelogram that slants right.
@ AsteriskFill
A filled asterisk shape.
@ HalfArc
A line-only half arc.
@ QuarterSquare
Quarter square (top left quarter)
@ Cross2
Rotated cross (lines only), 'x' shape.
@ ArrowHeadFilled
Right facing filled arrow head.
@ Shield
A shape consisting of a triangle attached to a rectangle.
@ HalfSquare
Half square (left half)
@ CrossFill
Solid filled cross.
@ RoundedSquare
A square with rounded corners.
@ RightHalfTriangle
Right half of triangle.
@ ThirdCircle
One third circle (top left third)
@ ThirdArc
A line-only one third arc.
@ SquareWithCorners
A square with diagonal corners.
@ QuarterArc
A line-only one quarter arc.
@ DiamondStar
A 4-sided star.
@ Cross
Cross (lines only)
@ ParallelogramLeft
Parallelogram that slants left.
@ DiagonalHalfSquare
Diagonal half square (bottom left half)
VerticalAnchorPoint
Marker symbol vertical anchor points.
@ Bottom
Align to bottom of symbol.
@ Center
Align to vertical center of symbol.
@ Baseline
Align to baseline of symbol, e.g. font baseline for font marker symbol layers. Treated as Bottom if n...
@ Top
Align to top of symbol.
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,...
@ RenderLayerTree
The render is for a layer tree display where map based properties are not available and where avoidan...
@ RenderBlocking
Render and load remote sources in the same thread to ensure rendering remote sources (svg and images)...
HorizontalAnchorPoint
Marker symbol horizontal anchor points.
static bool parseBase64DataUrl(const QString &path, QString *mimeType=nullptr, QString *data=nullptr)
Parses a path to determine if it represents a base 64 encoded HTML data URL, and if so,...
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 std::unique_ptr< QgsFillSymbol > createSimple(const QVariantMap &properties)
Create a fill symbol with one symbol layer: SimpleFill with specified properties.
Filled marker symbol layer, consisting of a shape which is rendered using a QgsFillSymbol.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QColor color() const override
Returns the "representative" color of the symbol layer.
QgsFilledMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
~QgsFilledMarkerSymbolLayer() override
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void setColor(const QColor &c) override
Sets the "representative" color for the symbol layer.
QString layerType() const override
Returns a string that represents this layer type.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsFilledMarkerSymbolLayer.
QgsFilledMarkerSymbolLayer(Qgis::MarkerShape shape=Qgis::MarkerShape::Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructor for QgsFilledMarkerSymbolLayer.
QString processFontFamilyName(const QString &name) const
Processes a font family name, applying any matching fontFamilyReplacements() to the name.
A marker symbol layer which displays characters rendered using a font.
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.
Q_DECL_DEPRECATED void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
Q_DECL_DEPRECATED 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.
void setVerticalAnchorPoint(Qgis::VerticalAnchorPoint v)
Sets the vertical anchor point for positioning the symbol.
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)
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.
bool toSld(QDomDocument &doc, QDomElement &element, QgsSldExportContext &context) const override
Saves the symbol layer as SLD.
Qgis::RenderUnit outputUnit() const override
Returns the units to use for sizes and widths within the symbol layer.
QPointF mOffset
Marker offset.
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.
Qgis::VerticalAnchorPoint mVerticalAnchorPoint
Vertical anchor point.
static QPointF _rotatedOffset(QPointF offset, double angle)
Adjusts a marker offset to account for rotation.
void setHorizontalAnchorPoint(Qgis::HorizontalAnchorPoint h)
Sets the horizontal anchor point for positioning the symbol.
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.
void markerOffset(QgsSymbolRenderContext &context, double &offsetX, double &offsetY) const
Calculates the required marker offset, including both the symbol offset and any displacement required...
Qgis::HorizontalAnchorPoint mHorizontalAnchorPoint
Horizontal anchor point.
void setOffsetMapUnitScale(const QgsMapUnitScale &scale)
Sets the map unit scale for the symbol's offset.
double mAngle
Marker rotation angle, in degrees clockwise from north.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
double angle() const
Returns the rotation angle for the marker, in degrees clockwise from north.
void setMapUnitScale(const QgsMapUnitScale &scale) override
static void drawPicture(QPainter *painter, const QPointF &point, const QPicture &picture)
Draws a picture onto a painter, correctly applying workarounds to avoid issues with incorrect scaling...
Resolves relative paths into absolute paths and vice versa.
Point geometry type, with support for z-dimension and m-values.
QVariant value(int key, const QgsExpressionContext &context, const QVariant &defaultValue=QVariant()) const final
Returns the calculated value of the property with the specified key from within the collection.
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
QgsProperty property(int key) const final
Returns a matching property from the collection, if one exists.
QString asExpression() const
Returns an expression string representing the state of the property, or an empty string if the proper...
static QVariantMap propertyMapToVariantMap(const QMap< QString, QgsProperty > &propertyMap)
Convert a map of QgsProperty to a map of QVariant This is useful to save a map of properties.
static QMap< QString, QgsProperty > variantMapToPropertyMap(const QVariantMap &variantMap)
Convert a map of QVariant to a map of QgsProperty This is useful to restore a map of properties.
static QgsProperty fromValue(const QVariant &value, bool isActive=true)
Returns a new StaticProperty created from the specified value.
Raster marker symbol layer class.
double mFixedAspectRatio
The marker fixed aspect ratio.
QColor color() const override
Returns the "representative" color of the symbol layer.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
static QgsSymbolLayer * createFromSld(QDomElement &element)
Creates a new QgsRasterMarkerSymbolLayer from an SLD XML element.
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.
Q_DECL_DEPRECATED void writeSldMarker(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Writes the symbol layer definition as a SLD XML element.
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.
A container for the context for various read/write operations on objects.
void pushMessage(const QString &message, Qgis::MessageLevel level=Qgis::MessageLevel::Warning) const
Append a message to the context.
Contains information about the context of a rendering operation.
double scaleFactor() const
Returns the scaling factor for the render to convert painter units to physical sizes.
double convertToPainterUnits(double size, Qgis::RenderUnit unit, const QgsMapUnitScale &scale=QgsMapUnitScale(), Qgis::RenderSubcomponentProperty property=Qgis::RenderSubcomponentProperty::Generic) const
Converts a size from the specified units to painter units (pixels).
QPainter * painter()
Returns the destination QPainter for the render operation.
void setPainterFlagsUsingContext(QPainter *painter=nullptr) const
Sets relevant flags on a destination painter, using the flags and settings currently defined for the ...
QgsExpressionContext & expressionContext()
Gets the expression context.
long long currentFrame() const
Returns the current frame number of the map (in frames per second), for maps which are part of an ani...
float devicePixelRatio() const
Returns the device pixel ratio.
void setFlag(Qgis::RenderContextFlag flag, bool on=true)
Enable or disable a particular flag (other flags are not affected)
double frameRate() const
Returns the frame rate of the map, for maps which are part of an animation.
const QgsMapToPixel & mapToPixel() const
Returns the context's map to pixel transform, which transforms between map coordinates and device coo...
QColor selectionColor() const
Returns the color to use when rendering selected features.
Qgis::RenderContextFlags flags() const
Returns combination of flags used for rendering.
const QgsPathResolver & pathResolver() const
Returns the path resolver for conversion between relative and absolute paths during rendering operati...
Scoped object for saving and restoring a QPainter object's state.
Abstract base class for simple marker symbol layers.
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
void calculateOffsetAndRotation(QgsSymbolRenderContext &context, double scaledSize, bool &hasDataDefinedRotation, QPointF &offset, double &angle) const
Calculates the marker offset and rotation.
Qgis::MarkerShape mShape
Symbol shape.
QPainterPath mPath
Painter path representing shape. If mPolygon is empty then the shape is stored in mPath.
bool shapeToPolygon(Qgis::MarkerShape shape, QPolygonF &polygon) const
Creates a polygon representing the specified shape.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
static QList< Qgis::MarkerShape > availableShapes()
Returns a list of all available shape types.
~QgsSimpleMarkerSymbolLayerBase() override
static bool shapeIsFilled(Qgis::MarkerShape shape)
Returns true if a symbol shape has a fill.
QPolygonF mPolygon
Polygon of points in shape. If polygon is empty then shape is using mPath.
Qgis::MarkerShape shape() const
Returns the shape for the rendered marker symbol.
QRectF bounds(QPointF point, QgsSymbolRenderContext &context) override
Returns the approximate bounding box of the marker symbol layer, taking into account any data defined...
QgsSimpleMarkerSymbolLayerBase(Qgis::MarkerShape shape=Qgis::MarkerShape::Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructor for QgsSimpleMarkerSymbolLayerBase.
static QString encodeShape(Qgis::MarkerShape shape)
Encodes a shape to its string representation.
double calculateSize(QgsSymbolRenderContext &context, bool &hasDataDefinedSize) const
Calculates the desired size of the marker, considering data defined size overrides.
static Qgis::MarkerShape decodeShape(const QString &name, bool *ok=nullptr)
Attempts to decode a string representation of a shape name to the corresponding shape.
bool prepareMarkerPath(Qgis::MarkerShape symbol)
Prepares the layer for drawing the specified shape (QPainterPath version)
bool prepareMarkerShape(Qgis::MarkerShape shape)
Prepares the layer for drawing the specified shape (QPolygonF version)
Simple marker symbol layer, consisting of a rendered shape with solid fill color and a 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.
Q_DECL_DEPRECATED void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
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
Q_DECL_DEPRECATED 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.
Holds SLD export options and other information related to SLD export of a QGIS layer style.
void setExtraProperties(const QVariantMap &properties)
Sets the open ended set of properties that can drive/inform the SLD encoding.
QVariantMap extraProperties() const
Returns the open ended set of properties that can drive/inform the SLD encoding.
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.
A marker symbol layer which renders an SVG graphic.
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.
Q_DECL_DEPRECATED void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const override
Saves the symbol layer as SLD.
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.
Q_DECL_DEPRECATED 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 Q_DECL_DEPRECATED 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 Q_DECL_DEPRECATED void externalMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &path, const QString &format, int *markIndex=nullptr, const QColor &color=QColor(), double size=-1)
Exports a marker to an SLD definition.
static bool wellKnownMarkerFromSld(QDomElement &element, QString &name, QColor &color, QColor &strokeColor, Qt::PenStyle &strokeStyle, double &strokeWidth, double &size)
Extracts properties from an SLD marker definition.
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 Q_DECL_DEPRECATED void wellKnownMarkerToSld(QDomDocument &doc, QDomElement &element, const QString &name, const QColor &color, const QColor &strokeColor, Qt::PenStyle strokeStyle, double strokeWidth=-1, double size=-1)
Exports a marker to SLD.
static QString encodeScaleMethod(Qgis::ScaleMethod scaleMethod)
Encodes a symbol scale method to a string.
static Qt::PenStyle decodePenStyle(const QString &str)
static Q_DECL_DEPRECATED void createRotationElement(QDomDocument &doc, QDomElement &element, const QString &rotationFunc)
Creates SLD rotation element.
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.
Abstract base class for symbol layers.
bool shouldRenderUsingSelectionColor(const QgsSymbolRenderContext &context) const
Returns true if the symbol layer should be rendered using the selection color from the render context...
static const bool SELECTION_IS_OPAQUE
Whether styles for selected features ignore symbol alpha.
bool installMasks(QgsRenderContext &context, bool recursive, const QRectF &rect=QRectF())
When rendering, install masks on context painter.
void removeMasks(QgsRenderContext &context, bool recursive)
When rendering, remove previously installed masks from context painter if recursive is true masks are...
virtual QSet< QString > usedAttributes(const QgsRenderContext &context) const
Returns the set of attributes referenced by the layer.
void copyDataDefinedProperties(QgsSymbolLayer *destLayer) const
Copies all data defined properties of this layer to another symbol layer.
@ StrokeStyle
Stroke style (eg solid, dashed)
@ Name
Name, eg shape name for simple markers.
@ Character
Character, eg for font marker symbol layers.
@ StrokeColor
Stroke color.
@ CapStyle
Line cap style.
@ JoinStyle
Line join style.
@ StrokeWidth
Stroke width.
void restoreOldDataDefinedProperties(const QVariantMap &stringMap)
Restores older data defined properties from string map.
virtual void startRender(QgsSymbolRenderContext &context)=0
Called before a set of rendering operations commences on the supplied render context.
virtual void prepareExpressions(const QgsSymbolRenderContext &context)
Prepares all data defined property expressions for evaluation.
virtual Q_DECL_DEPRECATED void toSld(QDomDocument &doc, QDomElement &element, const QVariantMap &props) const
Saves the symbol layer as SLD.
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.
Encapsulates the context in which a symbol is being rendered.
const QgsFeature * feature() const
Returns the current feature being rendered.
QgsFields fields() const
Fields of the layer.
Qgis::SymbolRenderHints renderHints() const
Returns the rendering hint flags for the symbol.
void setOriginalValueVariable(const QVariant &value)
Sets the original value variable value for data defined symbology.
bool forceVectorRendering() const
Returns true if symbol must be rendered using vector methods, and optimisations like pre-rendered ima...
qreal opacity() const
Returns the opacity for the symbol.
QgsRenderContext & renderContext()
Returns a reference to the context's render context.
Abstract base class for all rendered symbols.
Qgis::SymbolType type() const
Returns the symbol's type.
static Q_INVOKABLE Qgis::RenderUnit decodeRenderUnit(const QString &string, bool *ok=nullptr)
Decodes a render unit from a string.
static Q_INVOKABLE QString encodeUnit(Qgis::DistanceUnit unit)
Encodes a distance unit to a string.
static bool isNull(const QVariant &variant, bool silenceNullWarnings=false)
Returns true if the specified variant should be considered a NULL value.
As part of the API refactoring and improvements which landed in the Processing API was substantially reworked from the x version This was done in order to allow much of the underlying Processing framework to be ported into c
bool qgsDoubleNear(double a, double b, double epsilon=4 *std::numeric_limits< double >::epsilon())
Compare two doubles (but allow some difference)
QMap< QString, QString > QgsStringMap
QVector< QgsPointSequence > QgsRingSequence
QVector< QgsPoint > QgsPointSequence
#define QgsDebugMsgLevel(str, level)
#define QgsDebugError(str)
#define DEFAULT_FONTMARKER_JOINSTYLE
#define DEFAULT_RASTERMARKER_ANGLE
#define DEFAULT_RASTERMARKER_SIZE
#define DEFAULT_SVGMARKER_ANGLE
#define DEFAULT_SIMPLEMARKER_JOINSTYLE
#define DEFAULT_FONTMARKER_CHR
#define DEFAULT_SIMPLEMARKER_BORDERCOLOR
#define DEFAULT_SIMPLEMARKER_SIZE
#define DEFAULT_SIMPLEMARKER_NAME
#define DEFAULT_SIMPLEMARKER_ANGLE
#define DEFAULT_SVGMARKER_SIZE
#define DEFAULT_FONTMARKER_FONT
#define DEFAULT_FONTMARKER_BORDERCOLOR
#define DEFAULT_FONTMARKER_ANGLE
#define DEFAULT_FONTMARKER_COLOR
#define DEFAULT_FONTMARKER_SIZE
#define DEFAULT_SIMPLEMARKER_COLOR
#define DEFAULT_SCALE_METHOD
#define FONTMARKER_CHR_FIX