39#include <QDomDocument>
42#include <QMimeDatabase>
45#include <QSvgRenderer>
48static constexpr int MAX_FONT_CHARACTER_SIZE_IN_PIXELS = 500;
59 QList< Qgis::MarkerShape > shapes;
174 QTransform transform;
177 if ( !hasDataDefinedSize )
187 const double half = scaledSize / 2.0;
188 transform.scale( half, half );
194 transform.rotate(
mAngle );
221 bool hasDataDefinedSize =
false;
222 const double scaledSize =
calculateSize( context, hasDataDefinedSize );
224 bool hasDataDefinedRotation =
false;
230 bool createdNewPath =
false;
248 createdNewPath =
true;
257 QTransform transform;
260 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
263 if ( hasDataDefinedSize || createdNewPath )
272 const double half = s / 2.0;
273 transform.scale( half, half );
278 transform.rotate(
angle );
287 polygon = transform.map(
mPolygon );
291 path = transform.map(
mPath );
293 draw( context, symbol, polygon, path );
298 bool hasDataDefinedSize =
false;
299 double scaledSize =
calculateSize( context, hasDataDefinedSize );
301 bool hasDataDefinedRotation =
false;
308 QTransform transform;
311 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
314 transform.rotate(
angle );
316 return transform.mapRect( QRectF( -scaledSize / 2.0,
326 const QString cleaned = name.toLower().trimmed();
328 if ( cleaned == QLatin1String(
"square" ) || cleaned == QLatin1String(
"rectangle" ) )
330 else if ( cleaned == QLatin1String(
"trapezoid" ) )
332 else if ( cleaned == QLatin1String(
"parallelogram_right" ) )
334 else if ( cleaned == QLatin1String(
"parallelogram_left" ) )
336 else if ( cleaned == QLatin1String(
"square_with_corners" ) )
338 else if ( cleaned == QLatin1String(
"rounded_square" ) )
340 else if ( cleaned == QLatin1String(
"diamond" ) )
342 else if ( cleaned == QLatin1String(
"shield" ) )
344 else if ( cleaned == QLatin1String(
"pentagon" ) )
346 else if ( cleaned == QLatin1String(
"hexagon" ) )
348 else if ( cleaned == QLatin1String(
"octagon" ) )
350 else if ( cleaned == QLatin1String(
"decagon" ) )
352 else if ( cleaned == QLatin1String(
"triangle" ) )
354 else if ( cleaned == QLatin1String(
"equilateral_triangle" ) )
356 else if ( cleaned == QLatin1String(
"star_diamond" ) )
358 else if ( cleaned == QLatin1String(
"star" ) || cleaned == QLatin1String(
"regular_star" ) )
360 else if ( cleaned == QLatin1String(
"heart" ) )
362 else if ( cleaned == QLatin1String(
"arrow" ) )
364 else if ( cleaned == QLatin1String(
"circle" ) )
366 else if ( cleaned == QLatin1String(
"cross" ) )
368 else if ( cleaned == QLatin1String(
"cross_fill" ) )
370 else if ( cleaned == QLatin1String(
"cross2" ) || cleaned == QLatin1String(
"x" ) )
372 else if ( cleaned == QLatin1String(
"line" ) )
374 else if ( cleaned == QLatin1String(
"arrowhead" ) )
376 else if ( cleaned == QLatin1String(
"filled_arrowhead" ) )
378 else if ( cleaned == QLatin1String(
"semi_circle" ) )
380 else if ( cleaned == QLatin1String(
"third_circle" ) )
382 else if ( cleaned == QLatin1String(
"quarter_circle" ) )
384 else if ( cleaned == QLatin1String(
"quarter_square" ) )
386 else if ( cleaned == QLatin1String(
"half_square" ) )
388 else if ( cleaned == QLatin1String(
"diagonal_half_square" ) )
390 else if ( cleaned == QLatin1String(
"right_half_triangle" ) )
392 else if ( cleaned == QLatin1String(
"left_half_triangle" ) )
394 else if ( cleaned == QLatin1String(
"asterisk_fill" ) )
396 else if ( cleaned == QLatin1String(
"half_arc" ) )
398 else if ( cleaned == QLatin1String(
"third_arc" ) )
400 else if ( cleaned == QLatin1String(
"quarter_arc" ) )
413 return QStringLiteral(
"square" );
415 return QStringLiteral(
"quarter_square" );
417 return QStringLiteral(
"half_square" );
419 return QStringLiteral(
"diagonal_half_square" );
421 return QStringLiteral(
"parallelogram_right" );
423 return QStringLiteral(
"parallelogram_left" );
425 return QStringLiteral(
"trapezoid" );
427 return QStringLiteral(
"shield" );
429 return QStringLiteral(
"diamond" );
431 return QStringLiteral(
"pentagon" );
433 return QStringLiteral(
"hexagon" );
435 return QStringLiteral(
"octagon" );
437 return QStringLiteral(
"decagon" );
439 return QStringLiteral(
"square_with_corners" );
441 return QStringLiteral(
"rounded_square" );
443 return QStringLiteral(
"triangle" );
445 return QStringLiteral(
"equilateral_triangle" );
447 return QStringLiteral(
"left_half_triangle" );
449 return QStringLiteral(
"right_half_triangle" );
451 return QStringLiteral(
"star_diamond" );
453 return QStringLiteral(
"star" );
455 return QStringLiteral(
"heart" );
457 return QStringLiteral(
"arrow" );
459 return QStringLiteral(
"filled_arrowhead" );
461 return QStringLiteral(
"cross_fill" );
463 return QStringLiteral(
"circle" );
465 return QStringLiteral(
"cross" );
467 return QStringLiteral(
"cross2" );
469 return QStringLiteral(
"line" );
471 return QStringLiteral(
"arrowhead" );
473 return QStringLiteral(
"semi_circle" );
475 return QStringLiteral(
"third_circle" );
477 return QStringLiteral(
"quarter_circle" );
479 return QStringLiteral(
"asterisk_fill" );
481 return QStringLiteral(
"half_arc" );
483 return QStringLiteral(
"third_arc" );
485 return QStringLiteral(
"quarter_arc" );
502 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 1, 1 ) ) );
507 static constexpr double VERTEX_OFFSET_FROM_ORIGIN = 0.6072;
509 polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
510 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
511 << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
512 << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
513 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
514 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
515 << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
516 << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
517 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
522 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 0 ) ) );
526 polygon = QPolygonF( QRectF( QPointF( -1, -1 ), QPointF( 0, 1 ) ) );
530 polygon << QPointF( -1, -1 ) << QPointF( 1, 1 ) << QPointF( -1, 1 ) << QPointF( -1, -1 );
534 polygon << QPointF( 0.5, -0.5 )
536 << QPointF( -1, 0.5 )
537 << QPointF( -0.5, -0.5 )
538 << QPointF( 0.5, -0.5 );
542 polygon << QPointF( 0.5, 0.5 )
543 << QPointF( 1, -0.5 )
544 << QPointF( -0.5, -0.5 )
545 << QPointF( -1, 0.5 )
546 << QPointF( 0.5, 0.5 );
550 polygon << QPointF( 1, 0.5 )
551 << QPointF( 0.5, -0.5 )
552 << QPointF( -1, -0.5 )
553 << QPointF( -0.5, 0.5 )
554 << QPointF( 1, 0.5 );
558 polygon << QPointF( -1, 0 ) << QPointF( 0, 1 )
559 << QPointF( 1, 0 ) << QPointF( 0, -1 ) << QPointF( -1, 0 );
563 polygon << QPointF( 1, 0.5 )
566 << QPointF( -1, 0.5 )
568 << QPointF( 1, 0.5 );
578 polygon << QPointF( -0.9511, -0.3090 )
579 << QPointF( -0.5878, 0.8090 )
580 << QPointF( 0.5878, 0.8090 )
581 << QPointF( 0.9511, -0.3090 )
583 << QPointF( -0.9511, -0.3090 );
594 polygon << QPointF( -0.8660, -0.5 )
595 << QPointF( -0.8660, 0.5 )
597 << QPointF( 0.8660, 0.5 )
598 << QPointF( 0.8660, -0.5 )
600 << QPointF( -0.8660, -0.5 );
605 static constexpr double VERTEX_OFFSET_FROM_ORIGIN = 1.0 / ( 1 + M_SQRT2 );
607 polygon << QPointF( - VERTEX_OFFSET_FROM_ORIGIN, 1 )
608 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, 1 )
609 << QPointF( 1, VERTEX_OFFSET_FROM_ORIGIN )
610 << QPointF( 1, -VERTEX_OFFSET_FROM_ORIGIN )
611 << QPointF( VERTEX_OFFSET_FROM_ORIGIN, -1 )
612 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, -1 )
613 << QPointF( -1, -VERTEX_OFFSET_FROM_ORIGIN )
614 << QPointF( -1, VERTEX_OFFSET_FROM_ORIGIN )
615 << QPointF( -VERTEX_OFFSET_FROM_ORIGIN, 1 );
622 polygon << QPointF( 0.587785252, 0.809016994 )
623 << QPointF( 0.951056516, 0.309016994 )
624 << QPointF( 0.951056516, -0.309016994 )
625 << QPointF( 0.587785252, -0.809016994 )
627 << QPointF( -0.587785252, -0.809016994 )
628 << QPointF( -0.951056516, -0.309016994 )
629 << QPointF( -0.951056516, 0.309016994 )
630 << QPointF( -0.587785252, 0.809016994 )
632 << QPointF( 0.587785252, 0.809016994 );
637 polygon << QPointF( -1, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
645 polygon << QPointF( -0.8660, 0.5 )
646 << QPointF( 0.8660, 0.5 )
648 << QPointF( -0.8660, 0.5 );
652 polygon << QPointF( 0, 1 ) << QPointF( 1, 1 ) << QPointF( 0, -1 ) << QPointF( 0, 1 );
656 polygon << QPointF( -1, 1 ) << QPointF( 0, 1 ) << QPointF( 0, -1 ) << QPointF( -1, 1 );
661 const double inner_r = std::cos(
DEG2RAD( 72.0 ) ) / std::cos(
DEG2RAD( 36.0 ) );
663 polygon << QPointF( inner_r * std::sin(
DEG2RAD( 315.0 ) ), - inner_r * std::cos(
DEG2RAD( 315.0 ) ) )
664 << QPointF( std::sin(
DEG2RAD( 270 ) ), - std::cos(
DEG2RAD( 270 ) ) )
665 << QPointF( inner_r * std::sin(
DEG2RAD( 225.0 ) ), - inner_r * std::cos(
DEG2RAD( 225.0 ) ) )
666 << QPointF( std::sin(
DEG2RAD( 180 ) ), - std::cos(
DEG2RAD( 180 ) ) )
667 << QPointF( inner_r * std::sin(
DEG2RAD( 135.0 ) ), - inner_r * std::cos(
DEG2RAD( 135.0 ) ) )
668 << QPointF( std::sin(
DEG2RAD( 90 ) ), - std::cos(
DEG2RAD( 90 ) ) )
669 << QPointF( inner_r * std::sin(
DEG2RAD( 45.0 ) ), - inner_r * std::cos(
DEG2RAD( 45.0 ) ) )
670 << QPointF( std::sin(
DEG2RAD( 0 ) ), - std::cos(
DEG2RAD( 0 ) ) )
671 << QPointF( inner_r * std::sin(
DEG2RAD( 315.0 ) ), - inner_r * std::cos(
DEG2RAD( 315.0 ) ) );
677 const double inner_r = std::cos(
DEG2RAD( 72.0 ) ) / std::cos(
DEG2RAD( 36.0 ) );
679 polygon << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) )
680 << QPointF( std::sin(
DEG2RAD( 288.0 ) ), - std::cos(
DEG2RAD( 288 ) ) )
681 << QPointF( inner_r * std::sin(
DEG2RAD( 252.0 ) ), - inner_r * std::cos(
DEG2RAD( 252.0 ) ) )
682 << QPointF( std::sin(
DEG2RAD( 216.0 ) ), - std::cos(
DEG2RAD( 216.0 ) ) )
683 << QPointF( 0, inner_r )
684 << QPointF( std::sin(
DEG2RAD( 144.0 ) ), - std::cos(
DEG2RAD( 144.0 ) ) )
685 << QPointF( inner_r * std::sin(
DEG2RAD( 108.0 ) ), - inner_r * std::cos(
DEG2RAD( 108.0 ) ) )
686 << QPointF( std::sin(
DEG2RAD( 72.0 ) ), - std::cos(
DEG2RAD( 72.0 ) ) )
687 << QPointF( inner_r * std::sin(
DEG2RAD( 36.0 ) ), - inner_r * std::cos(
DEG2RAD( 36.0 ) ) )
689 << QPointF( inner_r * std::sin(
DEG2RAD( 324.0 ) ), - inner_r * std::cos(
DEG2RAD( 324.0 ) ) );
694 polygon << QPointF( 0, -1 )
695 << QPointF( 0.5, -0.5 )
696 << QPointF( 0.25, -0.5 )
697 << QPointF( 0.25, 1 )
698 << QPointF( -0.25, 1 )
699 << QPointF( -0.25, -0.5 )
700 << QPointF( -0.5, -0.5 )
705 polygon << QPointF( 0, 0 ) << QPointF( -1, 1 ) << QPointF( -1, -1 ) << QPointF( 0, 0 );
709 polygon << QPointF( -1, -0.2 )
710 << QPointF( -1, -0.2 )
711 << QPointF( -1, 0.2 )
712 << QPointF( -0.2, 0.2 )
713 << QPointF( -0.2, 1 )
715 << QPointF( 0.2, 0.2 )
717 << QPointF( 1, -0.2 )
718 << QPointF( 0.2, -0.2 )
719 << QPointF( 0.2, -1 )
720 << QPointF( -0.2, -1 )
721 << QPointF( -0.2, -0.2 )
722 << QPointF( -1, -0.2 );
727 static constexpr double THICKNESS = 0.3;
728 static constexpr double HALF_THICKNESS = THICKNESS / 2.0;
729 static constexpr double INTERSECTION_POINT = THICKNESS / M_SQRT2;
730 static constexpr double DIAGONAL1 = M_SQRT1_2 - INTERSECTION_POINT * 0.5;
731 static constexpr double DIAGONAL2 = M_SQRT1_2 + INTERSECTION_POINT * 0.5;
733 polygon << QPointF( -HALF_THICKNESS, -1 )
734 << QPointF( HALF_THICKNESS, -1 )
735 << QPointF( HALF_THICKNESS, -HALF_THICKNESS - INTERSECTION_POINT )
736 << QPointF( DIAGONAL1, -DIAGONAL2 )
737 << QPointF( DIAGONAL2, -DIAGONAL1 )
738 << QPointF( HALF_THICKNESS + INTERSECTION_POINT, -HALF_THICKNESS )
739 << QPointF( 1, -HALF_THICKNESS )
740 << QPointF( 1, HALF_THICKNESS )
741 << QPointF( HALF_THICKNESS + INTERSECTION_POINT, HALF_THICKNESS )
742 << QPointF( DIAGONAL2, DIAGONAL1 )
743 << QPointF( DIAGONAL1, DIAGONAL2 )
744 << QPointF( HALF_THICKNESS, HALF_THICKNESS + INTERSECTION_POINT )
745 << QPointF( HALF_THICKNESS, 1 )
746 << QPointF( -HALF_THICKNESS, 1 )
747 << QPointF( -HALF_THICKNESS, HALF_THICKNESS + INTERSECTION_POINT )
748 << QPointF( -DIAGONAL1, DIAGONAL2 )
749 << QPointF( -DIAGONAL2, DIAGONAL1 )
750 << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, HALF_THICKNESS )
751 << QPointF( -1, HALF_THICKNESS )
752 << QPointF( -1, -HALF_THICKNESS )
753 << QPointF( -HALF_THICKNESS - INTERSECTION_POINT, -HALF_THICKNESS )
754 << QPointF( -DIAGONAL2, -DIAGONAL1 )
755 << QPointF( -DIAGONAL1, -DIAGONAL2 )
756 << QPointF( -HALF_THICKNESS, -HALF_THICKNESS - INTERSECTION_POINT )
757 << QPointF( -HALF_THICKNESS, -1 );
782 mPath = QPainterPath();
788 mPath.addEllipse( QRectF( -1, -1, 2, 2 ) );
792 mPath.moveTo( -1, -1 );
793 mPath.addRoundedRect( -1, -1, 2, 2, 0.25, 0.25 );
797 mPath.arcTo( -1, -1, 2, 2, 0, 180 );
798 mPath.lineTo( 0, 0 );
802 mPath.arcTo( -1, -1, 2, 2, 90, 120 );
803 mPath.lineTo( 0, 0 );
807 mPath.arcTo( -1, -1, 2, 2, 90, 90 );
808 mPath.lineTo( 0, 0 );
812 mPath.moveTo( 1, 0 );
813 mPath.arcTo( -1, -1, 2, 2, 0, 180 );
817 mPath.moveTo( 0, -1 );
818 mPath.arcTo( -1, -1, 2, 2, 90, 120 );
822 mPath.moveTo( 0, -1 );
823 mPath.arcTo( -1, -1, 2, 2, 90, 90 );
827 mPath.moveTo( -1, 0 );
828 mPath.lineTo( 1, 0 );
829 mPath.moveTo( 0, -1 );
830 mPath.lineTo( 0, 1 );
834 mPath.moveTo( -1, -1 );
835 mPath.lineTo( 1, 1 );
836 mPath.moveTo( 1, -1 );
837 mPath.lineTo( -1, 1 );
841 mPath.moveTo( 0, -1 );
842 mPath.lineTo( 0, 1 );
846 mPath.moveTo( -1, -1 );
847 mPath.lineTo( 0, 0 );
848 mPath.lineTo( -1, 1 );
852 mPath.moveTo( 0, 0.75 );
853 mPath.arcTo( 0, -1, 1, 1, -45, 210 );
854 mPath.arcTo( -1, -1, 1, 1, 15, 210 );
855 mPath.lineTo( 0, 0.75 );
889 double scaledSize =
mSize;
893 if ( hasDataDefinedSize )
900 if ( hasDataDefinedSize && ok )
905 scaledSize = std::sqrt( scaledSize );
920 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
921 offset = QPointF( offsetX, offsetY );
923 hasDataDefinedRotation =
false;
936 hasDataDefinedRotation =
true;
941 if ( hasDataDefinedRotation )
988 if ( props.contains( QStringLiteral(
"name" ) ) )
992 if ( props.contains( QStringLiteral(
"color" ) ) )
994 if ( props.contains( QStringLiteral(
"color_border" ) ) )
999 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
1003 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
1007 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
1011 if ( props.contains( QStringLiteral(
"size" ) ) )
1012 size = props[QStringLiteral(
"size" )].toDouble();
1013 if ( props.contains( QStringLiteral(
"angle" ) ) )
1014 angle = props[QStringLiteral(
"angle" )].toDouble();
1015 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1019 if ( props.contains( QStringLiteral(
"offset" ) ) )
1021 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1023 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1025 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1027 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1030 if ( props.contains( QStringLiteral(
"outline_style" ) ) )
1034 else if ( props.contains( QStringLiteral(
"line_style" ) ) )
1038 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
1040 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
1042 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
1044 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
1046 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
1050 if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
1054 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
1059 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1063 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1068 if ( props.contains( QStringLiteral(
"cap_style" ) ) )
1081 return QStringLiteral(
"SimpleMarker" );
1093 QColor brushColor =
mColor;
1096 brushColor.setAlphaF(
mColor.alphaF() * context.
opacity() );
1099 mBrush = QBrush( brushColor );
1100 mPen = QPen( penColor );
1110 selBrushColor.setAlphaF( context.
opacity() );
1111 selPenColor.setAlphaF( context.
opacity() );
1114 mSelPen = QPen( selPenColor );
1130 mCachedOpacity = context.
opacity();
1136 mSelPen.setColor( selBrushColor );
1169 scaledSize = ( std::abs( std::sin(
mAngle * M_PI / 180 ) ) + std::abs( std::cos(
mAngle * M_PI / 180 ) ) ) * scaledSize;
1172 const double pw =
static_cast< int >( std::round( ( (
qgsDoubleNear(
mPen.widthF(), 0.0 ) ? 1 :
mPen.widthF() * 4 ) + 1 ) ) ) / 2 * 2;
1173 const int imageSize = (
static_cast< int >( scaledSize ) + pw ) / 2 * 2 + 1;
1174 const double center = imageSize / 2.0;
1180 mCache = QImage( QSize( imageSize * deviceRatio,
1181 imageSize * deviceRatio ), QImage::Format_ARGB32_Premultiplied );
1191 p.setRenderHint( QPainter::Antialiasing );
1192 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
1194 p.translate( QPointF( center, center ) );
1202 mSelCache = QImage( QSize( imageSize, imageSize ), QImage::Format_ARGB32_Premultiplied );
1206 p.setRenderHint( QPainter::Antialiasing );
1207 p.setBrush( needsBrush ?
mSelBrush : Qt::NoBrush );
1209 p.translate( QPointF( center, center ) );
1220 p.setRenderHint( QPainter::Antialiasing );
1221 p.fillRect( 0, 0, imageSize, imageSize, selColor );
1222 p.setBrush( needsBrush ?
mBrush : Qt::NoBrush );
1224 p.translate( QPointF( center, center ) );
1243 QColor brushColor =
mColor;
1244 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
1245 mBrush.setColor( brushColor );
1248 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
1249 mPen.setColor( penColor );
1258 c.setAlphaF(
c.alphaF() * context.
opacity() );
1268 c.setAlphaF(
c.alphaF() * context.
opacity() );
1321 p->setBrush( Qt::NoBrush );
1325 if ( !polygon.isEmpty() )
1326 p->drawPolygon( polygon );
1328 p->drawPath( path );
1346 const double s = img.width() / img.devicePixelRatioF();
1348 bool hasDataDefinedSize =
false;
1349 const double scaledSize =
calculateSize( context, hasDataDefinedSize );
1351 bool hasDataDefinedRotation =
false;
1356 p->drawImage( QRectF( point.x() - s / 2.0 +
offset.x(),
1357 point.y() - s / 2.0 +
offset.y(),
1372 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1375 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1381 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
1386 map[QStringLiteral(
"horizontal_anchor_point" )] = QString::number(
static_cast< int >(
mHorizontalAnchorPoint ) );
1387 map[QStringLiteral(
"vertical_anchor_point" )] = QString::number(
static_cast< int >(
mVerticalAnchorPoint ) );
1415 toSld( doc, element, context );
1433 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
1434 element.appendChild( graphicElem );
1451 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
1454 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
1472 Q_UNUSED( mmScaleFactor )
1473 Q_UNUSED( mapUnitScaleFactor )
1475 QString ogrType =
"3";
1476 if ( mName ==
"square" )
1480 else if ( mName ==
"triangle" )
1484 else if ( mName ==
"star" )
1488 else if ( mName ==
"circle" )
1492 else if ( mName ==
"cross" )
1496 else if ( mName ==
"x" || mName ==
"cross2" )
1500 else if ( mName ==
"line" )
1506 ogrString.append(
"SYMBOL(" );
1507 ogrString.append(
"id:" );
1508 ogrString.append(
'\"' );
1509 ogrString.append(
"ogr-sym-" );
1510 ogrString.append( ogrType );
1511 ogrString.append(
'\"' );
1512 ogrString.append(
",c:" );
1513 ogrString.append(
mColor.name() );
1514 ogrString.append(
",o:" );
1516 ogrString.append( QString(
",s:%1mm" ).arg(
mSize ) );
1517 ogrString.append(
')' );
1522 ogrString.append(
"PEN(" );
1523 ogrString.append(
"c:" );
1524 ogrString.append(
mColor.name() );
1525 ogrString.append(
",w:" );
1526 ogrString.append( QString::number(
mSize ) );
1527 ogrString.append(
"mm" );
1528 ogrString.append(
")" );
1536 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
1537 if ( graphicElem.isNull() )
1540 QString name = QStringLiteral(
"square" );
1553 const double d = angleFunc.toDouble( &ok );
1563 double scaleFactor = 1.0;
1564 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
1591 p->drawPath(
mPath );
1604 if ( hasDataDefinedSize )
1623 size *= mmMapUnitScaleFactor;
1630 const double halfSize =
size / 2.0;
1647 QColor pc =
mPen.color();
1648 QColor bc =
mBrush.color();
1668 QPointF off( offsetX, offsetY );
1697 t.translate( shift.x() + off.x(), shift.y() - off.y() );
1705 t.scale( halfSize, -halfSize );
1707 polygon = t.map( polygon );
1710 p.reserve( polygon.size() );
1711 for (
int i = 0; i < polygon.size(); i++ )
1716 if (
mBrush.style() != Qt::NoBrush )
1718 if (
mPen.style() != Qt::NoPen )
1723 shift += QPointF( off.x(), -off.y() );
1724 if (
mBrush.style() != Qt::NoBrush )
1726 if (
mPen.style() != Qt::NoPen )
1731 const QPointF pt1 = t.map( QPointF( 0, -halfSize ) );
1732 const QPointF pt2 = t.map( QPointF( 0, halfSize ) );
1734 if (
mPen.style() != Qt::NoPen )
1739 if (
mPen.style() != Qt::NoPen )
1741 const QPointF pt1 = t.map( QPointF( -halfSize, 0 ) );
1742 const QPointF pt2 = t.map( QPointF( halfSize, 0 ) );
1743 const QPointF pt3 = t.map( QPointF( 0, -halfSize ) );
1744 const QPointF pt4 = t.map( QPointF( 0, halfSize ) );
1752 if (
mPen.style() != Qt::NoPen )
1754 const QPointF pt1 = t.map( QPointF( -halfSize, -halfSize ) );
1755 const QPointF pt2 = t.map( QPointF( halfSize, halfSize ) );
1756 const QPointF pt3 = t.map( QPointF( halfSize, -halfSize ) );
1757 const QPointF pt4 = t.map( QPointF( -halfSize, halfSize ) );
1765 if (
mPen.style() != Qt::NoPen )
1767 const QPointF pt1 = t.map( QPointF( -halfSize, halfSize ) );
1768 const QPointF pt2 = t.map( QPointF( 0, 0 ) );
1769 const QPointF pt3 = t.map( QPointF( -halfSize, -halfSize ) );
1855 symbolBounds.adjust( -penWidth / 2.0, -penWidth / 2.0,
1856 penWidth / 2.0, penWidth / 2.0 );
1858 return symbolBounds;
1907 if ( props.contains( QStringLiteral(
"name" ) ) )
1908 name = props[QStringLiteral(
"name" )].toString();
1909 if ( props.contains( QStringLiteral(
"size" ) ) )
1910 size = props[QStringLiteral(
"size" )].toDouble();
1911 if ( props.contains( QStringLiteral(
"angle" ) ) )
1912 angle = props[QStringLiteral(
"angle" )].toDouble();
1913 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
1917 if ( props.contains( QStringLiteral(
"offset" ) ) )
1919 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
1921 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
1923 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
1925 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
1927 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
1931 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
1945 return QStringLiteral(
"FilledMarker" );
1985 map[QStringLiteral(
"size" )] = QString::number(
mSize );
1988 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
1993 map[QStringLiteral(
"horizontal_anchor_point" )] = QString::number(
static_cast< int >(
mHorizontalAnchorPoint ) );
1994 map[QStringLiteral(
"vertical_anchor_point" )] = QString::number(
static_cast< int >(
mVerticalAnchorPoint ) );
2044 attr.unite( mFill->usedAttributes( context ) );
2052 if ( mFill && mFill->hasDataDefinedProperties() )
2061 mFill->setColor(
c );
2066 return mFill ? mFill->color() :
mColor;
2073 || ( mFill && mFill->usesMapUnits() );
2080 mFill->setOutputUnit( unit );
2094 const double prevOpacity = mFill->opacity();
2095 mFill->setOpacity( mFill->opacity() * context.
opacity() );
2099 p->setBrush( Qt::red );
2103 p->setBrush( Qt::NoBrush );
2105 p->setPen( Qt::black );
2111 if ( !polygon.isEmpty() )
2113 mFill->renderPolygon( polygon,
nullptr, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2117 const QPolygonF poly = path.toFillPolygon();
2118 mFill->renderPolygon( poly,
nullptr, context.
feature(), context.
renderContext(), -1, useSelectedColor );
2123 mFill->setOpacity( prevOpacity );
2138 mColor = QColor( 35, 35, 35 );
2166 if ( props.contains( QStringLiteral(
"name" ) ) )
2167 name = props[QStringLiteral(
"name" )].toString();
2168 if ( props.contains( QStringLiteral(
"size" ) ) )
2169 size = props[QStringLiteral(
"size" )].toDouble();
2170 if ( props.contains( QStringLiteral(
"angle" ) ) )
2171 angle = props[QStringLiteral(
"angle" )].toDouble();
2172 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
2177 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
2179 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
2181 if ( props.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
2183 if ( props.contains( QStringLiteral(
"offset" ) ) )
2185 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
2187 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
2189 if ( props.contains( QStringLiteral(
"fill" ) ) )
2194 else if ( props.contains( QStringLiteral(
"color" ) ) )
2198 if ( props.contains( QStringLiteral(
"outline" ) ) )
2203 else if ( props.contains( QStringLiteral(
"outline_color" ) ) )
2207 else if ( props.contains( QStringLiteral(
"line_color" ) ) )
2212 if ( props.contains( QStringLiteral(
"outline-width" ) ) )
2215 m->
setStrokeWidth( props[QStringLiteral(
"outline-width" )].toDouble() );
2217 else if ( props.contains( QStringLiteral(
"outline_width" ) ) )
2219 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
2221 else if ( props.contains( QStringLiteral(
"line_width" ) ) )
2223 m->
setStrokeWidth( props[QStringLiteral(
"line_width" )].toDouble() );
2226 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
2230 else if ( props.contains( QStringLiteral(
"line_width_unit" ) ) )
2234 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
2237 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
2241 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
2250 if ( props.contains( QStringLiteral(
"parameters" ) ) )
2252 const QVariantMap
parameters = props[QStringLiteral(
"parameters" )].toMap();
2261 const QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
2280 QColor defaultFillColor, defaultStrokeColor;
2282 bool hasFillOpacityParam =
false, hasStrokeParam =
false, hasStrokeWidthParam =
false, hasStrokeOpacityParam =
false;
2283 bool hasDefaultFillColor =
false, hasDefaultFillOpacity =
false, hasDefaultStrokeColor =
false, hasDefaultStrokeWidth =
false, hasDefaultStrokeOpacity =
false;
2285 hasFillOpacityParam, hasDefaultFillOpacity, fillOpacity,
2286 hasStrokeParam, hasDefaultStrokeColor, defaultStrokeColor,
2287 hasStrokeWidthParam, hasDefaultStrokeWidth,
strokeWidth,
2288 hasStrokeOpacityParam, hasDefaultStrokeOpacity, strokeOpacity );
2290 const double newFillOpacity = hasFillOpacityParam ?
fillColor().alphaF() : 1.0;
2291 const double newStrokeOpacity = hasStrokeOpacityParam ?
strokeColor().alphaF() : 1.0;
2293 if ( hasDefaultFillColor )
2295 defaultFillColor.setAlphaF( newFillOpacity );
2298 if ( hasDefaultFillOpacity )
2301 c.setAlphaF( fillOpacity );
2304 if ( hasDefaultStrokeColor )
2306 defaultStrokeColor.setAlphaF( newStrokeOpacity );
2309 if ( hasDefaultStrokeWidth )
2313 if ( hasDefaultStrokeOpacity )
2316 c.setAlphaF( strokeOpacity );
2330 const double widthScaleFactor = 3.465;
2333 mDefaultAspectRatio = svgViewbox.isValid() ? svgViewbox.height() / svgViewbox.width() : 0.0;
2341 if ( aPreservedAspectRatio && !par )
2345 else if ( !aPreservedAspectRatio && par )
2360 return QStringLiteral(
"SvgMarker" );
2385 bool hasDataDefinedSize =
false;
2386 const double scaledWidth = calculateSize( context, hasDataDefinedSize );
2391 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
2398 bool hasDataDefinedAspectRatio =
false;
2399 const double aspectRatio =
calculateAspectRatio( context, scaledWidth, hasDataDefinedAspectRatio );
2443 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
2447 QPointF outputOffset;
2449 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
2451 p->translate( point + outputOffset );
2457 bool fitsInCache =
true;
2458 bool usePict =
true;
2460 if ( ( !context.
forceVectorRendering() && !rotated ) || ( useSelectedColor && rasterizeSelected ) )
2465 if ( fitsInCache && img.width() > 1 )
2469 if ( useSelectedColor )
2477 QImage transparentImage = img.copy();
2479 if ( devicePixelRatio == 1 )
2481 p->drawImage( -transparentImage.width() / 2.0, -transparentImage.height() / 2.0, transparentImage );
2485 p->drawImage( QRectF( -transparentImage.width() / 2.0 / devicePixelRatio, -transparentImage.height() / 2.0 / devicePixelRatio,
2486 transparentImage.width() / devicePixelRatio, transparentImage.height() / devicePixelRatio
2487 ), transparentImage );
2492 if ( devicePixelRatio == 1 )
2494 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
2498 p->drawImage( QRectF( -img.width() / 2.0 / devicePixelRatio, -img.height() / 2.0 / devicePixelRatio,
2499 img.width() / devicePixelRatio, img.height() / devicePixelRatio ), img );
2505 if ( usePict || !fitsInCache )
2507 p->setOpacity( context.
opacity() );
2511 if ( pct.width() > 1 )
2521double QgsSvgMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
2523 double scaledSize =
mSize;
2527 if ( hasDataDefinedSize )
2535 if ( hasDataDefinedSize )
2542 if ( hasDataDefinedSize && ok )
2547 scaledSize = std::sqrt( scaledSize );
2560 if ( !hasDataDefinedAspectRatio )
2570 const double defaultHeight =
mSize * scaledAspectRatio;
2571 scaledAspectRatio = defaultHeight / scaledSize;
2574 double scaledHeight = scaledSize * scaledAspectRatio;
2581 if ( hasDataDefinedAspectRatio && ok )
2586 scaledHeight = sqrt( scaledHeight );
2593 scaledAspectRatio = scaledHeight / scaledSize;
2595 return scaledAspectRatio;
2598void QgsSvgMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &angle )
const
2603 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
2604 offset = QPointF( offsetX, offsetY );
2614 if ( hasDataDefinedRotation )
2621 const QgsFeature *f = context.
feature();
2640 map[QStringLiteral(
"name" )] =
mPath;
2641 map[QStringLiteral(
"size" )] = QString::number(
mSize );
2644 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
2645 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
2652 map[QStringLiteral(
"outline_width" )] = QString::number(
mStrokeWidth );
2655 map[QStringLiteral(
"horizontal_anchor_point" )] = QString::number(
static_cast< int >(
mHorizontalAnchorPoint ) );
2656 map[QStringLiteral(
"vertical_anchor_point" )] = QString::number(
static_cast< int >(
mVerticalAnchorPoint ) );
2679 toSld( doc, element, context );
2728 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
2729 element.appendChild( graphicElem );
2740 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
2743 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
2762 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
2763 if ( graphicElem.isNull() )
2766 QString
path, mimeType;
2774 double scaleFactor = 1.0;
2775 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
2779 if ( mimeType != QLatin1String(
"image/svg+xml" ) )
2787 const double d = angleFunc.toDouble( &ok );
2796 QString realPath {
path };
2797 QUrl svgUrl {
path };
2800 QUrlQuery queryString;
2802 if ( svgUrl.hasQuery() && svgUrl.hasFragment() )
2804 const QString queryPart {
path.mid(
path.indexOf(
'?' ) + 1 ) };
2805 queryString.setQuery( queryPart );
2809 if ( svgUrl.scheme().isEmpty() || svgUrl.isLocalFile() )
2811 svgUrl.setQuery( QString() );
2812 realPath = svgUrl.path();
2817 QMap<QString, QgsProperty> params;
2821 if ( queryString.hasQueryItem( QStringLiteral(
"fill" ) ) )
2823 const QColor
fillColor { queryString.queryItemValue( QStringLiteral(
"fill" ) ) };
2827 if ( queryString.hasQueryItem( QStringLiteral(
"fill-opacity" ) ) )
2829 const double alpha { queryString.queryItemValue( QStringLiteral(
"fill-opacity" ) ).toDouble( &ok ) };
2836 if ( queryString.hasQueryItem( QStringLiteral(
"outline" ) ) )
2838 const QColor
strokeColor { queryString.queryItemValue( QStringLiteral(
"outline" ) ) };
2842 if ( queryString.hasQueryItem( QStringLiteral(
"outline-opacity" ) ) )
2844 const double alpha { queryString.queryItemValue( QStringLiteral(
"outline-opacity" ) ).toDouble( &ok ) };
2851 if ( queryString.hasQueryItem( QStringLiteral(
"outline-width" ) ) )
2853 const int width { queryString.queryItemValue( QStringLiteral(
"outline-width" ) ).toInt( &ok )};
2860 if ( ! params.isEmpty() )
2879 if ( hasDataDefinedSize )
2885 if ( hasDataDefinedSize && ok )
2899 size *= mmMapUnitScaleFactor;
2913 const double offsetX =
offset.x();
2914 const double offsetY =
offset.y();
2916 QPointF outputOffset( offsetX, offsetY );
2966 QSvgRenderer r( svgContent );
2973 QSizeF outSize( r.defaultSize() );
2974 outSize.scale(
size,
size, Qt::KeepAspectRatio );
2980 p.translate( r.defaultSize().width() / 2.0, r.defaultSize().height() / 2.0 );
2982 p.translate( -r.defaultSize().width() / 2.0, -r.defaultSize().height() / 2.0 );
2984 pd.
setShift( shift + QPointF( outputOffset.x(), -outputOffset.y() ) );
2985 pd.
setOutputSize( QRectF( -outSize.width() / 2.0, -outSize.height() / 2.0, outSize.width(), outSize.height() ) );
2994 bool hasDataDefinedSize =
false;
2995 double scaledWidth = calculateSize( context, hasDataDefinedSize );
2997 bool hasDataDefinedAspectRatio =
false;
2998 const double aspectRatio =
calculateAspectRatio( context, scaledWidth, hasDataDefinedAspectRatio );
3005 if (
static_cast< int >( scaledWidth ) < 1 || 10000.0 < scaledWidth )
3010 QPointF outputOffset;
3012 calculateOffsetAndRotation( context, scaledWidth, scaledHeight, outputOffset,
angle );
3051 scaledHeight = svgViewbox.isValid() ? scaledWidth * svgViewbox.height() / svgViewbox.width() : scaledWidth;
3055 QTransform transform;
3057 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
3060 transform.rotate(
angle );
3065 QRectF symbolBounds = transform.mapRect( QRectF( -scaledWidth / 2.0,
3066 -scaledHeight / 2.0,
3074 return symbolBounds;
3098 if ( props.contains( QStringLiteral(
"imageFile" ) ) )
3099 path = props[QStringLiteral(
"imageFile" )].toString();
3100 if ( props.contains( QStringLiteral(
"size" ) ) )
3101 size = props[QStringLiteral(
"size" )].toDouble();
3102 if ( props.contains( QStringLiteral(
"angle" ) ) )
3103 angle = props[QStringLiteral(
"angle" )].toDouble();
3104 if ( props.contains( QStringLiteral(
"scale_method" ) ) )
3108 m->setCommonProperties( props );
3114 const QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
3115 if ( graphicElem.isNull() )
3118 const QDomElement externalGraphicElem = graphicElem.firstChildElement( QStringLiteral(
"ExternalGraphic" ) );
3119 if ( externalGraphicElem.isNull() )
3122 const QDomElement onlineResourceElem = externalGraphicElem.firstChildElement( QStringLiteral(
"OnlineResource" ) );
3123 const QDomElement inlineContentElem = externalGraphicElem.firstChildElement( QStringLiteral(
"InlineContent" ) );
3126 if ( !onlineResourceElem.isNull() )
3128 url = onlineResourceElem.attribute( QStringLiteral(
"href" ) );
3131 else if ( !inlineContentElem.isNull() && inlineContentElem.attribute( QStringLiteral(
"encoding" ) ) == QLatin1String(
"base64" ) )
3133 url = QStringLiteral(
"base64:" ) + inlineContentElem.text();
3147 if (
properties.contains( QStringLiteral(
"alpha" ) ) )
3152 if (
properties.contains( QStringLiteral(
"size_unit" ) ) )
3154 if (
properties.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
3156 if (
properties.contains( QStringLiteral(
"fixedAspectRatio" ) ) )
3159 if (
properties.contains( QStringLiteral(
"offset" ) ) )
3161 if (
properties.contains( QStringLiteral(
"offset_unit" ) ) )
3163 if (
properties.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
3166 if (
properties.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
3170 if (
properties.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
3181 const QVariantMap::iterator it =
properties.find( QStringLiteral(
"name" ) );
3182 if ( it !=
properties.end() && it.value().userType() == QMetaType::Type::QString )
3200 if ( aPreservedAspectRatio && !par )
3204 else if ( !aPreservedAspectRatio && par )
3223 return QStringLiteral(
"RasterMarker" );
3244 if (
path.isEmpty() )
3248 double height = 0.0;
3250 bool hasDataDefinedSize =
false;
3251 const double scaledSize = calculateSize( context, hasDataDefinedSize );
3253 bool hasDataDefinedAspectRatio =
false;
3254 const double aspectRatio =
calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
3256 QPointF outputOffset;
3263 if (
size.isEmpty() )
3266 width = ( scaledSize *
static_cast< double >(
size.width() ) ) / 100.0;
3267 height = ( scaledSize *
static_cast< double >(
size.height() ) ) / 100.0;
3270 if (
static_cast< int >( width ) < 1 || 10000.0 < width ||
static_cast< int >( height ) < 1 || 10000.0 < height )
3273 calculateOffsetAndRotation( context, width, height, outputOffset,
angle );
3283 if ( !
size.isNull() &&
size.isValid() &&
size.width() > 0 )
3285 height = width * (
static_cast< double >(
size.height() ) /
static_cast< double >(
size.width() ) );
3290 if (
static_cast< int >( width ) < 1 || 10000.0 < width )
3293 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
3297 p->translate( point + outputOffset );
3312 if ( !img.isNull() )
3315 if ( useSelectedColor )
3320 p->drawImage( -img.width() / 2.0, -img.height() / 2.0, img );
3326 bool cached =
false;
3330double QgsRasterMarkerSymbolLayer::calculateSize(
QgsSymbolRenderContext &context,
bool &hasDataDefinedSize )
const
3332 double scaledSize =
mSize;
3336 if ( hasDataDefinedSize )
3344 if ( hasDataDefinedSize )
3351 if ( hasDataDefinedSize && ok )
3356 scaledSize = std::sqrt( scaledSize );
3369 if ( !hasDataDefinedAspectRatio )
3379 const double defaultHeight =
mSize * scaledAspectRatio;
3380 scaledAspectRatio = defaultHeight / scaledSize;
3383 double scaledHeight = scaledSize * scaledAspectRatio;
3390 if ( hasDataDefinedAspectRatio && ok )
3395 scaledHeight = sqrt( scaledHeight );
3402 scaledAspectRatio = scaledHeight / scaledSize;
3404 return scaledAspectRatio;
3407void QgsRasterMarkerSymbolLayer::calculateOffsetAndRotation(
QgsSymbolRenderContext &context,
double scaledWidth,
double scaledHeight, QPointF &offset,
double &angle )
const
3412 markerOffset( context, scaledWidth, scaledHeight, offsetX, offsetY );
3413 offset = QPointF( offsetX, offsetY );
3423 if ( hasDataDefinedRotation )
3425 const QgsFeature *f = context.
feature();
3444 map[QStringLiteral(
"imageFile" )] =
mPath;
3445 map[QStringLiteral(
"size" )] = QString::number(
mSize );
3448 map[QStringLiteral(
"fixedAspectRatio" )] = QString::number(
mFixedAspectRatio );
3449 map[QStringLiteral(
"angle" )] = QString::number(
mAngle );
3450 map[QStringLiteral(
"alpha" )] = QString::number(
mOpacity );
3455 map[QStringLiteral(
"horizontal_anchor_point" )] = QString::number(
static_cast< int >(
mHorizontalAnchorPoint ) );
3456 map[QStringLiteral(
"vertical_anchor_point" )] = QString::number(
static_cast< int >(
mVerticalAnchorPoint ) );
3462 auto m = std::make_unique< QgsRasterMarkerSymbolLayer >();
3511 bool hasDataDefinedSize =
false;
3512 const double scaledSize = calculateSize( context, hasDataDefinedSize );
3514 bool hasDataDefinedAspectRatio =
false;
3515 const double aspectRatio =
calculateAspectRatio( context, scaledSize, hasDataDefinedAspectRatio );
3519 if (
static_cast< int >( scaledSize ) < 1 || 10000.0 < scaledSize )
3524 QPointF outputOffset;
3526 calculateOffsetAndRotation( context, scaledSize, scaledSize * ( height / width ), outputOffset,
angle );
3528 QTransform transform;
3531 transform.translate( point.x() + outputOffset.x(), point.y() + outputOffset.y() );
3534 transform.rotate(
angle );
3536 QRectF symbolBounds = transform.mapRect( QRectF( -width / 2.0,
3541 return symbolBounds;
3556 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
3557 element.appendChild( graphicElem );
3560 QDomElement extGraphElem = doc.createElement( QStringLiteral(
"se:ExternalGraphic" ) );
3561 graphicElem.appendChild( extGraphElem );
3563 QMimeDatabase mimeDB;
3567 if (
mPath.startsWith( QLatin1String(
"base64:" ) ) )
3569 base64data =
mPath.mid( 7 );
3581 if ( !base64data.isEmpty() )
3584 QDomElement inlineContEleme = doc.createElement( QStringLiteral(
"se:InlineContent" ) );
3586 inlineContEleme.setAttribute( QStringLiteral(
"encoding" ), QStringLiteral(
"base64" ) );
3587 inlineContEleme.appendChild( doc.createTextNode( base64data ) );
3588 extGraphElem.appendChild( inlineContEleme );
3591 const QByteArray ba = QByteArray::fromBase64( base64data.toUtf8() );
3592 mimeType = mimeDB.mimeTypeForData( ba );
3597 QDomElement onlineResElem = doc.createElement( QStringLiteral(
"se:OnlineResource" ) );
3598 QString url =
mPath;
3600 onlineResElem.setAttribute( QStringLiteral(
"xlink:href" ), url );
3601 onlineResElem.setAttribute( QStringLiteral(
"xlink:type" ), QStringLiteral(
"simple" ) );
3602 extGraphElem.appendChild( onlineResElem );
3605 if (
mPath.startsWith( QLatin1String(
"http://" ) ) ||
mPath.startsWith( QLatin1String(
"https://" ) ) )
3609 mimeType = mimeDB.mimeTypeForName(
"image/png" );
3613 mimeType = mimeDB.mimeTypeForUrl( url );
3617 QDomElement formatElem = doc.createElement( QStringLiteral(
"se:Format" ) );
3618 formatElem.appendChild( doc.createTextNode( mimeType.name() ) );
3619 extGraphElem.appendChild( formatElem );
3634 mOrigSize = pointSize;
3654 if ( props.contains( QStringLiteral(
"font" ) ) )
3655 fontFamily = props[QStringLiteral(
"font" )].toString();
3656 if ( props.contains( QStringLiteral(
"chr" ) ) && props[QStringLiteral(
"chr" )].toString().length() > 0 )
3658 string = props[
"chr"].toString();
3659 const thread_local QRegularExpression charRegExp( QStringLiteral(
"%1([0-9]+)%1" ).arg(
FONTMARKER_CHR_FIX ) );
3660 QRegularExpressionMatch match = charRegExp.match(
string );
3661 while ( match.hasMatch() )
3663 QChar replacement = QChar( match.captured( 1 ).toUShort() );
3664 string =
string.mid( 0, match.capturedStart( 0 ) ) + replacement +
string.mid( match.capturedEnd( 0 ) );
3665 match = charRegExp.match(
string );
3669 if ( props.contains( QStringLiteral(
"size" ) ) )
3670 pointSize = props[QStringLiteral(
"size" )].toDouble();
3671 if ( props.contains( QStringLiteral(
"color" ) ) )
3673 if ( props.contains( QStringLiteral(
"angle" ) ) )
3674 angle = props[QStringLiteral(
"angle" )].toDouble();
3678 if ( props.contains( QStringLiteral(
"font_style" ) ) )
3679 m->
setFontStyle( props[QStringLiteral(
"font_style" )].toString() );
3680 if ( props.contains( QStringLiteral(
"outline_color" ) ) )
3682 if ( props.contains( QStringLiteral(
"outline_width" ) ) )
3683 m->
setStrokeWidth( props[QStringLiteral(
"outline_width" )].toDouble() );
3684 if ( props.contains( QStringLiteral(
"offset" ) ) )
3686 if ( props.contains( QStringLiteral(
"offset_unit" ) ) )
3688 if ( props.contains( QStringLiteral(
"offset_map_unit_scale" ) ) )
3690 if ( props.contains( QStringLiteral(
"size_unit" ) ) )
3692 if ( props.contains( QStringLiteral(
"size_map_unit_scale" ) ) )
3694 if ( props.contains( QStringLiteral(
"outline_width_unit" ) ) )
3696 if ( props.contains( QStringLiteral(
"outline_width_map_unit_scale" ) ) )
3698 if ( props.contains( QStringLiteral(
"joinstyle" ) ) )
3700 if ( props.contains( QStringLiteral(
"horizontal_anchor_point" ) ) )
3702 if ( props.contains( QStringLiteral(
"vertical_anchor_point" ) ) )
3712 return QStringLiteral(
"FontMarker" );
3722 QColor brushColor =
mColor;
3723 QColor penColor = mStrokeColor;
3725 brushColor.setAlphaF(
mColor.alphaF() * context.
opacity() );
3726 penColor.setAlphaF( mStrokeColor.alphaF() * context.
opacity() );
3728 mBrush = QBrush( brushColor );
3729 mPen = QPen( penColor );
3730 mPen.setJoinStyle( mPenJoinStyle );
3734 if ( !mFontStyle.isEmpty() )
3742 if ( mNonZeroFontSize && sizePixels > MAX_FONT_CHARACTER_SIZE_IN_PIXELS )
3747 mFontSizeScale = sizePixels / MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
3748 sizePixels = MAX_FONT_CHARACTER_SIZE_IN_PIXELS;
3751 mFontSizeScale = 1.0;
3755 mFont.setPixelSize( std::max( 2,
static_cast< int >( std::round( sizePixels ) ) ) );
3756 mFontMetrics = std::make_unique<QFontMetrics>( mFont );
3757 mChrWidth = mFontMetrics->horizontalAdvance( mString );
3762 mChrOffset = QPointF( mChrWidth / 2.0, -sizePixels / 2.0 );
3769 mChrOffset = QPointF( mChrWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3779 if ( mUseCachedPath )
3781 QPointF chrOffset = mChrOffset;
3783 const QString charToRender = characterToRender( context, chrOffset, chrWidth );
3784 mCachedPath = QPainterPath();
3785 mCachedPath.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
3794QString QgsFontMarkerSymbolLayer::characterToRender(
QgsSymbolRenderContext &context, QPointF &charOffset,
double &charWidth )
3796 charOffset = mChrOffset;
3797 QString stringToRender = mString;
3802 if ( stringToRender != mString )
3804 charWidth = mFontMetrics->horizontalAdvance( stringToRender );
3810 charOffset = QPointF( charWidth / 2.0, -sizePixels / 2.0 );
3817 charOffset = QPointF( charWidth / 2.0, -mFontMetrics->ascent() / 2.0 );
3823 return stringToRender;
3828 bool &hasDataDefinedRotation,
3830 double &angle )
const
3835 markerOffset( context, scaledSize, scaledSize, offsetX, offsetY );
3836 offset = QPointF( offsetX, offsetY );
3837 hasDataDefinedRotation =
false;
3851 hasDataDefinedRotation =
true;
3855 if ( hasDataDefinedRotation )
3862 const QgsFeature *f = context.
feature();
3879 double scaledSize =
mSize;
3883 if ( hasDataDefinedSize )
3889 if ( hasDataDefinedSize && ok )
3894 scaledSize = std::sqrt( scaledSize );
3906 if ( !p || !mNonZeroFontSize )
3909 QTransform transform;
3912 QColor brushColor =
mColor;
3922 brushColor.setAlphaF( brushColor.alphaF() * context.
opacity() );
3924 mBrush.setColor( brushColor );
3926 QColor penColor = mStrokeColor;
3932 penColor.setAlphaF( penColor.alphaF() * context.
opacity() );
3956 p->setBrush( mBrush );
3959 mPen.setColor( penColor );
3960 mPen.setWidthF( penWidth );
3965 p->setPen( Qt::NoPen );
3983 mFontMetrics = std::make_unique<QFontMetrics>( mFont );
3986 QPointF chrOffset = mChrOffset;
3988 const QString charToRender = characterToRender( context, chrOffset, chrWidth );
3990 const double sizeToRender = calculateSize( context );
3992 bool hasDataDefinedRotation =
false;
3995 calculateOffsetAndRotation( context, sizeToRender, hasDataDefinedRotation,
offset,
angle );
3997 p->translate( point.x() +
offset.x(), point.y() +
offset.y() );
4000 transform.rotate(
angle );
4004 const double s = sizeToRender / mOrigSize;
4005 transform.scale( s, s );
4009 transform.scale( mFontSizeScale, mFontSizeScale );
4011 if ( mUseCachedPath )
4013 p->drawPath( transform.map( mCachedPath ) );
4018 path.addText( -chrOffset.x(), -chrOffset.y(), mFont, charToRender );
4019 p->drawPath( transform.map( path ) );
4026 props[QStringLiteral(
"font" )] = mFontFamily;
4027 props[QStringLiteral(
"font_style" )] = mFontStyle;
4028 QString chr = mString;
4029 for (
int i = 0; i < 32; i++ )
4031 if ( i == 9 || i == 10 || i == 13 )
4035 chr.replace( QChar( i ), QStringLiteral(
"%1%2%1" ).arg(
FONTMARKER_CHR_FIX, QString::number( i ) ) );
4037 props[QStringLiteral(
"chr" )] = chr;
4038 props[QStringLiteral(
"size" )] = QString::number(
mSize );
4043 props[QStringLiteral(
"outline_width" )] = QString::number( mStrokeWidth );
4047 props[QStringLiteral(
"angle" )] = QString::number(
mAngle );
4051 props[QStringLiteral(
"horizontal_anchor_point" )] = QString::number(
static_cast< int >(
mHorizontalAnchorPoint ) );
4052 props[QStringLiteral(
"vertical_anchor_point" )] = QString::number(
static_cast< int >(
mVerticalAnchorPoint ) );
4081 toSld( doc, element, context );
4099 QDomElement graphicElem = doc.createElement( QStringLiteral(
"se:Graphic" ) );
4100 element.appendChild( graphicElem );
4103 const QString fontPath = QStringLiteral(
"ttf://%1" ).arg( mFontFamily );
4104 int markIndex = !mString.isEmpty() ? mString.at( 0 ).unicode() : 0;
4111 const double angle = props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toDouble( &ok );
4114 angleFunc = QStringLiteral(
"%1 + %2" ).arg( props.value( QStringLiteral(
"angle" ), QStringLiteral(
"0" ) ).toString() ).arg(
mAngle );
4138 mStrokeWidthUnit = unit;
4143 QPointF chrOffset = mChrOffset;
4144 double chrWidth = mChrWidth;
4146 ( void )characterToRender( context, chrOffset, chrWidth );
4148 if ( !mFontMetrics )
4149 mFontMetrics = std::make_unique<QFontMetrics>( mFont );
4151 double scaledSize = calculateSize( context );
4154 chrWidth *= scaledSize / mOrigSize;
4156 chrWidth *= mFontSizeScale;
4158 bool hasDataDefinedRotation =
false;
4161 calculateOffsetAndRotation( context, scaledSize, hasDataDefinedRotation,
offset,
angle );
4164 QTransform transform;
4167 transform.translate( point.x() +
offset.x(), point.y() +
offset.y() );
4170 transform.rotate(
angle );
4172 QRectF symbolBounds = transform.mapRect( QRectF( -chrWidth / 2.0,
4176 return symbolBounds;
4183 QDomElement graphicElem = element.firstChildElement( QStringLiteral(
"Graphic" ) );
4184 if ( graphicElem.isNull() )
4187 QString name, format;
4195 if ( !name.startsWith( QLatin1String(
"ttf://" ) ) || format != QLatin1String(
"ttf" ) )
4205 const double d = angleFunc.toDouble( &ok );
4213 double scaleFactor = 1.0;
4214 const QString uom = element.attribute( QStringLiteral(
"uom" ) );
4235 context.
pushMessage( QObject::tr(
"Font “%1” not available on system" ).arg( processedFamily ) );
4241 QMap<QString, QgsProperty>::iterator it =
mParameters.begin();
4253 QMap<QString, QgsProperty>::const_iterator it =
mParameters.constBegin();
4256 attrs.unite( it.value().referencedFields( context.
expressionContext(),
true ) );
4280 if (
properties.contains( QStringLiteral(
"imageFile" ) ) )
4282 if (
properties.contains( QStringLiteral(
"size" ) ) )
4284 if (
properties.contains( QStringLiteral(
"angle" ) ) )
4287 auto m = std::make_unique< QgsAnimatedMarkerSymbolLayer >(
path,
size,
angle );
4288 m->setFrameRate(
properties.value( QStringLiteral(
"frameRate" ), QStringLiteral(
"10" ) ).toDouble() );
4296 return QStringLiteral(
"AnimatedMarker" );
4302 res.insert( QStringLiteral(
"frameRate" ), mFrameRateFps );
4308 auto m = std::make_unique< QgsAnimatedMarkerSymbolLayer >(
mPath,
mSize,
mAngle );
4309 m->setFrameRate( mFrameRateFps );
4318 mPreparedPaths.clear();
4326 mStaticPath =
false;
4332 if ( !mStaticPath && !mPreparedPaths.contains(
path ) )
4335 mPreparedPaths.insert(
path );
4338 const long long mapFrameNumber = context.
currentFrame();
4340 const double markerAnimationDuration = totalFrameCount / mFrameRateFps;
4342 double animationTimeSeconds = 0;
4343 if ( mapFrameNumber >= 0 && context.
frameRate() > 0 )
4346 animationTimeSeconds = mapFrameNumber / context.
frameRate();
4351 animationTimeSeconds = QDateTime::currentMSecsSinceEpoch() / 1000.0;
4354 const double markerAnimationProgressSeconds = std::fmod( animationTimeSeconds, markerAnimationDuration );
4355 const int movieFrame =
static_cast< int >( std::floor( markerAnimationProgressSeconds * mFrameRateFps ) );
4357 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,...
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.
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.
QSet< QString > usedAttributes(const QgsRenderContext &context) const override
Returns the set of attributes referenced by the layer.
void setOutputUnit(Qgis::RenderUnit unit) override
Sets the units to use for sizes and widths within the symbol layer.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
QColor color() const override
Returns the "representative" color of the symbol layer.
QgsFilledMarkerSymbolLayer * clone() const override
Shall be reimplemented by subclasses to create a deep copy of the instance.
bool hasDataDefinedProperties() const override
Returns true if the symbol layer (or any of its sub-symbols) contains data defined properties.
void startRender(QgsSymbolRenderContext &context) override
Called before a set of rendering operations commences on the supplied render context.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QgsSymbol * subSymbol() override
Returns the symbol's sub symbol, if present.
void stopFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called after the layer has been rendered for a particular feature.
void startFeatureRender(const QgsFeature &feature, QgsRenderContext &context) override
Called before the layer will be rendered for a particular feature.
~QgsFilledMarkerSymbolLayer() override
bool setSubSymbol(QgsSymbol *symbol) override
Sets layer's subsymbol. takes ownership of the passed symbol.
void stopRender(QgsSymbolRenderContext &context) override
Called after a set of rendering operations has finished on the supplied render context.
double estimateMaxBleed(const QgsRenderContext &context) const override
Returns the estimated maximum distance which the layer style will bleed outside the drawn shape when ...
void setColor(const QColor &c) override
Sets the "representative" color for the symbol layer.
QString layerType() const override
Returns a string that represents this layer type.
static QgsSymbolLayer * create(const QVariantMap &properties=QVariantMap())
Creates a new QgsFilledMarkerSymbolLayer.
QgsFilledMarkerSymbolLayer(Qgis::MarkerShape shape=Qgis::MarkerShape::Circle, double size=DEFAULT_SIMPLEMARKER_SIZE, double angle=DEFAULT_SIMPLEMARKER_ANGLE, Qgis::ScaleMethod scaleMethod=DEFAULT_SCALE_METHOD)
Constructor for QgsFilledMarkerSymbolLayer.
QString processFontFamilyName(const QString &name) const
Processes a font family name, applying any matching fontFamilyReplacements() to the name.
void setStrokeWidthUnit(Qgis::RenderUnit unit)
Sets the stroke width unit.
~QgsFontMarkerSymbolLayer() override
void setStrokeColor(const QColor &color) override
Sets the stroke color for the symbol layer.
QgsFontMarkerSymbolLayer(const QString &fontFamily=DEFAULT_FONTMARKER_FONT, QString chr=DEFAULT_FONTMARKER_CHR, double pointSize=DEFAULT_FONTMARKER_SIZE, const QColor &color=DEFAULT_FONTMARKER_COLOR, double angle=DEFAULT_FONTMARKER_ANGLE)
Constructs a font marker symbol layer.
void setStrokeWidthMapUnitScale(const QgsMapUnitScale &scale)
Sets the stroke width map unit scale.
double strokeWidth() const
Returns the marker's stroke width.
QVariantMap properties() const override
Should be reimplemented by subclasses to return a string map that contains the configuration informat...
void renderPoint(QPointF point, QgsSymbolRenderContext &context) override
Renders a marker at the specified point.
void setFontStyle(const QString &style)
Sets the font style for the font which will be used to render the point.
bool usesMapUnits() const override
Returns true if the symbol layer has any components which use map unit based sizes.
QString fontStyle() const
Returns the font style for the associated font which will be used to render the point.
QString fontFamily() const
Returns the font family name for the associated font which will be used to render the point.
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.
void setVerticalAnchorPoint(Qgis::VerticalAnchorPoint v)
Sets the vertical anchor point for positioning the symbol.
QgsMarkerSymbolLayer(const QgsMarkerSymbolLayer &other)
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.
bool isActive(int key) const final
Returns true if the collection contains an active property with the specified key.
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.
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.
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).
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.
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.
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.
QgsSymbolLayer(const QgsSymbolLayer &other)
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